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.
@@ -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 03)
10
- http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-03
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
- Coming soon..
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.3
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
@@ -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
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "access_token":"access_token",
3
+ "refresh_token":"refresh_token",
3
4
  "token_type":"bearer",
4
5
  "expires_in":3600
5
6
  }
@@ -0,0 +1,5 @@
1
+ {
2
+ "access_token":"access_token",
3
+ "refresh_token":"refresh_token",
4
+ "expires_in":3600
5
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "token_type":"mac",
3
+ "algorithm":"hmac-sha-256",
4
+ "expires_in":3600,
5
+ "secret":"secret",
6
+ "refresh_token":"refresh_token",
7
+ "access_token":"access_token"
8
+ }
@@ -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
- before do
76
- client.authorization_code = 'code'
77
- fake_response(
78
- :post,
79
- 'https://server.example.com/oauth2/token',
80
- 'token.json'
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
- it do
84
- client.access_token!.should == {
85
- 'access_token' => 'access_token',
86
- 'token_type' => 'bearer',
87
- 'expires_in' => 3600
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 error response is given' do
92
- before do
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
- 'invalid_request.json',
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
- expect { client.access_token! }.should raise_error Rack::OAuth2::Client::Error
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
- 'facebook_token_response.txt'
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: 1
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 3
10
- version: 0.6.3
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/facebook_token_response.txt
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/token.json
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/facebook_token_response.txt
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/token.json
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