songkick-oauth2-provider 0.10.2 → 0.10.3
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 +7 -0
- data/History.txt +7 -0
- data/README.rdoc +18 -11
- data/example/README.rdoc +1 -1
- data/example/application.rb +9 -9
- data/example/schema.rb +1 -1
- data/example/views/authorize.erb +2 -2
- data/example/views/layout.erb +4 -4
- data/example/views/login.erb +2 -2
- data/example/views/new_client.erb +1 -1
- data/example/views/new_user.erb +1 -1
- data/lib/songkick/oauth2/model.rb +8 -6
- data/lib/songkick/oauth2/model/authorization.rb +31 -31
- data/lib/songkick/oauth2/model/client.rb +15 -15
- data/lib/songkick/oauth2/model/client_owner.rb +2 -2
- data/lib/songkick/oauth2/model/hashing.rb +3 -3
- data/lib/songkick/oauth2/model/helpers.rb +16 -0
- data/lib/songkick/oauth2/model/resource_owner.rb +4 -4
- data/lib/songkick/oauth2/provider.rb +16 -16
- data/lib/songkick/oauth2/provider/access_token.rb +20 -15
- data/lib/songkick/oauth2/provider/authorization.rb +43 -42
- data/lib/songkick/oauth2/provider/error.rb +4 -4
- data/lib/songkick/oauth2/provider/exchange.rb +46 -46
- data/lib/songkick/oauth2/router.rb +13 -13
- data/lib/songkick/oauth2/schema.rb +11 -3
- data/lib/songkick/oauth2/schema/20120828112156_songkick_oauth2_schema_original_schema.rb +2 -2
- data/lib/songkick/oauth2/schema/20121024180930_songkick_oauth2_schema_add_authorization_index.rb +3 -3
- data/lib/songkick/oauth2/schema/20121025180447_songkick_oauth2_schema_add_unique_indexes.rb +7 -7
- data/spec/request_helpers.rb +25 -21
- data/spec/songkick/oauth2/model/authorization_spec.rb +56 -56
- data/spec/songkick/oauth2/model/client_spec.rb +9 -9
- data/spec/songkick/oauth2/model/helpers_spec.rb +26 -0
- data/spec/songkick/oauth2/model/resource_owner_spec.rb +13 -13
- data/spec/songkick/oauth2/provider/access_token_spec.rb +32 -20
- data/spec/songkick/oauth2/provider/authorization_spec.rb +73 -62
- data/spec/songkick/oauth2/provider/exchange_spec.rb +72 -72
- data/spec/songkick/oauth2/provider_spec.rb +101 -101
- data/spec/spec_helper.rb +5 -3
- data/spec/test_app/helper.rb +11 -7
- data/spec/test_app/provider/application.rb +12 -12
- data/spec/test_app/provider/views/authorize.erb +2 -2
- metadata +71 -93
data/spec/request_helpers.rb
CHANGED
@@ -1,57 +1,61 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
1
3
|
module RequestHelpers
|
2
|
-
require
|
3
|
-
|
4
|
+
require "net/http"
|
5
|
+
|
6
|
+
SERVER_PORT = TCPServer.new(0).addr[1]
|
7
|
+
|
4
8
|
def querystring(params)
|
5
|
-
params.map { |k,v| "#{ CGI.escape k.to_s }=#{ CGI.escape v.to_s }" }.join(
|
9
|
+
params.map { |k,v| "#{ CGI.escape k.to_s }=#{ CGI.escape v.to_s }" }.join("&")
|
6
10
|
end
|
7
|
-
|
11
|
+
|
8
12
|
def get(query_params)
|
9
|
-
uri = URI.parse(
|
13
|
+
uri = URI.parse("http://localhost:#{SERVER_PORT}/authorize?" + querystring(query_params))
|
10
14
|
Net::HTTP.get_response(uri)
|
11
15
|
end
|
12
|
-
|
16
|
+
|
13
17
|
def allow_or_deny(query_params)
|
14
|
-
Net::HTTP.post_form(URI.parse(
|
18
|
+
Net::HTTP.post_form(URI.parse("http://localhost:#{SERVER_PORT}/allow"), query_params)
|
15
19
|
end
|
16
|
-
|
20
|
+
|
17
21
|
def post_basic_auth(auth_params, query_params)
|
18
|
-
url = "http://#{ auth_params[
|
22
|
+
url = "http://#{ auth_params["client_id"] }:#{ auth_params["client_secret"] }@localhost:#{SERVER_PORT}/authorize"
|
19
23
|
Net::HTTP.post_form(URI.parse(url), query_params)
|
20
24
|
end
|
21
|
-
|
25
|
+
|
22
26
|
def post(body_params, query_params = {})
|
23
|
-
uri = URI.parse(
|
27
|
+
uri = URI.parse("http://localhost:#{SERVER_PORT}/authorize?" + querystring(query_params))
|
24
28
|
Net::HTTP.start(uri.host, uri.port) do |http|
|
25
|
-
http.post(uri.path +
|
29
|
+
http.post(uri.path + "?" + uri.query.to_s, querystring(body_params))
|
26
30
|
end
|
27
31
|
end
|
28
|
-
|
32
|
+
|
29
33
|
def validate_response(response, status, body)
|
30
34
|
response.code.to_i.should == status
|
31
35
|
response.body.should == body
|
32
|
-
response[
|
36
|
+
response["Cache-Control"].should == "no-store"
|
33
37
|
end
|
34
|
-
|
38
|
+
|
35
39
|
def validate_json_response(response, status, body)
|
36
40
|
response.code.to_i.should == status
|
37
41
|
JSON.parse(response.body).should == body
|
38
|
-
response[
|
39
|
-
response[
|
42
|
+
response["Content-Type"].should == "application/json"
|
43
|
+
response["Cache-Control"].should == "no-store"
|
40
44
|
end
|
41
|
-
|
45
|
+
|
42
46
|
def mock_request(request_class, stubs = {})
|
43
|
-
mock_request =
|
47
|
+
mock_request = double(request_class)
|
44
48
|
method_stubs = {
|
45
49
|
:redirect? => false,
|
46
50
|
:response_body => nil,
|
47
51
|
:response_headers => {},
|
48
52
|
:response_status => 200
|
49
53
|
}.merge(stubs)
|
50
|
-
|
54
|
+
|
51
55
|
method_stubs.each do |method, value|
|
52
56
|
mock_request.should_receive(method).and_return(value)
|
53
57
|
end
|
54
|
-
|
58
|
+
|
55
59
|
mock_request
|
56
60
|
end
|
57
61
|
end
|
@@ -6,112 +6,112 @@ describe Songkick::OAuth2::Model::Authorization do
|
|
6
6
|
let(:owner) { Factory :owner }
|
7
7
|
let(:user) { Factory :owner }
|
8
8
|
let(:tester) { Factory(:owner) }
|
9
|
-
|
9
|
+
|
10
10
|
let(:authorization) do
|
11
11
|
create_authorization(:owner => tester, :client => client)
|
12
12
|
end
|
13
|
-
|
14
|
-
it "is
|
13
|
+
|
14
|
+
it "is valid" do
|
15
15
|
authorization.should be_valid
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "is not valid without a client" do
|
19
19
|
authorization.client = nil
|
20
20
|
authorization.should_not be_valid
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "is not valid without an owner" do
|
24
24
|
authorization.owner = nil
|
25
25
|
authorization.should_not be_valid
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
describe "when there are existing authorizations" do
|
29
29
|
before do
|
30
30
|
create_authorization(
|
31
31
|
:owner => user,
|
32
32
|
:client => impostor,
|
33
33
|
:access_token => 'existing_access_token')
|
34
|
-
|
34
|
+
|
35
35
|
create_authorization(
|
36
36
|
:owner => user,
|
37
37
|
:client => client,
|
38
38
|
:code => 'existing_code')
|
39
|
-
|
39
|
+
|
40
40
|
create_authorization(
|
41
41
|
:owner => owner,
|
42
42
|
:client => client,
|
43
43
|
:refresh_token => 'existing_refresh_token')
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it "is valid if its access_token is unique" do
|
47
47
|
authorization.should be_valid
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it "is valid if both access_tokens are nil" do
|
51
51
|
Songkick::OAuth2::Model::Authorization.first.update_attribute(:access_token, nil)
|
52
52
|
authorization.access_token = nil
|
53
53
|
authorization.should be_valid
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "is not valid if its access_token is not unique" do
|
57
57
|
authorization.access_token = 'existing_access_token'
|
58
58
|
authorization.should_not be_valid
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
it "is valid if it has a unique code for its client" do
|
62
62
|
authorization.client = impostor
|
63
63
|
authorization.code = 'existing_code'
|
64
64
|
authorization.should be_valid
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "is not valid if it does not have a unique client and code" do
|
68
68
|
authorization.code = 'existing_code'
|
69
69
|
authorization.should_not be_valid
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
it "is valid if it has a unique refresh_token for its client" do
|
73
73
|
authorization.client = impostor
|
74
74
|
authorization.refresh_token = 'existing_refresh_token'
|
75
75
|
authorization.should be_valid
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it "is not valid if it does not have a unique client and refresh_token" do
|
79
79
|
authorization.refresh_token = 'existing_refresh_token'
|
80
80
|
authorization.should_not be_valid
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
describe ".create_code" do
|
84
84
|
before { Songkick::OAuth2.stub(:random_string).and_return('existing_code', 'new_code') }
|
85
|
-
|
85
|
+
|
86
86
|
it "returns the first code the client has not used" do
|
87
87
|
Songkick::OAuth2::Model::Authorization.create_code(client).should == 'new_code'
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
it "returns the first code another client has not used" do
|
91
91
|
Songkick::OAuth2::Model::Authorization.create_code(impostor).should == 'existing_code'
|
92
92
|
end
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
describe ".create_access_token" do
|
96
96
|
before { Songkick::OAuth2.stub(:random_string).and_return('existing_access_token', 'new_access_token') }
|
97
|
-
|
97
|
+
|
98
98
|
it "returns the first unused token it can find" do
|
99
99
|
Songkick::OAuth2::Model::Authorization.create_access_token.should == 'new_access_token'
|
100
100
|
end
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
describe ".create_refresh_token" do
|
104
104
|
before { Songkick::OAuth2.stub(:random_string).and_return('existing_refresh_token', 'new_refresh_token') }
|
105
|
-
|
105
|
+
|
106
106
|
it "returns the first refresh_token the client has not used" do
|
107
107
|
Songkick::OAuth2::Model::Authorization.create_refresh_token(client).should == 'new_refresh_token'
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
it "returns the first refresh_token another client has not used" do
|
111
111
|
Songkick::OAuth2::Model::Authorization.create_refresh_token(impostor).should == 'existing_refresh_token'
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
describe "duplicate records" do
|
116
116
|
it "raises an error if a duplicate authorization is created" do
|
117
117
|
lambda {
|
@@ -121,7 +121,7 @@ describe Songkick::OAuth2::Model::Authorization do
|
|
121
121
|
authorization.save
|
122
122
|
}.should raise_error
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
it "finds an existing record after a race" do
|
126
126
|
user.stub(:oauth2_authorization_for) do
|
127
127
|
user.unstub(:oauth2_authorization_for)
|
@@ -133,19 +133,19 @@ describe Songkick::OAuth2::Model::Authorization do
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
end
|
136
|
-
|
136
|
+
|
137
137
|
describe "#exchange!" do
|
138
138
|
it "saves the record" do
|
139
139
|
authorization.should_receive(:save!)
|
140
140
|
authorization.exchange!
|
141
141
|
end
|
142
|
-
|
142
|
+
|
143
143
|
it "uses its helpers to find unique tokens" do
|
144
144
|
Songkick::OAuth2::Model::Authorization.should_receive(:create_access_token).and_return('access_token')
|
145
145
|
authorization.exchange!
|
146
146
|
authorization.access_token.should == 'access_token'
|
147
147
|
end
|
148
|
-
|
148
|
+
|
149
149
|
it "updates the tokens correctly" do
|
150
150
|
authorization.exchange!
|
151
151
|
authorization.should be_valid
|
@@ -153,84 +153,84 @@ describe Songkick::OAuth2::Model::Authorization do
|
|
153
153
|
authorization.refresh_token.should be_nil
|
154
154
|
end
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
describe "#expired?" do
|
158
158
|
it "returns false when not expiry is set" do
|
159
159
|
authorization.should_not be_expired
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
it "returns false when expiry is in the future" do
|
163
163
|
authorization.expires_at = 2.days.from_now
|
164
164
|
authorization.should_not be_expired
|
165
165
|
end
|
166
|
-
|
166
|
+
|
167
167
|
it "returns true when expiry is in the past" do
|
168
168
|
authorization.expires_at = 2.days.ago
|
169
169
|
authorization.should be_expired
|
170
170
|
end
|
171
171
|
end
|
172
|
-
|
172
|
+
|
173
173
|
describe "#grants_access?" do
|
174
174
|
it "returns true given the right user" do
|
175
|
-
authorization.grants_access?(tester).should
|
175
|
+
authorization.grants_access?(tester).should be(true)
|
176
176
|
end
|
177
|
-
|
177
|
+
|
178
178
|
it "returns false given the wrong user" do
|
179
|
-
authorization.grants_access?(user).should
|
179
|
+
authorization.grants_access?(user).should be(false)
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
describe "when the authorization is expired" do
|
183
183
|
before { authorization.expires_at = 2.days.ago }
|
184
|
-
|
184
|
+
|
185
185
|
it "returns false in all cases" do
|
186
|
-
authorization.grants_access?(tester).should
|
187
|
-
authorization.grants_access?(user).should
|
186
|
+
authorization.grants_access?(tester).should be(false)
|
187
|
+
authorization.grants_access?(user).should be(false)
|
188
188
|
end
|
189
189
|
end
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
describe "with a scope" do
|
193
193
|
before { authorization.scope = 'foo bar' }
|
194
|
-
|
194
|
+
|
195
195
|
describe "#in_scope?" do
|
196
196
|
it "returns true for authorized scopes" do
|
197
197
|
authorization.should be_in_scope('foo')
|
198
198
|
authorization.should be_in_scope('bar')
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
it "returns false for unauthorized scopes" do
|
202
202
|
authorization.should_not be_in_scope('qux')
|
203
203
|
authorization.should_not be_in_scope('fo')
|
204
204
|
end
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
describe "#grants_access?" do
|
208
208
|
it "returns true given the right user and all authorization scopes" do
|
209
|
-
authorization.grants_access?(tester, 'foo', 'bar').should
|
209
|
+
authorization.grants_access?(tester, 'foo', 'bar').should be(true)
|
210
210
|
end
|
211
|
-
|
211
|
+
|
212
212
|
it "returns true given the right user and some authorization scopes" do
|
213
|
-
authorization.grants_access?(tester, 'bar').should
|
213
|
+
authorization.grants_access?(tester, 'bar').should be(true)
|
214
214
|
end
|
215
|
-
|
215
|
+
|
216
216
|
it "returns false given the right user and some unauthorization scopes" do
|
217
|
-
authorization.grants_access?(tester, 'foo', 'bar', 'qux').should
|
217
|
+
authorization.grants_access?(tester, 'foo', 'bar', 'qux').should be(false)
|
218
218
|
end
|
219
|
-
|
219
|
+
|
220
220
|
it "returns false given an unauthorized scope" do
|
221
|
-
authorization.grants_access?(tester, 'qux').should
|
221
|
+
authorization.grants_access?(tester, 'qux').should be(false)
|
222
222
|
end
|
223
|
-
|
223
|
+
|
224
224
|
it "returns true given the right user" do
|
225
|
-
authorization.grants_access?(tester).should
|
225
|
+
authorization.grants_access?(tester).should be(true)
|
226
226
|
end
|
227
|
-
|
227
|
+
|
228
228
|
it "returns false given the wrong user" do
|
229
|
-
authorization.grants_access?(user).should
|
229
|
+
authorization.grants_access?(user).should be(false)
|
230
230
|
end
|
231
|
-
|
231
|
+
|
232
232
|
it "returns false given the wrong user and an authorized scope" do
|
233
|
-
authorization.grants_access?(user, 'foo').should
|
233
|
+
authorization.grants_access?(user, 'foo').should be(false)
|
234
234
|
end
|
235
235
|
end
|
236
236
|
end
|
@@ -6,47 +6,47 @@ describe Songkick::OAuth2::Model::Client do
|
|
6
6
|
@owner = Factory(:owner)
|
7
7
|
Songkick::OAuth2::Model::Authorization.for(@owner, @client)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it "is valid" do
|
11
11
|
@client.should be_valid
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "is invalid without a name" do
|
15
15
|
@client.name = nil
|
16
16
|
@client.should_not be_valid
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "is invalid without a redirect_uri" do
|
20
20
|
@client.redirect_uri = nil
|
21
21
|
@client.should_not be_valid
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "is invalid with a non-URI redirect_uri" do
|
25
25
|
@client.redirect_uri = 'foo'
|
26
26
|
@client.should_not be_valid
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# http://en.wikipedia.org/wiki/HTTP_response_splitting
|
30
30
|
it "is invalid if the URI contains HTTP line breaks" do
|
31
31
|
@client.redirect_uri = "http://example.com/c\r\nb"
|
32
32
|
@client.should_not be_valid
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it "cannot mass-assign client_id" do
|
36
36
|
@client.update_attributes(:client_id => 'foo')
|
37
37
|
@client.client_id.should_not == 'foo'
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "cannot mass-assign client_secret" do
|
41
41
|
@client.update_attributes(:client_secret => 'foo')
|
42
42
|
@client.client_secret.should_not == 'foo'
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "has client_id and client_secret filled in" do
|
46
46
|
@client.client_id.should_not be_nil
|
47
47
|
@client.client_secret.should_not be_nil
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it "destroys its authorizations on destroy" do
|
51
51
|
@client.destroy
|
52
52
|
Songkick::OAuth2::Model::Authorization.count.should be_zero
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Songkick::OAuth2::Model::Helpers do
|
4
|
+
subject { Songkick::OAuth2::Model::Helpers }
|
5
|
+
|
6
|
+
describe '.count' do
|
7
|
+
let(:owner) { Factory(:owner) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
3.times { Factory(:client, :owner => owner) }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when conditions are not passed' do
|
14
|
+
it 'returns count of total rows' do
|
15
|
+
subject.count(owner.oauth2_clients).should == 3
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when conditions are passed' do
|
20
|
+
it 'returns count of rows satisfying supplied conditions' do
|
21
|
+
subject.count(Songkick::OAuth2::Model::Client, :client_id => Songkick::OAuth2::Model::Client.first.client_id).should == 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -5,29 +5,29 @@ describe Songkick::OAuth2::Model::ResourceOwner do
|
|
5
5
|
@owner = Factory(:owner)
|
6
6
|
@client = Factory(:client)
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
describe "#grant_access!" do
|
10
10
|
it "raises an error when passed an invalid client argument" do
|
11
11
|
lambda{ @owner.grant_access!('client') }.should raise_error(ArgumentError)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "creates an authorization between the owner and the client" do
|
15
15
|
authorization = Songkick::OAuth2::Model::Authorization.__send__(:new)
|
16
16
|
Songkick::OAuth2::Model::Authorization.should_receive(:new).and_return(authorization)
|
17
17
|
@owner.grant_access!(@client)
|
18
18
|
end
|
19
|
-
|
20
|
-
# This is hacky, but
|
19
|
+
|
20
|
+
# This is hacky, but doubleing ActiveRecord turns out to get messy
|
21
21
|
it "creates an Authorization" do
|
22
22
|
Songkick::OAuth2::Model::Authorization.count.should == 0
|
23
23
|
@owner.grant_access!(@client)
|
24
24
|
Songkick::OAuth2::Model::Authorization.count.should == 1
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it "returns the authorization" do
|
28
28
|
@owner.grant_access!(@client).should be_kind_of(Songkick::OAuth2::Model::Authorization)
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
# This method must return the same owner object, since the assertion
|
32
32
|
# handler may modify it -- either by changing its attributes or by extending
|
33
33
|
# it with new methods. These changes must be returned to the app calling the
|
@@ -36,34 +36,34 @@ describe Songkick::OAuth2::Model::ResourceOwner do
|
|
36
36
|
authorization = @owner.grant_access!(@client)
|
37
37
|
authorization.owner.should be_equal(@owner)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "sets the duration of the authorization" do
|
41
41
|
authorization = @owner.grant_access!(@client, :duration => 5.hours)
|
42
42
|
authorization.expires_at.to_i.should == (Time.now + 5.hours.to_i).to_i
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
describe "when there is an existing authorization" do
|
47
47
|
before do
|
48
48
|
@authorization = create_authorization(:owner => @owner, :client => @client)
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
it "does not create a new one" do
|
52
52
|
Songkick::OAuth2::Model::Authorization.should_not_receive(:new)
|
53
53
|
@owner.grant_access!(@client)
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "updates the authorization with scopes" do
|
57
57
|
@owner.grant_access!(@client, :scopes => ['foo', 'bar'])
|
58
58
|
@authorization.reload
|
59
59
|
@authorization.scopes.should == Set.new(['foo', 'bar'])
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
describe "with scopes" do
|
63
63
|
before do
|
64
64
|
@authorization.update_attribute(:scope, 'foo bar')
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "merges the new scopes with the existing ones" do
|
68
68
|
@owner.grant_access!(@client, :scopes => ['qux'])
|
69
69
|
@authorization.reload
|
@@ -78,7 +78,7 @@ describe Songkick::OAuth2::Model::ResourceOwner do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it "destroys its authorizations on destroy" do
|
83
83
|
Songkick::OAuth2::Model::Authorization.for(@owner, @client)
|
84
84
|
@owner.destroy
|