rack-oauth2 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -4
- data/VERSION +1 -1
- data/lib/rack/oauth2/access_token/mac.rb +6 -6
- data/lib/rack/oauth2/client.rb +9 -1
- data/lib/rack/oauth2/server/resource/error.rb +3 -3
- data/spec/fake_response/{invalid_request.json → errors/invalid_request.json} +0 -0
- data/spec/fake_response/{token.json → tokens/bearer.json} +1 -0
- data/spec/fake_response/tokens/legacy.json +5 -0
- data/spec/fake_response/{facebook_token_response.txt → tokens/legacy.txt} +0 -0
- data/spec/fake_response/tokens/mac.json +8 -0
- data/spec/rack/oauth2/access_token/mac_spec.rb +6 -6
- data/spec/rack/oauth2/client_spec.rb +58 -20
- data/spec/rack/oauth2/server/resource/error_spec.rb +1 -1
- metadata +13 -9
data/README.rdoc
CHANGED
@@ -6,8 +6,8 @@ Both Bearer and MAC token type are supported.
|
|
6
6
|
The OAuth 2.0 Authorization Protocol (draft 15)
|
7
7
|
http://tools.ietf.org/html/draft-ietf-oauth-v2-15
|
8
8
|
|
9
|
-
The OAuth 2.0 Protocol: Bearer Tokens (draft
|
10
|
-
http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-
|
9
|
+
The OAuth 2.0 Protocol: Bearer Tokens (draft 04)
|
10
|
+
http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-04
|
11
11
|
|
12
12
|
HTTP Authentication: MAC Authentication (draft 02)
|
13
13
|
http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-02
|
@@ -42,7 +42,7 @@ http://github.com/nov/rack-oauth2-sample-mac
|
|
42
42
|
|
43
43
|
== Sample Client
|
44
44
|
|
45
|
-
=== Bearer
|
45
|
+
=== Common between Bearer and MAC
|
46
46
|
|
47
47
|
Authorization Request (request_type: 'code' and 'token')
|
48
48
|
https://gist.github.com/862393
|
@@ -50,12 +50,15 @@ https://gist.github.com/862393
|
|
50
50
|
Token Request (grant_type: 'client_credentials', 'password', 'authorization_code' and 'refresh_token')
|
51
51
|
https://gist.github.com/883541
|
52
52
|
|
53
|
+
=== Bearer
|
54
|
+
|
53
55
|
Resource Request (request both for resource owner resource and for client resource)
|
54
56
|
https://gist.github.com/883575
|
55
57
|
|
56
58
|
=== MAC
|
57
59
|
|
58
|
-
|
60
|
+
Resource Request (request both for resource owner resource and for client resource)
|
61
|
+
https://gist.github.com/933885
|
59
62
|
|
60
63
|
== Note on Patches/Pull Requests
|
61
64
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.4
|
@@ -88,12 +88,12 @@ module Rack
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def authorization_header
|
91
|
-
header = "MAC
|
92
|
-
header << "token=\"#{access_token}\","
|
93
|
-
header << "timestamp=\"#{timestamp}\","
|
94
|
-
header << "nonce=\"#{nonce}\","
|
95
|
-
header << "bodyhash=\"#{body_hash}\"," if self.body_hash.present?
|
96
|
-
header << "signature=\"#{signature}\""
|
91
|
+
header = "MAC"
|
92
|
+
header << " token=\"#{access_token}\","
|
93
|
+
header << " timestamp=\"#{timestamp}\","
|
94
|
+
header << " nonce=\"#{nonce}\","
|
95
|
+
header << " bodyhash=\"#{body_hash}\"," if self.body_hash.present?
|
96
|
+
header << " signature=\"#{signature}\""
|
97
97
|
end
|
98
98
|
|
99
99
|
def generate_nonce
|
data/lib/rack/oauth2/client.rb
CHANGED
@@ -67,7 +67,15 @@ module Rack
|
|
67
67
|
|
68
68
|
def handle_response
|
69
69
|
response = yield
|
70
|
-
JSON.parse(response.body).with_indifferent_access
|
70
|
+
token_hash = JSON.parse(response.body).with_indifferent_access
|
71
|
+
case token_hash[:token_type]
|
72
|
+
when 'bearer'
|
73
|
+
AccessToken::Bearer.new(token_hash)
|
74
|
+
when 'mac'
|
75
|
+
AccessToken::MAC.new(token_hash)
|
76
|
+
else
|
77
|
+
token_hash
|
78
|
+
end
|
71
79
|
rescue JSON::ParserError
|
72
80
|
# NOTE: Facebook support (They don't use JSON as token response)
|
73
81
|
Rack::Utils.parse_nested_query(response.body).with_indifferent_access
|
@@ -15,9 +15,9 @@ module Rack
|
|
15
15
|
self.realm ||= DEFAULT_REALM
|
16
16
|
header = response.header['WWW-Authenticate'] = "#{scheme} realm=\"#{realm}\""
|
17
17
|
if ErrorMethods::DEFAULT_DESCRIPTION.keys.include?(error)
|
18
|
-
header << ",error=\"#{error}\""
|
19
|
-
header << ",error_description=\"#{description}\"" if description.present?
|
20
|
-
header << ",error_uri=\"#{uri}\"" if uri.present?
|
18
|
+
header << ", error=\"#{error}\""
|
19
|
+
header << ", error_description=\"#{description}\"" if description.present?
|
20
|
+
header << ", error_uri=\"#{uri}\"" if uri.present?
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
File without changes
|
File without changes
|
@@ -37,7 +37,7 @@ describe Rack::OAuth2::AccessToken::MAC do
|
|
37
37
|
Time.fix(Time.at(1302361200)) do
|
38
38
|
RestClient.should_receive(:get).with(
|
39
39
|
resource_endpoint,
|
40
|
-
:AUTHORIZATION => "MAC token=\"access_token\",timestamp=\"1302361200\",nonce=\"51e74de734c05613f37520872e68db5f\",signature=\"yYDSkZMrEbOOqj0anHNLA9ougNA+lxU0zmPiMSPtmJ8=\""
|
40
|
+
:AUTHORIZATION => "MAC token=\"access_token\", timestamp=\"1302361200\", nonce=\"51e74de734c05613f37520872e68db5f\", signature=\"yYDSkZMrEbOOqj0anHNLA9ougNA+lxU0zmPiMSPtmJ8=\""
|
41
41
|
)
|
42
42
|
token.get resource_endpoint
|
43
43
|
end
|
@@ -50,7 +50,7 @@ describe Rack::OAuth2::AccessToken::MAC do
|
|
50
50
|
RestClient.should_receive(:post).with(
|
51
51
|
resource_endpoint,
|
52
52
|
{:key => :value},
|
53
|
-
{:AUTHORIZATION => "MAC token=\"access_token\",timestamp=\"1302361200\",nonce=\"51e74de734c05613f37520872e68db5f\",bodyhash=\"Vj8DVxGNBe8UXWvd8pZswj6Gyo8vAT+RXlZa/fCfeiM=\",signature=\"xRvIiA+rmjhPjULVpyCCgiHEsOkLEHZik4ZaB+cyqgk=\""}
|
53
|
+
{:AUTHORIZATION => "MAC token=\"access_token\", timestamp=\"1302361200\", nonce=\"51e74de734c05613f37520872e68db5f\", bodyhash=\"Vj8DVxGNBe8UXWvd8pZswj6Gyo8vAT+RXlZa/fCfeiM=\", signature=\"xRvIiA+rmjhPjULVpyCCgiHEsOkLEHZik4ZaB+cyqgk=\""}
|
54
54
|
)
|
55
55
|
token.post resource_endpoint, :key => :value
|
56
56
|
end
|
@@ -63,7 +63,7 @@ describe Rack::OAuth2::AccessToken::MAC do
|
|
63
63
|
RestClient.should_receive(:put).with(
|
64
64
|
resource_endpoint,
|
65
65
|
{:key => :value},
|
66
|
-
{:AUTHORIZATION => "MAC token=\"access_token\",timestamp=\"1302361200\",nonce=\"51e74de734c05613f37520872e68db5f\",bodyhash=\"Vj8DVxGNBe8UXWvd8pZswj6Gyo8vAT+RXlZa/fCfeiM=\",signature=\"2lWgkUCtD9lNBlDi5fe9eVDwEwbxfLGAqjgykaSV1ww=\""}
|
66
|
+
{:AUTHORIZATION => "MAC token=\"access_token\", timestamp=\"1302361200\", nonce=\"51e74de734c05613f37520872e68db5f\", bodyhash=\"Vj8DVxGNBe8UXWvd8pZswj6Gyo8vAT+RXlZa/fCfeiM=\", signature=\"2lWgkUCtD9lNBlDi5fe9eVDwEwbxfLGAqjgykaSV1ww=\""}
|
67
67
|
)
|
68
68
|
token.put resource_endpoint, :key => :value
|
69
69
|
end
|
@@ -75,7 +75,7 @@ describe Rack::OAuth2::AccessToken::MAC do
|
|
75
75
|
Time.fix(Time.at(1302361200)) do
|
76
76
|
RestClient.should_receive(:delete).with(
|
77
77
|
resource_endpoint,
|
78
|
-
:AUTHORIZATION => "MAC token=\"access_token\",timestamp=\"1302361200\",nonce=\"51e74de734c05613f37520872e68db5f\",signature=\"PX2GhHuo5yYNEs51e4Zlllw8itQ4Te0v+6ZuRCK7k+s=\""
|
78
|
+
:AUTHORIZATION => "MAC token=\"access_token\", timestamp=\"1302361200\", nonce=\"51e74de734c05613f37520872e68db5f\", signature=\"PX2GhHuo5yYNEs51e4Zlllw8itQ4Te0v+6ZuRCK7k+s=\""
|
79
79
|
)
|
80
80
|
token.delete resource_endpoint
|
81
81
|
end
|
@@ -90,7 +90,7 @@ describe Rack::OAuth2::AccessToken::MAC do
|
|
90
90
|
let(:env) do
|
91
91
|
Rack::MockRequest.env_for(
|
92
92
|
'/protected_resources',
|
93
|
-
'HTTP_AUTHORIZATION' => "MAC token=\"access_token\",timestamp=\"1302361200\",nonce=\"51e74de734c05613f37520872e68db5f\",signature=\"#{signature}\""
|
93
|
+
'HTTP_AUTHORIZATION' => "MAC token=\"access_token\", timestamp=\"1302361200\", nonce=\"51e74de734c05613f37520872e68db5f\", signature=\"#{signature}\""
|
94
94
|
)
|
95
95
|
end
|
96
96
|
|
@@ -122,7 +122,7 @@ describe Rack::OAuth2::AccessToken::MAC do
|
|
122
122
|
:params => {
|
123
123
|
:key1 => 'value1'
|
124
124
|
},
|
125
|
-
'HTTP_AUTHORIZATION' => "MAC token=\"access_token\",timestamp=\"1302361200\",nonce=\"51e74de734c05613f37520872e68db5f\",bodyhash=\"#{body_hash}\",signature=\"#{signature}\""
|
125
|
+
'HTTP_AUTHORIZATION' => "MAC token=\"access_token\", timestamp=\"1302361200\", nonce=\"51e74de734c05613f37520872e68db5f\", bodyhash=\"#{body_hash}\", signature=\"#{signature}\""
|
126
126
|
)
|
127
127
|
end
|
128
128
|
let(:signature) { 'invalid' }
|
@@ -72,44 +72,68 @@ describe Rack::OAuth2::Client do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
describe '#access_token!' do
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
subject { client.access_token! }
|
76
|
+
|
77
|
+
context 'when bearer token is given' do
|
78
|
+
before do
|
79
|
+
client.authorization_code = 'code'
|
80
|
+
fake_response(
|
81
|
+
:post,
|
82
|
+
'https://server.example.com/oauth2/token',
|
83
|
+
'tokens/bearer.json'
|
84
|
+
)
|
85
|
+
end
|
86
|
+
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
|
87
|
+
its(:token_type) { should == :bearer }
|
88
|
+
its(:access_token) { should == 'access_token' }
|
89
|
+
its(:refresh_token) { should == 'refresh_token' }
|
90
|
+
its(:expires_in) { should == 3600 }
|
82
91
|
end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
92
|
+
|
93
|
+
context 'when mac token is given' do
|
94
|
+
before do
|
95
|
+
client.authorization_code = 'code'
|
96
|
+
fake_response(
|
97
|
+
:post,
|
98
|
+
'https://server.example.com/oauth2/token',
|
99
|
+
'tokens/mac.json'
|
100
|
+
)
|
101
|
+
end
|
102
|
+
it { should be_instance_of Rack::OAuth2::AccessToken::MAC }
|
103
|
+
its(:token_type) { should == :mac }
|
104
|
+
its(:access_token) { should == 'access_token' }
|
105
|
+
its(:refresh_token) { should == 'refresh_token' }
|
106
|
+
its(:expires_in) { should == 3600 }
|
89
107
|
end
|
90
108
|
|
91
|
-
context 'when
|
92
|
-
before
|
109
|
+
context 'when legacy-style (JSON) token is given' do
|
110
|
+
before do
|
111
|
+
client.authorization_code = 'code'
|
93
112
|
fake_response(
|
94
113
|
:post,
|
95
114
|
'https://server.example.com/oauth2/token',
|
96
|
-
'
|
97
|
-
:status => 400
|
115
|
+
'tokens/legacy.json'
|
98
116
|
)
|
99
117
|
end
|
118
|
+
it { should be_instance_of ActiveSupport::HashWithIndifferentAccess }
|
100
119
|
it do
|
101
|
-
|
120
|
+
client.access_token!.should == {
|
121
|
+
'access_token' => 'access_token',
|
122
|
+
'refresh_token' => 'refresh_token',
|
123
|
+
'expires_in' => 3600
|
124
|
+
}
|
102
125
|
end
|
103
126
|
end
|
104
127
|
|
105
|
-
context 'when key-value response is given' do
|
128
|
+
context 'when legacy-style (key-value) response is given' do
|
106
129
|
before do
|
107
130
|
fake_response(
|
108
131
|
:post,
|
109
132
|
'https://server.example.com/oauth2/token',
|
110
|
-
'
|
133
|
+
'tokens/legacy.txt'
|
111
134
|
)
|
112
135
|
end
|
136
|
+
it { should be_instance_of ActiveSupport::HashWithIndifferentAccess }
|
113
137
|
it do
|
114
138
|
client.access_token!.should == {
|
115
139
|
'access_token' => 'access_token',
|
@@ -117,5 +141,19 @@ describe Rack::OAuth2::Client do
|
|
117
141
|
}
|
118
142
|
end
|
119
143
|
end
|
144
|
+
|
145
|
+
context 'when error response is given' do
|
146
|
+
before do
|
147
|
+
fake_response(
|
148
|
+
:post,
|
149
|
+
'https://server.example.com/oauth2/token',
|
150
|
+
'errors/invalid_request.json',
|
151
|
+
:status => 400
|
152
|
+
)
|
153
|
+
end
|
154
|
+
it do
|
155
|
+
expect { client.access_token! }.should raise_error Rack::OAuth2::Client::Error
|
156
|
+
end
|
157
|
+
end
|
120
158
|
end
|
121
159
|
end
|
@@ -43,7 +43,7 @@ describe Rack::OAuth2::Server::Resource::Unauthorized do
|
|
43
43
|
status, header, response = error_with_scheme.finish
|
44
44
|
status.should == 401
|
45
45
|
header['Content-Type'].should == 'application/json'
|
46
|
-
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\",error=\"invalid_token\""
|
46
|
+
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\", error=\"invalid_token\""
|
47
47
|
response.body.should == ['{"error":"invalid_token"}']
|
48
48
|
end
|
49
49
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-oauth2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 4
|
10
|
+
version: 0.6.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- nov matake
|
@@ -223,10 +223,12 @@ files:
|
|
223
223
|
- lib/rack/oauth2/server/token/refresh_token.rb
|
224
224
|
- lib/rack/oauth2/util.rb
|
225
225
|
- rack-oauth2.gemspec
|
226
|
-
- spec/fake_response/
|
227
|
-
- spec/fake_response/invalid_request.json
|
226
|
+
- spec/fake_response/errors/invalid_request.json
|
228
227
|
- spec/fake_response/resources/fake.txt
|
229
|
-
- spec/fake_response/
|
228
|
+
- spec/fake_response/tokens/bearer.json
|
229
|
+
- spec/fake_response/tokens/legacy.json
|
230
|
+
- spec/fake_response/tokens/legacy.txt
|
231
|
+
- spec/fake_response/tokens/mac.json
|
230
232
|
- spec/helpers/time.rb
|
231
233
|
- spec/rack/oauth2/access_token/bearer_spec.rb
|
232
234
|
- spec/rack/oauth2/access_token/mac/verifier_spec.rb
|
@@ -290,10 +292,12 @@ signing_key:
|
|
290
292
|
specification_version: 3
|
291
293
|
summary: OAuth 2.0 Server & Client Library - Both Bearer and MAC token type are supported
|
292
294
|
test_files:
|
293
|
-
- spec/fake_response/
|
294
|
-
- spec/fake_response/invalid_request.json
|
295
|
+
- spec/fake_response/errors/invalid_request.json
|
295
296
|
- spec/fake_response/resources/fake.txt
|
296
|
-
- spec/fake_response/
|
297
|
+
- spec/fake_response/tokens/bearer.json
|
298
|
+
- spec/fake_response/tokens/legacy.json
|
299
|
+
- spec/fake_response/tokens/legacy.txt
|
300
|
+
- spec/fake_response/tokens/mac.json
|
297
301
|
- spec/helpers/time.rb
|
298
302
|
- spec/rack/oauth2/access_token/bearer_spec.rb
|
299
303
|
- spec/rack/oauth2/access_token/mac/verifier_spec.rb
|