oauthenticator 1.3.0 → 1.3.5
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 +5 -5
- data/CHANGELOG.md +23 -0
- data/README.md +9 -4
- data/Rakefile.rb +2 -1
- data/lib/oauthenticator/faraday_signer.rb +14 -3
- data/lib/oauthenticator/parse_authorization.rb +4 -4
- data/lib/oauthenticator/rack_authenticator.rb +4 -3
- data/lib/oauthenticator/version.rb +1 -1
- data/test/faraday_signer_test.rb +17 -0
- data/test/rack_authenticator_test.rb +4 -1
- data/test/signable_request_test.rb +2 -1
- metadata +23 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 16ab24b09d173ed8caca336faa49d9cc263513b5a1b918f656985dff431caa61
|
4
|
+
data.tar.gz: d3439a11045ed50fb9c72ccb85d137c72ea04b04189d58729b24ca365744937f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd14158bfbc8c6ff4f998226ae110d5d3c9d251fb011968dd5ddc7d3fd1d131450e5dce683e1590728218527ea2a9f31e82b17f81b674eb4ea391a4d68d0bdb0
|
7
|
+
data.tar.gz: 82aef9ae6b004bcd95b5cf6a96c198089195022b3a131ec1346a62a2c18d3db1b6b2eae54af4ba41e665ef57677dc72bed6a9f886615fdeb53e7351e0a697918
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
# 1.3.5
|
2
|
+
|
3
|
+
- relax faraday and rack gem dependency constraints
|
4
|
+
|
5
|
+
# 1.3.4
|
6
|
+
|
7
|
+
- relax json gem dependency constraint
|
8
|
+
|
9
|
+
# 1.3.3
|
10
|
+
|
11
|
+
- env["oauth.signed_request"] contains the signed request. this makes any helper methods from the implemented
|
12
|
+
config methods module available and helps avoid code duplication (and sometimes duplicated db queries -
|
13
|
+
depending on implementation)
|
14
|
+
- fix irrelevant warning with Hash#reject called on hash with a default proc
|
15
|
+
|
16
|
+
# 1.3.2
|
17
|
+
|
18
|
+
- loosen dependency to allow rack 2.0
|
19
|
+
|
20
|
+
# 1.3.1
|
21
|
+
|
22
|
+
- set media type to the default that the adapter will use if it's not specified on a request that is expected to have a body
|
23
|
+
|
1
24
|
# 1.3.0
|
2
25
|
|
3
26
|
- Make error messages fully-human readable on their own (not requiring context of the error key)
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# OAuthenticator
|
2
2
|
|
3
|
+
[](https://travis-ci.org/notEthan/oauthenticator)
|
4
|
+
|
3
5
|
OAuthenticator signs outgoing requests with OAuth 1.0.
|
4
6
|
|
5
7
|
OAuthenticator authenticates incoming OAuth 1.0 signed requests, primarily as a middleware, and forms useful
|
@@ -46,7 +48,10 @@ connection.get '/path'
|
|
46
48
|
```
|
47
49
|
|
48
50
|
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.
|
51
|
+
`:oauthenticator_signer`; the use of `:url_encoded` is not related to OAuthenticator.
|
52
|
+
|
53
|
+
Note that for the RSA-SHA1 signature method, the token secret is the contents of the RSA certificate
|
54
|
+
used for signing the requests.
|
50
55
|
|
51
56
|
### Any other HTTP library
|
52
57
|
|
@@ -73,13 +78,13 @@ See the documentation for {OAuthenticator::SignableRequest} for more detailed in
|
|
73
78
|
|
74
79
|
### OAuth Request Body Hash
|
75
80
|
|
76
|
-
The [OAuth Request Body Hash](https://
|
81
|
+
The [OAuth Request Body Hash](https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00)
|
77
82
|
specification is supported. By default all signing of outgoing does include the body hash. This can be
|
78
83
|
disabled by setting the `:hash_body?` / `'hash_body?'` attribute to false when instantiating an
|
79
84
|
OAuthenticator::SignableRequest.
|
80
85
|
|
81
86
|
For info on when to include the body hash, see
|
82
|
-
[When to Include the Body Hash](https://
|
87
|
+
[When to Include the Body Hash](https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-4.1.1).
|
83
88
|
|
84
89
|
## Authenticating incoming requests
|
85
90
|
|
@@ -193,7 +198,7 @@ methods it needs to function.
|
|
193
198
|
|
194
199
|
### OAuth Request Body Hash
|
195
200
|
|
196
|
-
The [OAuth Request Body Hash](https://
|
201
|
+
The [OAuth Request Body Hash](https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00)
|
197
202
|
specification is supported. Requests which include the oauth_body_hash parameter are authenticated according
|
198
203
|
to the spec.
|
199
204
|
|
data/Rakefile.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'oauthenticator'
|
2
1
|
require 'faraday'
|
2
|
+
require 'rack'
|
3
3
|
|
4
4
|
if Faraday.respond_to?(:register_middleware)
|
5
5
|
Faraday.register_middleware(:request, :oauthenticator_signer => proc { OAuthenticator::FaradaySigner })
|
@@ -30,7 +30,7 @@ module OAuthenticator
|
|
30
30
|
class FaradaySigner
|
31
31
|
# options are passed to {OAuthenticator::SignableRequest}.
|
32
32
|
#
|
33
|
-
# attributes of the request are added by the middleware, so you should not provide those as
|
33
|
+
# attributes of the request are added by the middleware, so you should not provide those as options
|
34
34
|
# (it would not make sense to do so on the connection level).
|
35
35
|
#
|
36
36
|
# These are the options you should or may provide (see {OAuthenticator::SignableRequest} for details of
|
@@ -49,14 +49,25 @@ module OAuthenticator
|
|
49
49
|
@options = options
|
50
50
|
end
|
51
51
|
|
52
|
+
# see also Faraday::Env::MethodsWithBodies
|
53
|
+
METHODS_WITH_BODIES = %w(post put patch options)
|
54
|
+
|
52
55
|
# do the thing
|
53
56
|
def call(request_env)
|
57
|
+
media_type = Rack::Request.new('CONTENT_TYPE' => request_env[:request_headers]['Content-Type']).media_type
|
54
58
|
request_attributes = {
|
55
59
|
:request_method => request_env[:method],
|
56
60
|
:uri => request_env[:url],
|
57
|
-
:media_type =>
|
61
|
+
:media_type => media_type,
|
58
62
|
:body => request_env[:body]
|
59
63
|
}
|
64
|
+
# the adapter will set the media type to form-encoded when not otherwise specified on
|
65
|
+
# requests it expects to have a body. see
|
66
|
+
# Net::HTTPGenericRequest#supply_default_content_type called in #send_request_with_body.
|
67
|
+
# other adapters do similarly, I think.
|
68
|
+
if METHODS_WITH_BODIES.include?(request_env[:method].to_s.downcase) && !request_attributes[:media_type]
|
69
|
+
request_attributes[:media_type] = 'application/x-www-form-urlencoded'
|
70
|
+
end
|
60
71
|
oauthenticator_signable_request = OAuthenticator::SignableRequest.new(@options.merge(request_attributes))
|
61
72
|
request_env[:request_headers]['Authorization'] = oauthenticator_signable_request.authorization
|
62
73
|
@app.call(request_env)
|
@@ -33,16 +33,16 @@ module OAuthenticator
|
|
33
33
|
header = header.to_s
|
34
34
|
scanner = StringScanner.new(header)
|
35
35
|
auth_parse_error = proc { |message| raise ParseError.new(message, {'Authorization' => [message]}) }
|
36
|
-
scanner.scan(/OAuth\s*/i) || auth_parse_error.call("Authorization scheme is not OAuth -
|
37
|
-
attributes =
|
38
|
-
while
|
36
|
+
scanner.scan(/OAuth\s*/i) || auth_parse_error.call("Authorization scheme is not OAuth - received: #{header}")
|
37
|
+
attributes = {}
|
38
|
+
while scanner.scan(/(\w+)="([^"]*)"\s*(,?)\s*/)
|
39
39
|
key = scanner[1]
|
40
40
|
value = scanner[2]
|
41
41
|
comma_follows = !scanner[3].empty?
|
42
42
|
if !comma_follows && !scanner.eos?
|
43
43
|
auth_parse_error.call("Could not parse Authorization header: #{header}\naround or after character #{scanner.pos}: #{scanner.rest}")
|
44
44
|
end
|
45
|
-
attributes[unescape(key)] << unescape(value)
|
45
|
+
(attributes[unescape(key)] ||= []) << unescape(value)
|
46
46
|
end
|
47
47
|
unless scanner.eos?
|
48
48
|
auth_parse_error.call("Could not parse Authorization header: #{header}\naround or after character #{scanner.pos}: #{scanner.rest}")
|
@@ -25,8 +25,8 @@ module OAuthenticator
|
|
25
25
|
#
|
26
26
|
# - `:realm` - 401 responses include a `WWW-Authenticate` with the realm set to the given value. default
|
27
27
|
# is an empty string.
|
28
|
-
def initialize(app, options={})
|
29
|
-
@app=app
|
28
|
+
def initialize(app, options = {})
|
29
|
+
@app = app
|
30
30
|
@options = options
|
31
31
|
unless @options[:config_methods].is_a?(Module)
|
32
32
|
raise ArgumentError, "options[:config_methods] must be a Module"
|
@@ -48,6 +48,7 @@ module OAuthenticator
|
|
48
48
|
unauthenticated_response(oauth_request.errors)
|
49
49
|
else
|
50
50
|
log_success(env, oauth_request)
|
51
|
+
env["oauth.signed_request"] = oauth_request
|
51
52
|
env["oauth.consumer_key"] = oauth_request.consumer_key
|
52
53
|
env["oauth.token"] = oauth_request.token
|
53
54
|
env["oauth.authenticated"] = true
|
@@ -60,7 +61,7 @@ module OAuthenticator
|
|
60
61
|
|
61
62
|
# the response for an unauthenticated request. the argument will be a hash with the key 'errors', whose
|
62
63
|
# value is a hash with string keys indicating attributes with errors, and values being arrays of strings
|
63
|
-
# indicating error messages on the attribute key
|
64
|
+
# indicating error messages on the attribute key.
|
64
65
|
def unauthenticated_response(errors)
|
65
66
|
# default to a blank realm, I suppose
|
66
67
|
realm = @options[:realm] || ''
|
data/test/faraday_signer_test.rb
CHANGED
@@ -46,6 +46,23 @@ describe OAuthenticator::FaradaySigner do
|
|
46
46
|
assert_response 200, '☺', response
|
47
47
|
end
|
48
48
|
|
49
|
+
it 'succeeds with charset' do
|
50
|
+
signing_options = {
|
51
|
+
:signature_method => 'HMAC-SHA1',
|
52
|
+
:consumer_key => consumer_key,
|
53
|
+
:consumer_secret => consumer_secret,
|
54
|
+
:token => token,
|
55
|
+
:token_secret => token_secret,
|
56
|
+
}
|
57
|
+
|
58
|
+
connection = Faraday.new(:url => 'http://example.com', :headers => {'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'}) do |faraday|
|
59
|
+
faraday.request :oauthenticator_signer, signing_options
|
60
|
+
faraday.adapter :rack, oapp
|
61
|
+
end
|
62
|
+
response = connection.post('/', 'a=b')
|
63
|
+
assert_response 200, '☺', response
|
64
|
+
end
|
65
|
+
|
49
66
|
it 'is unauthorized' do
|
50
67
|
signing_options = {
|
51
68
|
:signature_method => 'PLAINTEXT',
|
@@ -592,14 +592,16 @@ describe OAuthenticator::RackAuthenticator do
|
|
592
592
|
end
|
593
593
|
end
|
594
594
|
|
595
|
-
it 'sets oauth.authenticated, oauth.token, oauth.consumer_key' do
|
595
|
+
it 'sets oauth.authenticated, oauth.token, oauth.consumer_key, oauth.signed_request' do
|
596
596
|
oauth_authenticated = nil
|
597
597
|
oauth_token = nil
|
598
598
|
oauth_consumer_key = nil
|
599
|
+
oauth_signed_request = nil
|
599
600
|
testapp = proc do |env|
|
600
601
|
oauth_authenticated = env['oauth.authenticated']
|
601
602
|
oauth_token = env['oauth.token']
|
602
603
|
oauth_consumer_key = env['oauth.consumer_key']
|
604
|
+
oauth_signed_request = env['oauth.signed_request']
|
603
605
|
[200, {}, ['☺']]
|
604
606
|
end
|
605
607
|
otestapp = OAuthenticator::RackAuthenticator.new(testapp, :config_methods => OAuthenticatorTestConfigMethods)
|
@@ -607,6 +609,7 @@ describe OAuthenticator::RackAuthenticator do
|
|
607
609
|
assert_equal(token, oauth_token)
|
608
610
|
assert_equal(consumer_key, oauth_consumer_key)
|
609
611
|
assert_equal(true, oauth_authenticated)
|
612
|
+
assert_kind_of(OAuthenticator::SignedRequest, oauth_signed_request)
|
610
613
|
end
|
611
614
|
end
|
612
615
|
end
|
@@ -87,7 +87,7 @@ describe OAuthenticator::SignableRequest do
|
|
87
87
|
end
|
88
88
|
it 'does not generate timestamp' do
|
89
89
|
request = example_request(:signature_method => 'PLAINTEXT')
|
90
|
-
assert(!request.protocol_params.key?('
|
90
|
+
assert(!request.protocol_params.key?('oauth_timestamp'))
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -329,6 +329,7 @@ describe OAuthenticator::SignableRequest do
|
|
329
329
|
|
330
330
|
it 'excludes query and fragment' do
|
331
331
|
assert_equal('http://example.com/FooBar', example_request(:uri => 'http://example.com/FooBar?foo=bar#foobar').send(:base_string_uri))
|
332
|
+
assert_equal('http://example.com/FooBar', example_request(:uri => 'http://example.com/FooBar#foobar').send(:base_string_uri))
|
332
333
|
end
|
333
334
|
end
|
334
335
|
|
metadata
CHANGED
@@ -1,57 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oauthenticator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.4'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.0'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '1.4'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: json
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
39
|
+
version: '0'
|
34
40
|
type: :runtime
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
|
-
- - "
|
44
|
+
- - ">="
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
46
|
+
version: '0'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: faraday
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
|
-
- - "
|
51
|
+
- - ">="
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '0.9'
|
54
|
+
- - "<"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '2.0'
|
48
57
|
type: :runtime
|
49
58
|
prerelease: false
|
50
59
|
version_requirements: !ruby/object:Gem::Requirement
|
51
60
|
requirements:
|
52
|
-
- - "
|
61
|
+
- - ">="
|
53
62
|
- !ruby/object:Gem::Version
|
54
63
|
version: '0.9'
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '2.0'
|
55
67
|
- !ruby/object:Gem::Dependency
|
56
68
|
name: addressable
|
57
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -228,8 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
240
|
- !ruby/object:Gem::Version
|
229
241
|
version: '0'
|
230
242
|
requirements: []
|
231
|
-
|
232
|
-
rubygems_version: 2.2.2
|
243
|
+
rubygems_version: 3.0.6
|
233
244
|
signing_key:
|
234
245
|
specification_version: 4
|
235
246
|
summary: OAuth 1.0 request signing and authentication
|
@@ -244,4 +255,3 @@ test_files:
|
|
244
255
|
- test/signed_request_test.rb
|
245
256
|
- test/test_config_methods.rb
|
246
257
|
- ".simplecov"
|
247
|
-
has_rdoc:
|