Blame view

node_modules/request/lib/oauth.js 3.9 KB
f7563de62   Palak Handa   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  'use strict'
  
  var url = require('url')
    , qs = require('qs')
    , caseless = require('caseless')
    , uuid = require('uuid')
    , oauth = require('oauth-sign')
    , crypto = require('crypto')
    , Buffer = require('safe-buffer').Buffer
  
  
  function OAuth (request) {
    this.request = request
    this.params = null
  }
  
  OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) {
    var oa = {}
    for (var i in _oauth) {
      oa['oauth_' + i] = _oauth[i]
    }
    if (!oa.oauth_version) {
      oa.oauth_version = '1.0'
    }
    if (!oa.oauth_timestamp) {
      oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString()
    }
    if (!oa.oauth_nonce) {
      oa.oauth_nonce = uuid().replace(/-/g, '')
    }
    if (!oa.oauth_signature_method) {
      oa.oauth_signature_method = 'HMAC-SHA1'
    }
  
    var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key
    delete oa.oauth_consumer_secret
    delete oa.oauth_private_key
  
    var token_secret = oa.oauth_token_secret
    delete oa.oauth_token_secret
  
    var realm = oa.oauth_realm
    delete oa.oauth_realm
    delete oa.oauth_transport_method
  
    var baseurl = uri.protocol + '//' + uri.host + uri.pathname
    var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&'))
  
    oa.oauth_signature = oauth.sign(
      oa.oauth_signature_method,
      method,
      baseurl,
      params,
      consumer_secret_or_private_key,
      token_secret)
  
    if (realm) {
      oa.realm = realm
    }
  
    return oa
  }
  
  OAuth.prototype.buildBodyHash = function(_oauth, body) {
    if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) {
      this.request.emit('error', new Error('oauth: ' + _oauth.signature_method +
        ' signature_method not supported with body_hash signing.'))
    }
  
    var shasum = crypto.createHash('sha1')
    shasum.update(body || '')
    var sha1 = shasum.digest('hex')
  
    return Buffer.from(sha1).toString('base64')
  }
  
  OAuth.prototype.concatParams = function (oa, sep, wrap) {
    wrap = wrap || ''
  
    var params = Object.keys(oa).filter(function (i) {
      return i !== 'realm' && i !== 'oauth_signature'
    }).sort()
  
    if (oa.realm) {
      params.splice(0, 0, 'realm')
    }
    params.push('oauth_signature')
  
    return params.map(function (i) {
      return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap
    }).join(sep)
  }
  
  OAuth.prototype.onRequest = function (_oauth) {
    var self = this
    self.params = _oauth
  
    var uri = self.request.uri || {}
      , method = self.request.method || ''
      , headers = caseless(self.request.headers)
      , body = self.request.body || ''
      , qsLib = self.request.qsLib || qs
  
    var form
      , query
      , contentType = headers.get('content-type') || ''
      , formContentType = 'application/x-www-form-urlencoded'
      , transport = _oauth.transport_method || 'header'
  
    if (contentType.slice(0, formContentType.length) === formContentType) {
      contentType = formContentType
      form = body
    }
    if (uri.query) {
      query = uri.query
    }
    if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) {
      self.request.emit('error', new Error('oauth: transport_method of body requires POST ' +
        'and content-type ' + formContentType))
    }
  
    if (!form && typeof _oauth.body_hash === 'boolean') {
      _oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString())
    }
  
    var oa = self.buildParams(_oauth, uri, method, query, form, qsLib)
  
    switch (transport) {
      case 'header':
        self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"'))
        break
  
      case 'query':
        var href = self.request.uri.href += (query ? '&' : '?') + self.concatParams(oa, '&')
        self.request.uri = url.parse(href)
        self.request.path = self.request.uri.path
        break
  
      case 'body':
        self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&')
        break
  
      default:
        self.request.emit('error', new Error('oauth: transport_method invalid'))
    }
  }
  
  exports.OAuth = OAuth