rack-oauth2-server 2.0.0.beta3 → 2.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +25 -7
- data/README.rdoc +18 -7
- data/VERSION +1 -1
- data/bin/oauth2-server +6 -6
- data/lib/rack/oauth2/admin/css/screen.css +8 -2
- data/lib/rack/oauth2/admin/js/application.js +44 -37
- data/lib/rack/oauth2/admin/js/sammy.oauth2.js +10 -3
- data/lib/rack/oauth2/admin/views/client.tmpl +3 -2
- data/lib/rack/oauth2/admin/views/edit.tmpl +13 -9
- data/lib/rack/oauth2/models/access_grant.rb +6 -4
- data/lib/rack/oauth2/models/access_token.rb +12 -14
- data/lib/rack/oauth2/models/auth_request.rb +10 -7
- data/lib/rack/oauth2/models/client.rb +11 -7
- data/lib/rack/oauth2/rails.rb +2 -2
- data/lib/rack/oauth2/server/admin.rb +8 -6
- data/lib/rack/oauth2/server/helper.rb +2 -2
- data/lib/rack/oauth2/server/practice.rb +1 -1
- data/lib/rack/oauth2/server/utils.rb +4 -4
- data/lib/rack/oauth2/server.rb +53 -26
- data/lib/rack/oauth2/sinatra.rb +2 -2
- data/test/admin/api_test.rb +13 -11
- data/test/oauth/access_grant_test.rb +27 -3
- data/test/oauth/access_token_test.rb +2 -25
- data/test/oauth/server_test.rb +64 -21
- data/test/rails2/log/test.log +10567 -0
- data/test/rails3/log/test.log +15977 -0
- data/test/setup.rb +2 -2
- metadata +5 -5
@@ -71,8 +71,8 @@ module Rack
|
|
71
71
|
# Forces all requests to use HTTPS (true by default except in
|
72
72
|
# development mode).
|
73
73
|
set :force_ssl, !development?
|
74
|
-
# Common
|
75
|
-
set :
|
74
|
+
# Common scope shown and added by default to new clients.
|
75
|
+
set :scope, []
|
76
76
|
|
77
77
|
|
78
78
|
set :logger, defined?(::Rails) && ::Rails.logger
|
@@ -129,7 +129,7 @@ module Rack
|
|
129
129
|
get "/api/clients" do
|
130
130
|
content_type "application/json"
|
131
131
|
json = { :list=>Server::Client.all.map { |client| client_as_json(client) },
|
132
|
-
:
|
132
|
+
:scope=>Server::Utils.normalize_scope(settings.scope),
|
133
133
|
:history=>"#{request.script_name}/api/clients/history",
|
134
134
|
:tokens=>{ :total=>Server::AccessToken.count, :week=>Server::AccessToken.count(:days=>7),
|
135
135
|
:revoked=>Server::AccessToken.count(:days=>7, :revoked=>true) } }
|
@@ -220,13 +220,15 @@ module Rack
|
|
220
220
|
halt 400, "Image URL must be an absolute URL with HTTP/S scheme" unless
|
221
221
|
image_url.absolute? && %{http https}.include?(image_url.scheme)
|
222
222
|
end
|
223
|
-
|
224
|
-
{ :display_name=>display_name, :link=>link.to_s, :image_url=>image_url.to_s,
|
223
|
+
scope = Server::Utils.normalize_scope(params[:scope])
|
224
|
+
{ :display_name=>display_name, :link=>link.to_s, :image_url=>image_url.to_s,
|
225
|
+
:redirect_uri=>redirect_uri.to_s, :scope=>scope, :notes=>params[:notes] }
|
225
226
|
end
|
226
227
|
|
227
228
|
def client_as_json(client, with_stats = false)
|
228
229
|
{ "id"=>client.id.to_s, "secret"=>client.secret, :redirectUri=>client.redirect_uri,
|
229
|
-
:displayName=>client.display_name, :link=>client.link, :imageUrl=>client.image_url,
|
230
|
+
:displayName=>client.display_name, :link=>client.link, :imageUrl=>client.image_url,
|
231
|
+
:notes=>client.notes, :scope=>client.scope,
|
230
232
|
:url=>"#{request.script_name}/api/client/#{client.id}",
|
231
233
|
:revoke=>"#{request.script_name}/api/client/#{client.id}/revoke",
|
232
234
|
:history=>"#{request.script_name}/api/client/#{client.id}/history",
|
@@ -54,9 +54,9 @@ module Rack
|
|
54
54
|
# @return [Array<String>, nil] Scope names, e.g ["read, "write"]
|
55
55
|
def scope
|
56
56
|
if access_token
|
57
|
-
@scope ||= Server
|
57
|
+
@scope ||= Server.get_access_token(access_token).scope
|
58
58
|
elsif authorization
|
59
|
-
@scope ||= Server
|
59
|
+
@scope ||= Server.get_auth_request(authorization).scope
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -21,7 +21,7 @@ module Rack
|
|
21
21
|
<dt>Resource requiring authorization and scope "sudo":</dt>
|
22
22
|
<dd>http://#{request.host}:#{request.port}/make</dd>
|
23
23
|
</dl>
|
24
|
-
<p>The
|
24
|
+
<p>The scope can be "nobody", "sudo", "oauth-admin" or combination of the three.</p>
|
25
25
|
<p>You can manage client applications and tokens from the <a href="/oauth/admin">OAuth console</a>.</p>
|
26
26
|
HTML
|
27
27
|
end
|
@@ -17,10 +17,10 @@ module Rack
|
|
17
17
|
raise InvalidRequestError, "Redirect URL looks fishy to me"
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
21
|
-
#
|
22
|
-
def
|
23
|
-
(Array ===
|
20
|
+
# Given scope as either array or string, return array of same names,
|
21
|
+
# unique and sorted.
|
22
|
+
def normalize_scope(scope)
|
23
|
+
(Array === scope ? scope.join(" ") : scope || "").split(/\s+/).compact.uniq.sort
|
24
24
|
end
|
25
25
|
|
26
26
|
end
|
data/lib/rack/oauth2/server.rb
CHANGED
@@ -35,8 +35,7 @@ module Rack
|
|
35
35
|
# Registers and returns a new Client. Can also be used to update
|
36
36
|
# existing client registration, by passing identifier (and secret) of
|
37
37
|
# existing client record. That way, your setup script can create a new
|
38
|
-
# client application and run repeatedly without fail.
|
39
|
-
# adding new scopes to your existing client application.
|
38
|
+
# client application and run repeatedly without fail.
|
40
39
|
#
|
41
40
|
# @param [Hash] args Arguments for registering client application
|
42
41
|
# @option args [String] :id Client identifier. Use this to update
|
@@ -50,17 +49,19 @@ module Rack
|
|
50
49
|
# name.
|
51
50
|
# @option args [String] redirect_uri Redirect URL: authorization
|
52
51
|
# requests for this client will always redirect back to this URL.
|
53
|
-
# @option args [Array]
|
52
|
+
# @option args [Array] scope Scope that client application can request
|
53
|
+
# (list of names).
|
54
|
+
# @option args [Array] notes Free form text, for internal use.
|
54
55
|
#
|
55
56
|
# @example Registering new client application
|
56
57
|
# Server.register :display_name=>"My Application",
|
57
|
-
# :link=>"http://example.com", :
|
58
|
+
# :link=>"http://example.com", :scope=>%w{read write},
|
58
59
|
# :redirect_uri=>"http://example.com/oauth/callback"
|
59
60
|
# @example Migration using configuration file
|
60
61
|
# config = YAML.load_file(Rails.root + "config/oauth.yml")
|
61
62
|
# Server.register config["id"], config["secret"],
|
62
63
|
# :display_name=>"My Application", :link=>"http://example.com",
|
63
|
-
# :
|
64
|
+
# :scope=>config["scope"],
|
64
65
|
# :redirect_uri=>"http://example.com/oauth/callback"
|
65
66
|
def register(args)
|
66
67
|
if args[:id] && args[:secret] && (client = get_client(args[:id]))
|
@@ -71,6 +72,19 @@ module Rack
|
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
75
|
+
# Creates and returns a new access grant. Actually, returns only the
|
76
|
+
# authorization code which you can turn into an access token by
|
77
|
+
# making a request to /oauth/access_token.
|
78
|
+
#
|
79
|
+
# @param [String] identity User ID, account ID, etc
|
80
|
+
# @param [String] client_id Client identifier
|
81
|
+
# @param [Array, nil] scope Array of string, nil if you want 'em all
|
82
|
+
# @return [String] Access grant authorization code
|
83
|
+
def access_grant(identity, client_id, scope = nil)
|
84
|
+
client = get_client(client_id) or fail "No such client"
|
85
|
+
AccessGrant.create(identity, client, scope || client.scope).code
|
86
|
+
end
|
87
|
+
|
74
88
|
# Returns AccessToken from token.
|
75
89
|
#
|
76
90
|
# @param [String] token Access token (e.g. from oauth.access_token)
|
@@ -80,15 +94,16 @@ module Rack
|
|
80
94
|
end
|
81
95
|
|
82
96
|
# Returns AccessToken for the specified identity, client application and
|
83
|
-
#
|
97
|
+
# scope. You can use this method to request existing access token, new
|
84
98
|
# token generated if one does not already exists.
|
85
99
|
#
|
86
100
|
# @param [String] identity Identity, e.g. user ID, account ID
|
87
101
|
# @param [String] client_id Client application identifier
|
88
|
-
# @param [
|
89
|
-
# @return [
|
90
|
-
def
|
91
|
-
|
102
|
+
# @param [Array, nil] scope Array of names, nil if you want 'em all
|
103
|
+
# @return [String] Access token
|
104
|
+
def token_for(identity, client_id, scope = nil)
|
105
|
+
client = get_client(client_id) or fail "No such client"
|
106
|
+
AccessToken.get_token_for(identity, client, scope || client.scope).token
|
92
107
|
end
|
93
108
|
|
94
109
|
# Returns all AccessTokens for an identity.
|
@@ -121,6 +136,15 @@ module Rack
|
|
121
136
|
# Defaults to use the request host name.
|
122
137
|
# - :logger -- The logger to use. Under Rails, defaults to use the Rails
|
123
138
|
# logger. Will use Rack::Logger if available.
|
139
|
+
#
|
140
|
+
# Authenticator is a block that receives either two or four parameters.
|
141
|
+
# The first two are username and password. The other two are the client
|
142
|
+
# identifier and scope. It authenticated, it returns an identity,
|
143
|
+
# otherwise it can return nil or false. For example:
|
144
|
+
# oauth.authenticator = lambda do |username, password|
|
145
|
+
# user = User.find_by_username(username)
|
146
|
+
# user if user && user.authenticated?(password)
|
147
|
+
# end
|
124
148
|
Options = Struct.new(:access_token_path, :authenticator, :authorization_types,
|
125
149
|
:authorize_path, :database, :host, :param_authentication, :path, :realm, :logger)
|
126
150
|
|
@@ -184,8 +208,8 @@ module Rack
|
|
184
208
|
# and return appropriate WWW-Authenticate header.
|
185
209
|
response = @app.call(env)
|
186
210
|
if response[0] == 403
|
187
|
-
|
188
|
-
challenge = 'OAuth realm="%s", error="insufficient_scope", scope="%s"' % [(options.realm || request.host),
|
211
|
+
scope = Utils.normalize_scope(response[1]["oauth.no_scope"])
|
212
|
+
challenge = 'OAuth realm="%s", error="insufficient_scope", scope="%s"' % [(options.realm || request.host), scope.join(" ")]
|
189
213
|
response[1]["WWW-Authenticate"] = challenge
|
190
214
|
return response
|
191
215
|
else
|
@@ -228,7 +252,7 @@ module Rack
|
|
228
252
|
response_type = auth_request.response_type # Needed for error handling
|
229
253
|
client = self.class.get_client(auth_request.client_id)
|
230
254
|
# Pass back to application, watch for 403 (deny!)
|
231
|
-
logger.info "Request #{auth_request.id}: Client #{client.display_name} requested #{auth_request.response_type} with scope #{auth_request.scope}" if logger
|
255
|
+
logger.info "Request #{auth_request.id}: Client #{client.display_name} requested #{auth_request.response_type} with scope #{auth_request.scope.join(" ")}" if logger
|
232
256
|
request.env["oauth.authorization"] = auth_request.id.to_s
|
233
257
|
response = @app.call(request.env)
|
234
258
|
raise AccessDeniedError if response[0] == 403
|
@@ -249,15 +273,15 @@ module Rack
|
|
249
273
|
client = get_client(request)
|
250
274
|
raise RedirectUriMismatchError unless client.redirect_uri.nil? || client.redirect_uri == redirect_uri.to_s
|
251
275
|
raise UnsupportedResponseTypeError unless options.authorization_types.include?(response_type)
|
252
|
-
requested_scope = Utils.
|
253
|
-
|
254
|
-
raise InvalidScopeError unless (requested_scope -
|
276
|
+
requested_scope = Utils.normalize_scope(request.GET["scope"])
|
277
|
+
allowed_scope = client.scope
|
278
|
+
raise InvalidScopeError unless (requested_scope - allowed_scope).empty?
|
255
279
|
# Create object to track authorization request and let application
|
256
280
|
# handle the rest.
|
257
|
-
auth_request = AuthRequest.create(client
|
281
|
+
auth_request = AuthRequest.create(client, requested_scope, redirect_uri.to_s, response_type, state)
|
258
282
|
uri = URI.parse(request.url)
|
259
283
|
uri.query = "authorization=#{auth_request.id.to_s}"
|
260
|
-
return [303, { "Location"=>uri.to_s }, []]
|
284
|
+
return [303, { "Location"=>uri.to_s }, ["You are being redirected"]]
|
261
285
|
end
|
262
286
|
rescue OAuthError=>error
|
263
287
|
logger.error "Authorization request error: #{error.code} #{error.message}" if logger
|
@@ -326,13 +350,16 @@ module Rack
|
|
326
350
|
# 4.1.2. Resource Owner Password Credentials
|
327
351
|
username, password = request.POST.values_at("username", "password")
|
328
352
|
raise InvalidGrantError unless username && password
|
329
|
-
|
353
|
+
requested_scope = Utils.normalize_scope(request.POST["scope"])
|
354
|
+
allowed_scope = client.scope
|
355
|
+
raise InvalidScopeError unless (requested_scope - allowed_scope).empty?
|
356
|
+
args = [username, password]
|
357
|
+
args << client.id << requested_scope unless options.authenticator.arity == 2
|
358
|
+
identity = options.authenticator.call(*args)
|
330
359
|
raise InvalidGrantError unless identity
|
331
|
-
|
332
|
-
|
333
|
-
raise
|
334
|
-
access_token = AccessToken.get_token_for(identity, client.id, requested_scope)
|
335
|
-
else raise UnsupportedGrantType
|
360
|
+
access_token = AccessToken.get_token_for(identity, client, requested_scope)
|
361
|
+
else
|
362
|
+
raise UnsupportedGrantType
|
336
363
|
end
|
337
364
|
logger.info "Access token #{access_token.token} granted to client #{client.display_name}, identity #{access_token.identity}" if logger
|
338
365
|
response = { :access_token=>access_token.token }
|
@@ -368,7 +395,7 @@ module Rack
|
|
368
395
|
|
369
396
|
# Rack redirect response. The argument is typically a URI object.
|
370
397
|
def redirect_to(uri)
|
371
|
-
return [302, { "Location"=>uri.to_s }, []]
|
398
|
+
return [302, { "Location"=>uri.to_s }, ["You are being redirected"]]
|
372
399
|
end
|
373
400
|
|
374
401
|
def bad_request(message)
|
@@ -379,7 +406,7 @@ module Rack
|
|
379
406
|
def unauthorized(request, error = nil)
|
380
407
|
challenge = 'OAuth realm="%s"' % (options.realm || request.host)
|
381
408
|
challenge << ', error="%s", error_description="%s"' % [error.code, error.message] if error
|
382
|
-
return [401, { "WWW-Authenticate"=>challenge }, []]
|
409
|
+
return [401, { "WWW-Authenticate"=>challenge }, [error && error.message || ""]]
|
383
410
|
end
|
384
411
|
|
385
412
|
# Wraps Rack::Request to expose Basic and OAuth authentication
|
data/lib/rack/oauth2/sinatra.rb
CHANGED
@@ -13,13 +13,13 @@ module Rack
|
|
13
13
|
# access scope.
|
14
14
|
#
|
15
15
|
# Adds oauth setting you can use to configure the module (e.g. setting
|
16
|
-
# available
|
16
|
+
# available scope, see example).
|
17
17
|
#
|
18
18
|
# @example
|
19
19
|
# require "rack/oauth2/sinatra"
|
20
20
|
# class MyApp < Sinatra::Base
|
21
21
|
# register Rack::OAuth2::Sinatra
|
22
|
-
# oauth[:
|
22
|
+
# oauth[:scope] = %w{read write}
|
23
23
|
#
|
24
24
|
# oauth_required "/api"
|
25
25
|
# oauth_required "/api/edit", :scope=>"write"
|
data/test/admin/api_test.rb
CHANGED
@@ -18,13 +18,13 @@ class AdminApiTest < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
|
20
20
|
def without_scope
|
21
|
-
token = Server.
|
22
|
-
header "Authorization", "OAuth #{token
|
21
|
+
token = Server.token_for("Superman", client.id, "nobody")
|
22
|
+
header "Authorization", "OAuth #{token}"
|
23
23
|
end
|
24
24
|
|
25
25
|
def with_scope
|
26
|
-
token = Server.
|
27
|
-
header "Authorization", "OAuth #{token
|
26
|
+
token = Server.token_for("Superman", client.id, "oauth-admin")
|
27
|
+
header "Authorization", "OAuth #{token}"
|
28
28
|
end
|
29
29
|
|
30
30
|
def json
|
@@ -84,8 +84,8 @@ class AdminApiTest < Test::Unit::TestCase
|
|
84
84
|
should "return list of clients" do
|
85
85
|
assert Array === json["list"]
|
86
86
|
end
|
87
|
-
should "return
|
88
|
-
assert_equal %w{read write}, json["
|
87
|
+
should "return known scope" do
|
88
|
+
assert_equal %w{read write}, json["scope"]
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -123,8 +123,8 @@ class AdminApiTest < Test::Unit::TestCase
|
|
123
123
|
should "provide link to revoke resource"do
|
124
124
|
assert_equal ["/oauth/admin/api/client", client.id, "revoke"].join("/"), @first["revoke"]
|
125
125
|
end
|
126
|
-
should "provide
|
127
|
-
assert_equal %w{read write}, @first["
|
126
|
+
should "provide scope for client" do
|
127
|
+
assert_equal %w{oauth-admin read write}, @first["scope"]
|
128
128
|
end
|
129
129
|
should "tell if not revoked" do
|
130
130
|
assert @first["revoked"].nil?
|
@@ -149,12 +149,14 @@ class AdminApiTest < Test::Unit::TestCase
|
|
149
149
|
tokens = []
|
150
150
|
1.upto(10).map do |days|
|
151
151
|
Timecop.travel -days*86400 do
|
152
|
-
tokens << Server.
|
152
|
+
tokens << Server.token_for("Superman#{days}", client.id)
|
153
153
|
end
|
154
154
|
end
|
155
155
|
# Revoke one token today (within past 7 days), one 10 days ago (beyond)
|
156
|
-
|
157
|
-
|
156
|
+
Timecop.travel -7 * 86400 do
|
157
|
+
Server.get_access_token(tokens[0]).revoke!
|
158
|
+
end
|
159
|
+
Server.get_access_token(tokens[1]).revoke!
|
158
160
|
with_scope ; get "/oauth/admin/api/clients"
|
159
161
|
end
|
160
162
|
|
@@ -148,7 +148,7 @@ class AccessGrantTest < Test::Unit::TestCase
|
|
148
148
|
|
149
149
|
context "authorization code for different client" do
|
150
150
|
setup do
|
151
|
-
grant =
|
151
|
+
grant = Server::AccessGrant.create("foo bar", Server.register(:scope=>%w{read write}), "read write", nil)
|
152
152
|
request_access_token :code=>grant.code
|
153
153
|
end
|
154
154
|
should_return_error :invalid_grant
|
@@ -156,7 +156,7 @@ class AccessGrantTest < Test::Unit::TestCase
|
|
156
156
|
|
157
157
|
context "authorization code revoked" do
|
158
158
|
setup do
|
159
|
-
|
159
|
+
Server::AccessGrant.from_code(@code).revoke!
|
160
160
|
request_access_token
|
161
161
|
end
|
162
162
|
should_return_error :invalid_grant
|
@@ -169,7 +169,8 @@ class AccessGrantTest < Test::Unit::TestCase
|
|
169
169
|
|
170
170
|
context "no redirect URI to match" do
|
171
171
|
setup do
|
172
|
-
|
172
|
+
@client = Server.register(:display_name=>"No rediret", :scope=>"read write")
|
173
|
+
grant = Server::AccessGrant.create("foo bar", client, "read write", nil)
|
173
174
|
request_access_token :code=>grant.code, :redirect_uri=>"http://uberclient.dot/oz"
|
174
175
|
end
|
175
176
|
should_respond_with_access_token
|
@@ -203,6 +204,29 @@ class AccessGrantTest < Test::Unit::TestCase
|
|
203
204
|
should_return_error :invalid_scope
|
204
205
|
end
|
205
206
|
|
207
|
+
context "authenticator with 4 parameters" do
|
208
|
+
setup do
|
209
|
+
@old = config.authenticator
|
210
|
+
config.authenticator = lambda do |username, password, client_id, scope|
|
211
|
+
@client_id = client_id
|
212
|
+
@scope = scope
|
213
|
+
"Batman"
|
214
|
+
end
|
215
|
+
request_with_username_password "cowbell", "more", "read"
|
216
|
+
end
|
217
|
+
|
218
|
+
should_respond_with_access_token "read"
|
219
|
+
should "receive client identifier" do
|
220
|
+
assert_equal client.id, @client_id
|
221
|
+
end
|
222
|
+
should "receive scope" do
|
223
|
+
assert_equal %w{read}, @scope
|
224
|
+
end
|
225
|
+
|
226
|
+
teardown { config.authenticator = @old }
|
227
|
+
end
|
228
|
+
|
229
|
+
|
206
230
|
# 4.2. Access Token Response
|
207
231
|
|
208
232
|
context "using authorization code" do
|
@@ -103,7 +103,7 @@ class AccessTokenTest < Test::Unit::TestCase
|
|
103
103
|
|
104
104
|
context "revoked HTTP token" do
|
105
105
|
setup do
|
106
|
-
|
106
|
+
Server::AccessToken.from_token(@token).revoke!
|
107
107
|
with_token
|
108
108
|
get "/private"
|
109
109
|
end
|
@@ -257,7 +257,7 @@ class AccessTokenTest < Test::Unit::TestCase
|
|
257
257
|
|
258
258
|
context "list tokens" do
|
259
259
|
setup do
|
260
|
-
@other =
|
260
|
+
@other = Server.token_for("foobar", client.id, "read")
|
261
261
|
get "/list_tokens"
|
262
262
|
end
|
263
263
|
|
@@ -271,29 +271,6 @@ class AccessTokenTest < Test::Unit::TestCase
|
|
271
271
|
end
|
272
272
|
|
273
273
|
|
274
|
-
context "get_token_for" do
|
275
|
-
should "return two different tokens for two different clients" do
|
276
|
-
myapp = Rack::OAuth2::Server.get_token_for("Batman", "4cca30423321e895cb000001", "read write")
|
277
|
-
yourapp = Rack::OAuth2::Server.get_token_for("Batman", "4fff30423321e895cb000001", "read write")
|
278
|
-
assert myapp.token != yourapp.token
|
279
|
-
end
|
280
|
-
should "return two different tokens for two different identities" do
|
281
|
-
me = Rack::OAuth2::Server.get_token_for("Batman", "4cca30423321e895cb000001", "read write")
|
282
|
-
you = Rack::OAuth2::Server.get_token_for("Robin", "4cca30423321e895cb000001", "read write")
|
283
|
-
assert me.token != you.token
|
284
|
-
end
|
285
|
-
should "return two different tokens for two different scope" do
|
286
|
-
write = Rack::OAuth2::Server.get_token_for("Batman", "4cca30423321e895cb000001", "read write")
|
287
|
-
math = Rack::OAuth2::Server.get_token_for("Batman", "4cca30423321e895cb000001", "read math")
|
288
|
-
assert write.token != math.token
|
289
|
-
end
|
290
|
-
should "return same tokens regardless of order of scope" do
|
291
|
-
one = Rack::OAuth2::Server.get_token_for("Batman", "4cca30423321e895cb000001", "read write math")
|
292
|
-
two = Rack::OAuth2::Server.get_token_for("Batman", "4cca30423321e895cb000001", "math write read")
|
293
|
-
assert_equal one.token, two.token
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
274
|
context "with specific host" do
|
298
275
|
context "right host" do
|
299
276
|
setup do
|
data/test/oauth/server_test.rb
CHANGED
@@ -8,7 +8,7 @@ class ServerTest < Test::Unit::TestCase
|
|
8
8
|
end
|
9
9
|
|
10
10
|
context "get_auth_request" do
|
11
|
-
setup { @request = Server::AuthRequest.create(client
|
11
|
+
setup { @request = Server::AuthRequest.create(client, client.scope.join(" "), client.redirect_uri, "token", nil) }
|
12
12
|
should "return authorization request" do
|
13
13
|
assert_equal @request.id, Server.get_auth_request(@request.id).id
|
14
14
|
end
|
@@ -34,7 +34,7 @@ class ServerTest < Test::Unit::TestCase
|
|
34
34
|
context "no client ID" do
|
35
35
|
setup do
|
36
36
|
@client = Server.register(:display_name=>"MyApp", :link=>"http://example.org", :image_url=>"http://example.org/favicon.ico",
|
37
|
-
:redirect_uri=>"http://example.org/oauth/callback", :
|
37
|
+
:redirect_uri=>"http://example.org/oauth/callback", :scope=>%w{read write})
|
38
38
|
end
|
39
39
|
|
40
40
|
should "create new client" do
|
@@ -58,8 +58,8 @@ class ServerTest < Test::Unit::TestCase
|
|
58
58
|
assert_equal "http://example.org/oauth/callback", Server.get_client(@client.id).redirect_uri
|
59
59
|
end
|
60
60
|
|
61
|
-
should "set
|
62
|
-
assert_equal %w{read write}, Server.get_client(@client.id).
|
61
|
+
should "set scope" do
|
62
|
+
assert_equal %w{read write}, Server.get_client(@client.id).scope
|
63
63
|
end
|
64
64
|
|
65
65
|
should "assign client an ID" do
|
@@ -134,8 +134,43 @@ class ServerTest < Test::Unit::TestCase
|
|
134
134
|
end
|
135
135
|
|
136
136
|
|
137
|
+
context "access_grant" do
|
138
|
+
setup do
|
139
|
+
code = Server.access_grant("Batman", client.id, %w{read})
|
140
|
+
basic_authorize client.id, client.secret
|
141
|
+
post "/oauth/access_token", :scope=>"read", :grant_type=>"authorization_code", :code=>code, :redirect_uri=>client.redirect_uri
|
142
|
+
@token = JSON.parse(last_response.body)["access_token"]
|
143
|
+
end
|
144
|
+
|
145
|
+
should "resolve into an access token" do
|
146
|
+
assert Server.get_access_token(@token)
|
147
|
+
end
|
148
|
+
|
149
|
+
should "resolve into access token with grant identity" do
|
150
|
+
assert_equal "Batman", Server.get_access_token(@token).identity
|
151
|
+
end
|
152
|
+
|
153
|
+
should "resolve into access token with grant scope" do
|
154
|
+
assert_equal %w{read}, Server.get_access_token(@token).scope
|
155
|
+
end
|
156
|
+
|
157
|
+
should "resolve into access token with grant client" do
|
158
|
+
assert_equal client.id, Server.get_access_token(@token).client_id
|
159
|
+
end
|
160
|
+
|
161
|
+
context "with no scope" do
|
162
|
+
setup { @code = Server.access_grant("Batman", client.id) }
|
163
|
+
|
164
|
+
should "pick client scope" do
|
165
|
+
assert_equal %w{oauth-admin read write}, Server::AccessGrant.from_code(@code).scope
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
|
137
172
|
context "get_access_token" do
|
138
|
-
setup { @token = Server.
|
173
|
+
setup { @token = Server.token_for("Batman", client.id, %w{read}) }
|
139
174
|
should "return authorization request" do
|
140
175
|
assert_equal @token, Server.get_access_token(@token).token
|
141
176
|
end
|
@@ -143,61 +178,69 @@ class ServerTest < Test::Unit::TestCase
|
|
143
178
|
should "return nil if no client found" do
|
144
179
|
assert !Server.get_access_token("4ce2488e3321e87ac1000004")
|
145
180
|
end
|
181
|
+
|
182
|
+
context "with no scope" do
|
183
|
+
setup { @token = Server.token_for("Batman", client.id) }
|
184
|
+
|
185
|
+
should "pick client scope" do
|
186
|
+
assert_equal %w{oauth-admin read write}, Server::AccessToken.from_token(@token).scope
|
187
|
+
end
|
188
|
+
end
|
146
189
|
end
|
147
190
|
|
148
191
|
|
149
|
-
context "
|
150
|
-
setup { @token = Server.
|
192
|
+
context "token_for" do
|
193
|
+
setup { @token = Server.token_for("Batman", client.id, %w{read write}) }
|
151
194
|
|
152
195
|
should "return access token" do
|
153
|
-
|
196
|
+
assert_match /[0-9a-f]{32}/, @token
|
154
197
|
end
|
155
198
|
|
156
199
|
should "associate token with client" do
|
157
|
-
assert_equal client.id, @token.client_id
|
200
|
+
assert_equal client.id, Server.get_access_token(@token).client_id
|
158
201
|
end
|
159
202
|
|
160
203
|
should "associate token with identity" do
|
161
|
-
assert_equal "Batman", @token.identity
|
204
|
+
assert_equal "Batman", Server.get_access_token(@token).identity
|
162
205
|
end
|
163
206
|
|
164
207
|
should "associate token with scope" do
|
165
|
-
assert_equal %w{read write}, @token.scope
|
208
|
+
assert_equal %w{read write}, Server.get_access_token(@token).scope
|
166
209
|
end
|
167
210
|
|
168
211
|
should "return same token for same parameters" do
|
169
|
-
assert_equal @token
|
212
|
+
assert_equal @token, Server.token_for("Batman", client.id, %w{write read})
|
170
213
|
end
|
171
214
|
|
172
215
|
should "return different token for different identity" do
|
173
|
-
assert @token
|
216
|
+
assert @token != Server.token_for("Superman", client.id, %w{read write})
|
174
217
|
end
|
175
218
|
|
176
219
|
should "return different token for different client" do
|
177
220
|
client = Server.register(:display_name=>"MyApp")
|
178
|
-
assert @token
|
221
|
+
assert @token != Server.token_for("Batman", client.id, %w{read write})
|
179
222
|
end
|
180
223
|
|
181
224
|
should "return different token for different scope" do
|
182
|
-
assert @token
|
225
|
+
assert @token != Server.token_for("Batman", client.id, %w{read})
|
183
226
|
end
|
184
227
|
end
|
185
228
|
|
186
229
|
|
187
230
|
context "list access tokens" do
|
188
231
|
setup do
|
189
|
-
@one = Server.
|
190
|
-
@two = Server.
|
191
|
-
@three = Server.
|
232
|
+
@one = Server.token_for("Batman", client.id, %w{read})
|
233
|
+
@two = Server.token_for("Superman", client.id, %w{read})
|
234
|
+
@three = Server.token_for("Batman", client.id, %w{write})
|
192
235
|
end
|
193
236
|
|
194
237
|
should "return all tokens for identity" do
|
195
|
-
assert_contains Server.list_access_tokens("Batman").map(&:token), @one
|
196
|
-
assert_contains Server.list_access_tokens("Batman").map(&:token), @three
|
238
|
+
assert_contains Server.list_access_tokens("Batman").map(&:token), @one
|
239
|
+
assert_contains Server.list_access_tokens("Batman").map(&:token), @three
|
197
240
|
end
|
198
241
|
|
199
242
|
should "not return tokens for other identities" do
|
200
|
-
assert !Server.list_access_tokens("Batman").map(&:token).include?(@two
|
243
|
+
assert !Server.list_access_tokens("Batman").map(&:token).include?(@two)
|
201
244
|
end
|
202
245
|
|
203
246
|
end
|