oauth2-provider-jonrowe 0.1.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.
- data/README.rdoc +314 -0
- data/example/README.rdoc +11 -0
- data/example/application.rb +151 -0
- data/example/config.ru +3 -0
- data/example/environment.rb +11 -0
- data/example/models/connection.rb +9 -0
- data/example/models/note.rb +4 -0
- data/example/models/user.rb +6 -0
- data/example/public/style.css +78 -0
- data/example/schema.rb +27 -0
- data/example/views/authorize.erb +28 -0
- data/example/views/create_user.erb +3 -0
- data/example/views/home.erb +25 -0
- data/example/views/layout.erb +25 -0
- data/example/views/login.erb +20 -0
- data/example/views/new_client.erb +25 -0
- data/example/views/new_user.erb +22 -0
- data/example/views/show_client.erb +15 -0
- data/lib/oauth2/model.rb +17 -0
- data/lib/oauth2/model/authorization.rb +113 -0
- data/lib/oauth2/model/client.rb +55 -0
- data/lib/oauth2/model/client_owner.rb +13 -0
- data/lib/oauth2/model/hashing.rb +27 -0
- data/lib/oauth2/model/resource_owner.rb +26 -0
- data/lib/oauth2/model/schema.rb +42 -0
- data/lib/oauth2/provider.rb +117 -0
- data/lib/oauth2/provider/access_token.rb +66 -0
- data/lib/oauth2/provider/authorization.rb +168 -0
- data/lib/oauth2/provider/error.rb +29 -0
- data/lib/oauth2/provider/exchange.rb +212 -0
- data/lib/oauth2/router.rb +60 -0
- data/spec/factories.rb +27 -0
- data/spec/oauth2/model/authorization_spec.rb +216 -0
- data/spec/oauth2/model/client_spec.rb +55 -0
- data/spec/oauth2/model/resource_owner_spec.rb +55 -0
- data/spec/oauth2/provider/access_token_spec.rb +125 -0
- data/spec/oauth2/provider/authorization_spec.rb +323 -0
- data/spec/oauth2/provider/exchange_spec.rb +330 -0
- data/spec/oauth2/provider_spec.rb +531 -0
- data/spec/request_helpers.rb +46 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/test_app/helper.rb +33 -0
- data/spec/test_app/provider/application.rb +61 -0
- data/spec/test_app/provider/views/authorize.erb +19 -0
- metadata +220 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module OAuth2
|
2
|
+
class Provider
|
3
|
+
|
4
|
+
class Error
|
5
|
+
def initialize(message = nil)
|
6
|
+
@message = message
|
7
|
+
end
|
8
|
+
|
9
|
+
def redirect?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def response_body
|
14
|
+
message = 'Bad request' + (@message ? ": #{@message}" : '')
|
15
|
+
JSON.unparse(ERROR => INVALID_REQUEST, ERROR_DESCRIPTION => message)
|
16
|
+
end
|
17
|
+
|
18
|
+
def response_headers
|
19
|
+
Exchange::RESPONSE_HEADERS
|
20
|
+
end
|
21
|
+
|
22
|
+
def response_status
|
23
|
+
400
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,212 @@
|
|
1
|
+
module OAuth2
|
2
|
+
class Provider
|
3
|
+
|
4
|
+
class Exchange
|
5
|
+
attr_reader :client, :error, :error_description
|
6
|
+
|
7
|
+
REQUIRED_PARAMS = [CLIENT_ID, CLIENT_SECRET, GRANT_TYPE]
|
8
|
+
VALID_GRANT_TYPES = [AUTHORIZATION_CODE, PASSWORD, ASSERTION, REFRESH_TOKEN]
|
9
|
+
|
10
|
+
REQUIRED_PASSWORD_PARAMS = [USERNAME, PASSWORD]
|
11
|
+
REQUIRED_ASSERTION_PARAMS = [ASSERTION_TYPE, ASSERTION]
|
12
|
+
|
13
|
+
RESPONSE_HEADERS = {
|
14
|
+
'Cache-Control' => 'no-store',
|
15
|
+
'Content-Type' => 'application/json'
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(resource_owner, params)
|
19
|
+
@params = params
|
20
|
+
@scope = params[SCOPE]
|
21
|
+
@grant_type = @params[GRANT_TYPE]
|
22
|
+
validate!
|
23
|
+
end
|
24
|
+
|
25
|
+
def owner
|
26
|
+
@authorization && @authorization.owner
|
27
|
+
end
|
28
|
+
|
29
|
+
def scopes
|
30
|
+
@scope ? @scope.split(/\s+/).delete_if { |s| s.empty? } : []
|
31
|
+
end
|
32
|
+
|
33
|
+
def redirect?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def response_body
|
38
|
+
return jsonize(ERROR, ERROR_DESCRIPTION) unless valid?
|
39
|
+
update_authorization
|
40
|
+
|
41
|
+
response = {}
|
42
|
+
%w[access_token refresh_token scope].each do |key|
|
43
|
+
value = @authorization.__send__(key)
|
44
|
+
response[key] = value if value
|
45
|
+
end
|
46
|
+
|
47
|
+
JSON.unparse(response)
|
48
|
+
end
|
49
|
+
|
50
|
+
def response_headers
|
51
|
+
RESPONSE_HEADERS
|
52
|
+
end
|
53
|
+
|
54
|
+
def response_status
|
55
|
+
valid? ? 200 : 400
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_authorization
|
59
|
+
return if not valid? or @already_updated
|
60
|
+
@authorization.exchange!
|
61
|
+
@already_updated = true
|
62
|
+
end
|
63
|
+
|
64
|
+
def valid?
|
65
|
+
@error.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def jsonize(*ivars)
|
71
|
+
hash = {}
|
72
|
+
ivars.each { |key| hash[key] = instance_variable_get("@#{key}") }
|
73
|
+
JSON.unparse(hash)
|
74
|
+
end
|
75
|
+
|
76
|
+
def validate!
|
77
|
+
validate_required_params
|
78
|
+
|
79
|
+
return if @error
|
80
|
+
validate_client
|
81
|
+
|
82
|
+
unless VALID_GRANT_TYPES.include?(@grant_type)
|
83
|
+
@error = UNSUPPORTED_GRANT_TYPE
|
84
|
+
@error_description = "The grant type #{@grant_type} is not recognized"
|
85
|
+
end
|
86
|
+
return if @error
|
87
|
+
|
88
|
+
__send__("validate_#{@grant_type}")
|
89
|
+
validate_scope
|
90
|
+
end
|
91
|
+
|
92
|
+
def validate_required_params
|
93
|
+
REQUIRED_PARAMS.each do |param|
|
94
|
+
next if @params.has_key?(param)
|
95
|
+
@error = INVALID_REQUEST
|
96
|
+
@error_description = "Missing required parameter #{param}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def validate_client
|
101
|
+
@client = Model::Client.find_by_client_id(@params[CLIENT_ID])
|
102
|
+
unless @client
|
103
|
+
@error = INVALID_CLIENT
|
104
|
+
@error_description = "Unknown client ID #{@params[CLIENT_ID]}"
|
105
|
+
end
|
106
|
+
|
107
|
+
if @client and not @client.valid_client_secret? @params[CLIENT_SECRET]
|
108
|
+
@error = INVALID_CLIENT
|
109
|
+
@error_description = 'Parameter client_secret does not match'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def validate_scope
|
114
|
+
if @authorization and not @authorization.in_scope?(scopes)
|
115
|
+
@error = INVALID_SCOPE
|
116
|
+
@error_description = 'The request scope was never granted by the user'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def validate_authorization_code
|
121
|
+
unless @params[CODE]
|
122
|
+
@error = INVALID_REQUEST
|
123
|
+
@error_description = "Missing required parameter code"
|
124
|
+
end
|
125
|
+
|
126
|
+
if @client.redirect_uri and @client.redirect_uri != @params[REDIRECT_URI]
|
127
|
+
@error = REDIRECT_MISMATCH
|
128
|
+
@error_description = "Parameter redirect_uri does not match registered URI"
|
129
|
+
end
|
130
|
+
|
131
|
+
unless @params.has_key?(REDIRECT_URI)
|
132
|
+
@error = INVALID_REQUEST
|
133
|
+
@error_description = "Missing required parameter redirect_uri"
|
134
|
+
end
|
135
|
+
|
136
|
+
return if @error
|
137
|
+
|
138
|
+
@authorization = @client.authorizations.find_by_code(@params[CODE])
|
139
|
+
validate_authorization
|
140
|
+
end
|
141
|
+
|
142
|
+
def validate_password
|
143
|
+
REQUIRED_PASSWORD_PARAMS.each do |param|
|
144
|
+
next if @params.has_key?(param)
|
145
|
+
@error = INVALID_REQUEST
|
146
|
+
@error_description = "Missing required parameter #{param}"
|
147
|
+
end
|
148
|
+
|
149
|
+
return if @error
|
150
|
+
|
151
|
+
@authorization = Provider.handle_password(@client, @params[USERNAME], @params[PASSWORD])
|
152
|
+
return validate_authorization if @authorization
|
153
|
+
|
154
|
+
@error = INVALID_GRANT
|
155
|
+
@error_description = 'The access grant you supplied is invalid'
|
156
|
+
end
|
157
|
+
|
158
|
+
def validate_assertion
|
159
|
+
REQUIRED_ASSERTION_PARAMS.each do |param|
|
160
|
+
next if @params.has_key?(param)
|
161
|
+
@error = INVALID_REQUEST
|
162
|
+
@error_description = "Missing required parameter #{param}"
|
163
|
+
end
|
164
|
+
|
165
|
+
if @params[ASSERTION_TYPE]
|
166
|
+
uri = URI.parse(@params[ASSERTION_TYPE]) rescue nil
|
167
|
+
unless uri and uri.absolute?
|
168
|
+
@error = INVALID_REQUEST
|
169
|
+
@error_description = 'Parameter assertion_type must be an absolute URI'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
return if @error
|
174
|
+
|
175
|
+
assertion = Assertion.new(@params)
|
176
|
+
@authorization = Provider.handle_assertion(@client, assertion)
|
177
|
+
return validate_authorization if @authorization
|
178
|
+
|
179
|
+
@error = UNAUTHORIZED_CLIENT
|
180
|
+
@error_description = 'Client cannot use the given assertion type'
|
181
|
+
end
|
182
|
+
|
183
|
+
def validate_refresh_token
|
184
|
+
refresh_token_hash = OAuth2.hashify(@params[REFRESH_TOKEN])
|
185
|
+
@authorization = @client.authorizations.find_by_refresh_token_hash(refresh_token_hash)
|
186
|
+
validate_authorization
|
187
|
+
end
|
188
|
+
|
189
|
+
def validate_authorization
|
190
|
+
unless @authorization
|
191
|
+
@error = INVALID_GRANT
|
192
|
+
@error_description = 'The access grant you supplied is invalid'
|
193
|
+
end
|
194
|
+
|
195
|
+
if @authorization and @authorization.expired?
|
196
|
+
@error = INVALID_GRANT
|
197
|
+
@error_description = 'The access grant you supplied is invalid'
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class Assertion
|
203
|
+
attr_reader :type, :value
|
204
|
+
def initialize(params)
|
205
|
+
@type = params[ASSERTION_TYPE]
|
206
|
+
@value = params[ASSERTION]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module OAuth2
|
4
|
+
class Router
|
5
|
+
|
6
|
+
def self.auth_params(request, params = nil)
|
7
|
+
return {} unless basic = request.env['HTTP_AUTHORIZATION']
|
8
|
+
parts = basic.split(/\s+/)
|
9
|
+
username, password = Base64.decode64(parts.last).split(':')
|
10
|
+
{CLIENT_ID => username, CLIENT_SECRET => password}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.transport_error(request)
|
14
|
+
uri = URI.parse(request.url)
|
15
|
+
|
16
|
+
if Provider.enforce_ssl and not uri.is_a?(URI::HTTPS)
|
17
|
+
return Provider::Error.new("must make requests using HTTPS")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.parse(resource_owner, request, params = nil)
|
22
|
+
if error = transport_error(request)
|
23
|
+
return error
|
24
|
+
end
|
25
|
+
|
26
|
+
params ||= request.params
|
27
|
+
auth = auth_params(request, params)
|
28
|
+
|
29
|
+
if auth[CLIENT_ID] and auth[CLIENT_ID] != params[CLIENT_ID]
|
30
|
+
return Provider::Error.new("#{CLIENT_ID} from Basic Auth and request body do not match")
|
31
|
+
end
|
32
|
+
|
33
|
+
params = params.merge(auth)
|
34
|
+
|
35
|
+
if params[GRANT_TYPE]
|
36
|
+
request.post? ?
|
37
|
+
Provider::Exchange.new(resource_owner, params) :
|
38
|
+
Provider::Error.new("should be a POST request")
|
39
|
+
else
|
40
|
+
Provider::Authorization.new(resource_owner, params)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.access_token(resource_owner, scopes, request, params = nil)
|
45
|
+
params ||= request.params
|
46
|
+
header = request.env['HTTP_AUTHORIZATION']
|
47
|
+
|
48
|
+
access_token = header && header =~ /^OAuth\s+/ ?
|
49
|
+
header.gsub(/^OAuth\s+/, '') :
|
50
|
+
params[OAUTH_TOKEN]
|
51
|
+
|
52
|
+
Provider::AccessToken.new(resource_owner,
|
53
|
+
scopes,
|
54
|
+
access_token,
|
55
|
+
transport_error(request))
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
data/spec/factories.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
|
3
|
+
Factory.sequence :client_name do |n|
|
4
|
+
"Client ##{n}"
|
5
|
+
end
|
6
|
+
|
7
|
+
Factory.sequence :user_name do |n|
|
8
|
+
"User ##{n}"
|
9
|
+
end
|
10
|
+
|
11
|
+
Factory.define :owner, :class => TestApp::User do |u|
|
12
|
+
u.name { Factory.next :user_name }
|
13
|
+
end
|
14
|
+
|
15
|
+
Factory.define :client, :class => OAuth2::Model::Client do |c|
|
16
|
+
c.client_id { OAuth2.random_string }
|
17
|
+
c.client_secret { OAuth2.random_string }
|
18
|
+
c.name { Factory.next :client_name }
|
19
|
+
c.redirect_uri 'https://client.example.com/cb'
|
20
|
+
end
|
21
|
+
|
22
|
+
Factory.define :authorization, :class => OAuth2::Model::Authorization do |ac|
|
23
|
+
ac.client Factory(:client)
|
24
|
+
ac.code { OAuth2.random_string }
|
25
|
+
ac.expires_at nil
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,216 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe OAuth2::Model::Authorization do
|
4
|
+
let(:client) { Factory :client }
|
5
|
+
let(:impostor) { Factory :client }
|
6
|
+
let(:owner) { Factory :owner }
|
7
|
+
let(:user) { Factory :owner }
|
8
|
+
|
9
|
+
let(:authorization) do
|
10
|
+
OAuth2::Model::Authorization.new(:owner => owner, :client => client)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is vaid" do
|
14
|
+
authorization.should be_valid
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is not valid without a client" do
|
18
|
+
authorization.client = nil
|
19
|
+
authorization.should_not be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is not valid without an owner" do
|
23
|
+
authorization.owner = nil
|
24
|
+
authorization.should_not be_valid
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "when there are existing authorizations" do
|
28
|
+
before do
|
29
|
+
OAuth2::Model::Authorization.create(
|
30
|
+
:owner => user,
|
31
|
+
:client => impostor,
|
32
|
+
:access_token => 'existing_access_token')
|
33
|
+
|
34
|
+
OAuth2::Model::Authorization.create(
|
35
|
+
:owner => owner,
|
36
|
+
:client => client,
|
37
|
+
:code => 'existing_code')
|
38
|
+
|
39
|
+
OAuth2::Model::Authorization.create(
|
40
|
+
:owner => owner,
|
41
|
+
:client => client,
|
42
|
+
:refresh_token => 'existing_refresh_token')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "is valid if its access_token is unique" do
|
46
|
+
authorization.should be_valid
|
47
|
+
end
|
48
|
+
|
49
|
+
it "is valid if both access_tokens are nil" do
|
50
|
+
OAuth2::Model::Authorization.first.update_attribute(:access_token, nil)
|
51
|
+
authorization.access_token = nil
|
52
|
+
authorization.should be_valid
|
53
|
+
end
|
54
|
+
|
55
|
+
it "is not valid if its access_token is not unique" do
|
56
|
+
authorization.access_token = 'existing_access_token'
|
57
|
+
authorization.should_not be_valid
|
58
|
+
end
|
59
|
+
|
60
|
+
it "is valid if it has a unique code for its client" do
|
61
|
+
authorization.client = impostor
|
62
|
+
authorization.code = 'existing_code'
|
63
|
+
authorization.should be_valid
|
64
|
+
end
|
65
|
+
|
66
|
+
it "is not valid if it does not have a unique client and code" do
|
67
|
+
authorization.code = 'existing_code'
|
68
|
+
authorization.should_not be_valid
|
69
|
+
end
|
70
|
+
|
71
|
+
it "is valid if it has a unique refresh_token for its client" do
|
72
|
+
authorization.client = impostor
|
73
|
+
authorization.refresh_token = 'existing_refresh_token'
|
74
|
+
authorization.should be_valid
|
75
|
+
end
|
76
|
+
|
77
|
+
it "is not valid if it does not have a unique client and refresh_token" do
|
78
|
+
authorization.refresh_token = 'existing_refresh_token'
|
79
|
+
authorization.should_not be_valid
|
80
|
+
end
|
81
|
+
|
82
|
+
describe ".create_code" do
|
83
|
+
before { OAuth2.stub(:random_string).and_return('existing_code', 'new_code') }
|
84
|
+
|
85
|
+
it "returns the first code the client has not used" do
|
86
|
+
OAuth2::Model::Authorization.create_code(client).should == 'new_code'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns the first code another client has not used" do
|
90
|
+
OAuth2::Model::Authorization.create_code(impostor).should == 'existing_code'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe ".create_access_token" do
|
95
|
+
before { OAuth2.stub(:random_string).and_return('existing_access_token', 'new_access_token') }
|
96
|
+
|
97
|
+
it "returns the first unused token it can find" do
|
98
|
+
OAuth2::Model::Authorization.create_access_token.should == 'new_access_token'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe ".create_refresh_token" do
|
103
|
+
before { OAuth2.stub(:random_string).and_return('existing_refresh_token', 'new_refresh_token') }
|
104
|
+
|
105
|
+
it "returns the first refresh_token the client has not used" do
|
106
|
+
OAuth2::Model::Authorization.create_refresh_token(client).should == 'new_refresh_token'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns the first refresh_token another client has not used" do
|
110
|
+
OAuth2::Model::Authorization.create_refresh_token(impostor).should == 'existing_refresh_token'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#exchange!" do
|
116
|
+
it "saves the record" do
|
117
|
+
authorization.should_receive(:save!)
|
118
|
+
authorization.exchange!
|
119
|
+
end
|
120
|
+
|
121
|
+
it "uses its helpers to find unique tokens" do
|
122
|
+
OAuth2::Model::Authorization.should_receive(:create_access_token).and_return('access_token')
|
123
|
+
authorization.exchange!
|
124
|
+
authorization.access_token.should == 'access_token'
|
125
|
+
end
|
126
|
+
|
127
|
+
it "updates the tokens correctly" do
|
128
|
+
authorization.exchange!
|
129
|
+
authorization.should be_valid
|
130
|
+
authorization.code.should be_nil
|
131
|
+
authorization.refresh_token.should be_nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#expired?" do
|
136
|
+
it "returns false when not expiry is set" do
|
137
|
+
authorization.should_not be_expired
|
138
|
+
end
|
139
|
+
|
140
|
+
it "returns false when expiry is in the future" do
|
141
|
+
authorization.expires_at = 2.days.from_now
|
142
|
+
authorization.should_not be_expired
|
143
|
+
end
|
144
|
+
|
145
|
+
it "returns true when expiry is in the past" do
|
146
|
+
authorization.expires_at = 2.days.ago
|
147
|
+
authorization.should be_expired
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#grants_access?" do
|
152
|
+
it "returns true given the right user" do
|
153
|
+
authorization.grants_access?(owner).should be_true
|
154
|
+
end
|
155
|
+
|
156
|
+
it "returns false given the wrong user" do
|
157
|
+
authorization.grants_access?(user).should be_false
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "when the authorization is expired" do
|
161
|
+
before { authorization.expires_at = 2.days.ago }
|
162
|
+
|
163
|
+
it "returns false in all cases" do
|
164
|
+
authorization.grants_access?(owner).should be_false
|
165
|
+
authorization.grants_access?(user).should be_false
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "with a scope" do
|
171
|
+
before { authorization.scope = 'foo bar' }
|
172
|
+
|
173
|
+
describe "#in_scope?" do
|
174
|
+
it "returns true for authorized scopes" do
|
175
|
+
authorization.should be_in_scope('foo')
|
176
|
+
authorization.should be_in_scope('bar')
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns false for unauthorized scopes" do
|
180
|
+
authorization.should_not be_in_scope('qux')
|
181
|
+
authorization.should_not be_in_scope('fo')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "#grants_access?" do
|
186
|
+
it "returns true given the right user and all authorization scopes" do
|
187
|
+
authorization.grants_access?(owner, 'foo', 'bar').should be_true
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns true given the right user and some authorization scopes" do
|
191
|
+
authorization.grants_access?(owner, 'bar').should be_true
|
192
|
+
end
|
193
|
+
|
194
|
+
it "returns false given the right user and some unauthorization scopes" do
|
195
|
+
authorization.grants_access?(owner, 'foo', 'bar', 'qux').should be_false
|
196
|
+
end
|
197
|
+
|
198
|
+
it "returns false given an unauthorized scope" do
|
199
|
+
authorization.grants_access?(owner, 'qux').should be_false
|
200
|
+
end
|
201
|
+
|
202
|
+
it "returns true given the right user" do
|
203
|
+
authorization.grants_access?(owner).should be_true
|
204
|
+
end
|
205
|
+
|
206
|
+
it "returns false given the wrong user" do
|
207
|
+
authorization.grants_access?(user).should be_false
|
208
|
+
end
|
209
|
+
|
210
|
+
it "returns false given the wrong user and an authorized scope" do
|
211
|
+
authorization.grants_access?(user, 'foo').should be_false
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|