oauthenticator 0.1.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.simplecov +1 -0
- data/README.md +118 -35
- data/Rakefile.rb +11 -0
- data/lib/oauthenticator.rb +5 -6
- data/lib/oauthenticator/config_methods.rb +62 -21
- data/lib/oauthenticator/faraday_signer.rb +66 -0
- data/lib/oauthenticator/parse_authorization.rb +81 -0
- data/lib/oauthenticator/{middleware.rb → rack_authenticator.rb} +37 -9
- data/lib/oauthenticator/signable_request.rb +340 -0
- data/lib/oauthenticator/signed_request.rb +123 -112
- data/lib/oauthenticator/version.rb +3 -1
- data/test/config_methods_test.rb +10 -7
- data/test/faraday_signer_test.rb +65 -0
- data/test/helper.rb +15 -3
- data/test/parse_authorization_test.rb +86 -0
- data/test/{oauthenticator_test.rb → rack_authenticator_test.rb} +264 -136
- data/test/signable_request_test.rb +653 -0
- data/test/signed_request_test.rb +12 -0
- data/test/test_config_methods.rb +67 -0
- metadata +26 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7006ebe89c4cd63acc4c40c404a81cd1d435c671
|
4
|
+
data.tar.gz: 54399c9d2d96645797f5bf0c179a46ac3aa0e47d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85859997c9cba4592b097443e643528c6ccc479542eb0410e64a57611c6226a0988314d0b8adb3a17e3e0ae08b823d45a6bbeb75f0f15ca6c298c4b5581859ab
|
7
|
+
data.tar.gz: b1776d367f14799e6fcf5da5e09ed4c6c97cc932d86969c19c06bdcb99ac81827396c8d227fd445a64cbb8ae71f561a9ae4d7da9d65c6dfef67b3b788ce2c142
|
data/.simplecov
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
SimpleCov.start
|
data/README.md
CHANGED
@@ -1,9 +1,89 @@
|
|
1
1
|
# OAuthenticator
|
2
2
|
|
3
|
-
OAuthenticator
|
4
|
-
messages when authentication fails.
|
3
|
+
OAuthenticator signs outgoing requests with OAuth 1.0.
|
5
4
|
|
6
|
-
|
5
|
+
OAuthenticator authenticates incoming OAuth 1.0 signed requests, primarily as a middleware, and forms useful
|
6
|
+
error messages when authentication fails.
|
7
|
+
|
8
|
+
Note: The canonical location of this README is on [RubyDoc](http://rubydoc.info/gems/oauthenticator/). When
|
9
|
+
viewed on [Github](https://github.com/notEthan/oauthenticator/), it may be inconsistent with the latest
|
10
|
+
released gem, and Yardoc links will not work.
|
11
|
+
|
12
|
+
## Signing outgoing requests
|
13
|
+
|
14
|
+
### Faraday
|
15
|
+
|
16
|
+
OAuthenticator provides Faraday middleware for easy signing of outgoing requests. This request middleware is
|
17
|
+
registered with faraday named `:oauthenticator_signer`.
|
18
|
+
|
19
|
+
The middleware should be in the stack immediately before the adapter. Any other middleware that modifies the
|
20
|
+
request between OAuthenticator signing it and the request actually being made may render the signature
|
21
|
+
invalid.
|
22
|
+
|
23
|
+
See the documentation for {OAuthenticator::FaradaySigner} for more detailed information.
|
24
|
+
|
25
|
+
An example:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'oauthenticator'
|
29
|
+
|
30
|
+
signing_options = {
|
31
|
+
:signature_method => 'HMAC-SHA1',
|
32
|
+
:consumer_key => 'a consumer',
|
33
|
+
:consumer_secret => 'a consumer secret',
|
34
|
+
:token => 'a token',
|
35
|
+
:token_secret => 'a token secret',
|
36
|
+
:realm => 'The Realm',
|
37
|
+
}
|
38
|
+
|
39
|
+
connection = Faraday.new('http://example.com/') do |faraday|
|
40
|
+
faraday.request :url_encoded
|
41
|
+
faraday.request :oauthenticator_signer, signing_options
|
42
|
+
faraday.adapter Faraday.default_adapter
|
43
|
+
end
|
44
|
+
|
45
|
+
connection.get '/path'
|
46
|
+
```
|
47
|
+
|
48
|
+
Note that `:url_encoded` is only included to illustrate that other middleware should all go before
|
49
|
+
`:oauthenticator_signer`; the use of `:url_encoded` is not related to OAuthenticator.
|
50
|
+
|
51
|
+
### Any other HTTP library
|
52
|
+
|
53
|
+
Generating an Authorization header to apply to an outgoing request is a relatively straightforward affair:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
oauthenticator_signable_request = OAuthenticator::SignableRequest.new(
|
57
|
+
:request_method => my_request_method,
|
58
|
+
:uri => my_request_uri,
|
59
|
+
:media_type => my_request_media_type,
|
60
|
+
:body => my_request_body,
|
61
|
+
:signature_method => my_oauth_signature_method,
|
62
|
+
:consumer_key => my_oauth_consumer_key,
|
63
|
+
:consumer_secret => my_oauth_consumer_secret,
|
64
|
+
:token => my_oauth_token,
|
65
|
+
:token_secret => my_oauth_token_secret,
|
66
|
+
:realm => my_authorization_realm,
|
67
|
+
:hash_body? => my_body_hashing_requirement
|
68
|
+
)
|
69
|
+
my_http_request.headers['Authorization'] = oauthenticator_signable_request.authorization
|
70
|
+
```
|
71
|
+
|
72
|
+
See the documentation for {OAuthenticator::SignableRequest} for more detailed information.
|
73
|
+
|
74
|
+
### OAuth Request Body Hash
|
75
|
+
|
76
|
+
The [OAuth Request Body Hash](https://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html)
|
77
|
+
specification is supported. By default all signing of outgoing does include the body hash. This can be
|
78
|
+
disabled by setting the `:hash_body?` / `'hash_body?'` attribute to false when instantiating an
|
79
|
+
OAuthenticator::SignableRequest.
|
80
|
+
|
81
|
+
For info on when to include the body hash, see
|
82
|
+
[When to Include the Body Hash](https://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html#when_to_include).
|
83
|
+
|
84
|
+
## Authenticating incoming requests
|
85
|
+
|
86
|
+
### Config Methods module
|
7
87
|
|
8
88
|
There are many ways (infinite, really) in which certain parts of the OAuth spec may be implemented. In order
|
9
89
|
to flexibly accomodate the general case of OAuth authentication, OAuthenticator leaves certain parts of the
|
@@ -11,11 +91,11 @@ implementation up to the user. The user configures this by creating a module imp
|
|
11
91
|
which will be passed to OAuthenticator.
|
12
92
|
|
13
93
|
For more information on the details of the methods which must or may be implemented, please see the
|
14
|
-
documentation for the module
|
94
|
+
documentation for the module {OAuthenticator::ConfigMethods}, which defines stub methods for
|
15
95
|
each recognized method, with method documentation relating to your implementation.
|
16
96
|
|
17
97
|
A simple, contrived example follows, which approximately resembles what you might implement. It is not useful
|
18
|
-
on its own but will be used in following examples for usage of
|
98
|
+
on its own but will be used in following examples for usage of RackAuthenticator and SignedRequest.
|
19
99
|
|
20
100
|
```ruby
|
21
101
|
require 'oauthenticator'
|
@@ -29,7 +109,7 @@ require 'oauthenticator'
|
|
29
109
|
# - OAuthConsumer
|
30
110
|
# - key
|
31
111
|
# - secret
|
32
|
-
# -
|
112
|
+
# - OAuthToken
|
33
113
|
# - token
|
34
114
|
# - secret
|
35
115
|
# - consumer_key
|
@@ -62,60 +142,63 @@ module AwesomeOAuthConfig
|
|
62
142
|
OAuthConsumer.where(:key => consumer_key).first.try(:secret)
|
63
143
|
end
|
64
144
|
|
65
|
-
#
|
66
|
-
def
|
67
|
-
|
145
|
+
# token secret, looked up by token
|
146
|
+
def token_secret
|
147
|
+
OAuthToken.where(:token => token).first.try(:secret)
|
68
148
|
end
|
69
149
|
|
70
|
-
# whether the
|
71
|
-
def
|
72
|
-
|
150
|
+
# whether the token belongs to the consumer
|
151
|
+
def token_belongs_to_consumer?
|
152
|
+
OAuthToken.where(:token => token).first.try(:consumer_key) == consumer_key
|
73
153
|
# alternately:
|
74
|
-
#
|
154
|
+
# OAuthToken.where(:token => token, :consumer_key => consumer_key).any?
|
155
|
+
end
|
156
|
+
|
157
|
+
# whether oauth_body_hash_is_required (this method defaults to false and may be omitted)
|
158
|
+
def body_hash_required?
|
159
|
+
false
|
75
160
|
end
|
76
161
|
end
|
77
162
|
```
|
78
163
|
|
79
|
-
You may also find it enlightening to peruse `test/
|
80
|
-
|
81
|
-
tests.
|
164
|
+
You may also find it enlightening to peruse `test/test_config_methods.rb`, which sets up some very simple
|
165
|
+
storage in memory, and defines a module of config methods which are used through the tests.
|
82
166
|
|
83
|
-
|
167
|
+
### OAuthenticator::RackAuthenticator
|
84
168
|
|
85
|
-
The middleware is used by passing the above-mentioned module on the `:config_methods` key to
|
86
|
-
middleware:
|
169
|
+
The RackAuthenticator middleware is used by passing the above-mentioned module on the `:config_methods` key to
|
170
|
+
initialize the middleware:
|
87
171
|
|
88
172
|
```ruby
|
89
173
|
# config.ru
|
90
174
|
|
91
|
-
use OAuthenticator::
|
175
|
+
use OAuthenticator::RackAuthenticator, :config_methods => AwesomeOAuthConfig
|
92
176
|
run proc { |env| [200, {'Content-Type' => 'text/plain'}, ['access granted!']] }
|
93
177
|
```
|
94
178
|
|
95
179
|
The authentication can also be bypassed with a proc on the `:bypass` key; see the documentation for
|
96
|
-
|
180
|
+
{OAuthenticator::RackAuthenticator} for the details of that.
|
97
181
|
|
98
|
-
|
182
|
+
### OAuthenticator::SignedRequest
|
99
183
|
|
100
|
-
The OAuthenticator::SignedRequest class may be used independently of the middleware, though
|
101
|
-
passed your module of config methods to include. It is used like:
|
184
|
+
The OAuthenticator::SignedRequest class may be used independently of the RackAuthenticator middleware, though
|
185
|
+
it must also be passed your module of config methods to include. It is used like:
|
102
186
|
|
103
187
|
```ruby
|
104
188
|
OAuthenticator::SignedRequest.including_config(AwesomeOAuthConfig).new(request_attrs)
|
105
189
|
```
|
106
190
|
|
107
|
-
See the documentation of OAuthenticator::SignedRequest for how the class is used, once it includes the
|
108
|
-
it needs to function.
|
191
|
+
See the documentation of {OAuthenticator::SignedRequest} for how the class is used, once it includes the
|
192
|
+
methods it needs to function.
|
109
193
|
|
110
|
-
|
194
|
+
### OAuth Request Body Hash
|
111
195
|
|
112
|
-
|
196
|
+
The [OAuth Request Body Hash](https://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html)
|
197
|
+
specification is supported. Requests which include the oauth_body_hash parameter are authenticated according
|
198
|
+
to the spec.
|
113
199
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
200
|
+
Requests which may include the oauth_body_hash parameter but do not are accepted or rejected based on the
|
201
|
+
config method `#body_hash_required?` - if the implementation indicates that oauth_body_hash is required, then
|
202
|
+
the request is rejected as inauthentic; if it is not required then the request is allowed (assuming all other
|
203
|
+
aspects of the OAuth signature are authentic.)
|
118
204
|
|
119
|
-
```ruby
|
120
|
-
gem 'simple_oauth', :git => 'https://github.com/notEthan/simple_oauth.git', :tag => 'ethan-v0.2.0.2'
|
121
|
-
```
|
data/Rakefile.rb
ADDED
data/lib/oauthenticator.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
1
|
+
require 'oauthenticator/version'
|
2
|
+
require 'oauthenticator/signed_request'
|
3
|
+
require 'oauthenticator/signable_request'
|
4
|
+
require 'oauthenticator/rack_authenticator'
|
5
|
+
require 'oauthenticator/faraday_signer'
|
@@ -1,14 +1,19 @@
|
|
1
1
|
module OAuthenticator
|
2
|
-
# This module contains stubs, or in some cases default values, for implementations of particulars of the
|
2
|
+
# This module contains stubs, or in some cases default values, for implementations of particulars of the
|
3
|
+
# OAuth protocol. Applications must implement some of these, and are likely to want to override the default
|
4
|
+
# values of others. certain methods will need to use methods of the {OAuthenticator::SignedRequest} class.
|
3
5
|
#
|
4
|
-
# the methods your implementation will need to be used are primarily those from the parsed OAuth
|
6
|
+
# the methods your implementation will need to be used are primarily those from the parsed OAuth
|
7
|
+
# Authorization header. these are methods your implementation WILL need to use to implement the required
|
8
|
+
# functionality:
|
5
9
|
#
|
6
10
|
# - `#consumer_key`
|
7
11
|
# - `#token`
|
8
12
|
# - `#nonce`
|
9
13
|
# - `#timestamp`
|
10
14
|
#
|
11
|
-
# the following are the other parts of the Authorization, but your implementation will probably NOT need to
|
15
|
+
# the following are the other parts of the Authorization, but your implementation will probably NOT need to
|
16
|
+
# use these (OAuthenticator does everything that is needed to validate these parts):
|
12
17
|
#
|
13
18
|
# - `#version`
|
14
19
|
# - `#signature_method`
|
@@ -16,9 +21,12 @@ module OAuthenticator
|
|
16
21
|
module ConfigMethods
|
17
22
|
# the number of seconds (integer) in both the past and future for which the request is considered valid.
|
18
23
|
#
|
19
|
-
# if it is desired to have a different period considered valid in the past than in the future, then the
|
24
|
+
# if it is desired to have a different period considered valid in the past than in the future, then the
|
25
|
+
# methods {#timestamp_valid_past} and {#timestamp_valid_future} may be implemented instead, and this
|
26
|
+
# method may remain unimplemented.
|
20
27
|
#
|
21
|
-
# see the documentation for {#timestamp_valid_past} and {#timestamp_valid_future} for other considerations
|
28
|
+
# see the documentation for {#timestamp_valid_past} and {#timestamp_valid_future} for other considerations
|
29
|
+
# of the valid period.
|
22
30
|
#
|
23
31
|
# @return [Integer] period in seconds
|
24
32
|
def timestamp_valid_period
|
@@ -27,9 +35,11 @@ module OAuthenticator
|
|
27
35
|
|
28
36
|
# the number of seconds (integer) in the past for which the request is considered valid.
|
29
37
|
#
|
30
|
-
# if the timestamp is more than this number of seconds less than the current clock time, then the request
|
38
|
+
# if the timestamp is more than this number of seconds less than the current clock time, then the request
|
39
|
+
# is considered invalid and the response is an error.
|
31
40
|
#
|
32
|
-
# this should be large enough to allow for clock skew between your application's server and the
|
41
|
+
# this should be large enough to allow for clock skew between your application's server and the
|
42
|
+
# requester's clock.
|
33
43
|
#
|
34
44
|
# nonces older than Time.now - timestamp_valid_past may be discarded.
|
35
45
|
#
|
@@ -42,9 +52,11 @@ module OAuthenticator
|
|
42
52
|
|
43
53
|
# the number of seconds (integer) in the future for which the request is considered valid.
|
44
54
|
#
|
45
|
-
# if the timestamp is more than this number of seconds greater than the current clock time, then the
|
55
|
+
# if the timestamp is more than this number of seconds greater than the current clock time, then the
|
56
|
+
# request is considered invalid and the response is an error.
|
46
57
|
#
|
47
|
-
# this should be large enough to allow for clock skew between your application's server and the
|
58
|
+
# this should be large enough to allow for clock skew between your application's server and the
|
59
|
+
# requester's clock.
|
48
60
|
#
|
49
61
|
# this method may remain unimplemented if {#timestamp_valid_period} is implemented.
|
50
62
|
#
|
@@ -53,48 +65,77 @@ module OAuthenticator
|
|
53
65
|
timestamp_valid_period
|
54
66
|
end
|
55
67
|
|
56
|
-
# the signature methods which the application will accept. this MUST be a subset of the signature methods
|
68
|
+
# the signature methods which the application will accept. this MUST be a subset of the signature methods
|
69
|
+
# defined in the OAuth 1.0 protocol: `%w(HMAC-SHA1 RSA-SHA1 PLAINTEXT)`. the default value for this is all
|
70
|
+
# allowed signature methods, and may remain unimplemented if you wish to allow all defined signature
|
71
|
+
# methods.
|
57
72
|
#
|
58
73
|
# @return [Array<String>]
|
59
74
|
def allowed_signature_methods
|
60
|
-
|
75
|
+
SignableRequest::SIGNATURE_METHODS.keys
|
61
76
|
end
|
62
77
|
|
63
|
-
# this should look up the consumer secret in your application's storage corresponding to the request's
|
78
|
+
# this should look up the consumer secret in your application's storage corresponding to the request's
|
79
|
+
# consumer key, which is available via the `#consumer_key` method. see the README for an example
|
80
|
+
# implementation.
|
64
81
|
#
|
65
82
|
# @return [String] the consumer secret for the request's consumer key
|
66
83
|
def consumer_secret
|
67
84
|
config_method_not_implemented
|
68
85
|
end
|
69
86
|
|
70
|
-
# this should look up the
|
87
|
+
# this should look up the token secret in your application's storage corresponding to the request's
|
88
|
+
# token, which is available via the `#token` method. see the README for an example implementation.
|
71
89
|
#
|
72
|
-
# @return [String] the
|
73
|
-
def
|
90
|
+
# @return [String] the token secret for the request's token
|
91
|
+
def token_secret
|
74
92
|
config_method_not_implemented
|
75
93
|
end
|
76
94
|
|
77
|
-
# whether the nonce, available via the `#nonce` method, has already been used. you may wish to use this in
|
95
|
+
# whether the nonce, available via the `#nonce` method, has already been used. you may wish to use this in
|
96
|
+
# conjunction with the timestamp (`#timestamp`), per the OAuth 1.0 spec.
|
78
97
|
#
|
79
|
-
# it's worth noting that if this ever returns true, it may indicate a replay attack under way against your
|
98
|
+
# it's worth noting that if this ever returns true, it may indicate a replay attack under way against your
|
99
|
+
# application. the replay attack will fail due to OAuth, but you may wish to log the event.
|
80
100
|
#
|
81
101
|
# @return [Boolean] whether the request's nonce has already been used.
|
82
102
|
def nonce_used?
|
83
103
|
config_method_not_implemented
|
84
104
|
end
|
85
105
|
|
86
|
-
# cause the nonce, available via the `#nonce` method, to be marked as used. you may wish to use this in
|
106
|
+
# cause the nonce, available via the `#nonce` method, to be marked as used. you may wish to use this in
|
107
|
+
# conjunction with the timestamp (`#timestamp`).
|
87
108
|
#
|
88
109
|
# @return [Void] (return value is ignored / unused)
|
89
110
|
def use_nonce!
|
90
111
|
config_method_not_implemented
|
91
112
|
end
|
92
113
|
|
93
|
-
# whether the
|
114
|
+
# whether the token indicated by the request (via `#token`) belongs to the consumer indicated by
|
115
|
+
# the request (via `#consumer_key`).
|
94
116
|
#
|
95
|
-
#
|
96
|
-
|
117
|
+
# this method may simply return true if the implementation does not care to restrict tokens by
|
118
|
+
# consumer.
|
119
|
+
#
|
120
|
+
# @return [Boolean] whether the request's token belongs to the request's consumer
|
121
|
+
def token_belongs_to_consumer?
|
97
122
|
config_method_not_implemented
|
98
123
|
end
|
124
|
+
|
125
|
+
# whether the request will be considered valid if it is missing the oauth_body_hash parameter, when that
|
126
|
+
# parameter is allowed. if you require requests to include the oauth_body_hash parameter, return true
|
127
|
+
# here.
|
128
|
+
#
|
129
|
+
# the default for this method is false, since the oauth body hash is not widely implemented.
|
130
|
+
#
|
131
|
+
# this only applies to requests which are NOT form encoded - requests which are form-encoded must never
|
132
|
+
# have the oauth_body_hash parameter regardless of this setting and will be rejected as inauthentic, per
|
133
|
+
# the OAuth Request Body Hash spec. this also does not apply to requests with a signature method which
|
134
|
+
# does not have a corresponding body hash method - i.e., the PLAINTEXT signature method.
|
135
|
+
#
|
136
|
+
# @return [Boolean] whether body hash is required
|
137
|
+
def body_hash_required?
|
138
|
+
false
|
139
|
+
end
|
99
140
|
end
|
100
141
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
if Faraday.respond_to?(:register_middleware)
|
4
|
+
Faraday.register_middleware(:request, :oauthenticator_signer => proc { OAuthenticator::FaradaySigner })
|
5
|
+
end
|
6
|
+
if Faraday::Request.respond_to?(:register_middleware)
|
7
|
+
Faraday::Request.register_middleware(:oauthenticator_signer => proc { OAuthenticator::FaradaySigner })
|
8
|
+
end
|
9
|
+
|
10
|
+
module OAuthenticator
|
11
|
+
# OAuthenticator Faraday middleware to sign outgoing requests.
|
12
|
+
#
|
13
|
+
# The middleware should be in the stack immediately before the adapter. Any other middleware that modifies
|
14
|
+
# the request between OAuthenticator signing it and the request actually being made may render the signature
|
15
|
+
# invalid.
|
16
|
+
#
|
17
|
+
# This request middleware is registered as `:oauthenticator_signer`. It should be used like
|
18
|
+
#
|
19
|
+
# connection = Faraday.new('http://example.com/') do |faraday|
|
20
|
+
# faraday.request :url_encoded
|
21
|
+
# faraday.request :oauthenticator_signer, signing_options
|
22
|
+
# faraday.adapter Faraday.default_adapter
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# Note that `:url_encoded` is only included to illustrate that other middleware should all go before
|
26
|
+
# `:oauthenticator_signer`; the use of `:url_encoded` is not related to OAuthenticator.
|
27
|
+
#
|
28
|
+
# See {#initialize} for details of what the `signing_options` hash should include.
|
29
|
+
class FaradaySigner
|
30
|
+
# options are passed to {OAuthenticator::SignableRequest}.
|
31
|
+
#
|
32
|
+
# attributes of the request are added by the middleware, so you should not provide those as optiosn
|
33
|
+
# (it would not make sense to do so on the connection level).
|
34
|
+
#
|
35
|
+
# These are the options you should or may provide (see {OAuthenticator::SignableRequest} for details of
|
36
|
+
# what options are required, what options have default or generated values, and what may be omitted):
|
37
|
+
#
|
38
|
+
# - signature_method
|
39
|
+
# - consumer_key
|
40
|
+
# - consumer_secret
|
41
|
+
# - token
|
42
|
+
# - token_secret
|
43
|
+
# - version
|
44
|
+
# - realm
|
45
|
+
# - hash_body?
|
46
|
+
def initialize(app, options)
|
47
|
+
@app = app
|
48
|
+
@options = options
|
49
|
+
end
|
50
|
+
|
51
|
+
# do the thing
|
52
|
+
def call(request_env)
|
53
|
+
request_attributes = {
|
54
|
+
:request_method => request_env[:method],
|
55
|
+
:uri => request_env[:url],
|
56
|
+
:media_type => request_env[:request_headers]['Content-Type'],
|
57
|
+
:body => request_env[:body]
|
58
|
+
}
|
59
|
+
oauthenticator_signable_request = OAuthenticator::SignableRequest.new(@options.merge(request_attributes))
|
60
|
+
authorization = oauthenticator_signable_request.authorization
|
61
|
+
signed_request_headers = request_env[:request_headers].merge('Authorization' => authorization)
|
62
|
+
signed_request_env = request_env.merge(:request_headers => signed_request_headers)
|
63
|
+
@app.call(signed_request_env)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|