rack-oauth2-server 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +27 -1
- data/README.rdoc +25 -19
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/bin/oauth2-server +7 -7
- data/lib/rack/oauth2/admin/css/screen.css +11 -1
- data/lib/rack/oauth2/admin/js/application.js +21 -10
- data/lib/rack/oauth2/admin/views/client.tmpl +1 -1
- data/lib/rack/oauth2/admin/views/no_access.tmpl +4 -0
- data/lib/rack/oauth2/server.rb +55 -41
- data/lib/rack/oauth2/server/admin.rb +6 -2
- data/lib/rack/oauth2/server/errors.rb +18 -11
- data/lib/rack/oauth2/server/helper.rb +15 -10
- data/rack-oauth2-server.gemspec +1 -0
- data/test/admin/api_test.rb +0 -4
- data/test/admin/ui_test.rb +13 -0
- data/test/oauth/access_grant_test.rb +2 -1
- data/test/oauth/access_token_test.rb +12 -11
- data/test/oauth/authorization_test.rb +19 -9
- data/test/rails/app/controllers/api_controller.rb +1 -1
- data/test/rails/app/controllers/oauth_controller.rb +6 -3
- data/test/rails/config/environment.rb +2 -2
- data/test/rails/log/test.log +43862 -0
- data/test/setup.rb +1 -1
- data/test/sinatra/my_app.rb +9 -6
- metadata +10 -9
- data/test/admin_test_.rb +0 -49
data/CHANGELOG
CHANGED
@@ -1,4 +1,30 @@
|
|
1
|
-
2010-11-
|
1
|
+
2010-11-09 version 1.4.0
|
2
|
+
|
3
|
+
If authorization handle is passed as request parameter (the recommended way),
|
4
|
+
then you can call oauth.grant! with a single argument and oauth.deny! with no
|
5
|
+
arguments.
|
6
|
+
|
7
|
+
You can now call oauth.deny! at any point during the authorization flow, e.g.
|
8
|
+
automatically deny all requests based on scope and client.
|
9
|
+
|
10
|
+
To deny access, return status code 403 (was, incorrectly 401). Or just use
|
11
|
+
oauth.deny!.
|
12
|
+
|
13
|
+
Web console gets template_url setting you can use to map access token identity
|
14
|
+
into a URL in your application. The substitution variable is "{id}".
|
15
|
+
|
16
|
+
Added error page when authorization attempt fails (instead of endless
|
17
|
+
redirect).
|
18
|
+
|
19
|
+
Fixed mounting of Web console on Rails. If it failed you before, try again.
|
20
|
+
|
21
|
+
Fixed documentation for configuration under Rails, clarify that all the
|
22
|
+
interesting stuff happens in after_initialize.
|
23
|
+
|
24
|
+
Fixed error responses for response_type=token to use fragment identifier.
|
25
|
+
|
26
|
+
|
27
|
+
2010-11-08 version 1.3.1
|
2
28
|
|
3
29
|
Added command line tool, helps you get started and setup:
|
4
30
|
$ oauth2-server setup --db my_db
|
data/README.rdoc
CHANGED
@@ -30,14 +30,15 @@ when required, but you do need to configure it from within
|
|
30
30
|
example:
|
31
31
|
|
32
32
|
Rails::Initializer.run do |config|
|
33
|
-
config.oauth.database = Mongo::Connection.new["my_db"]
|
34
|
-
config.oauth.scopes = %w{read write}
|
35
|
-
config.oauth.authenticator = lambda do |username, password|
|
36
|
-
user = User.find(username)
|
37
|
-
user if user && user.authenticated?(password)
|
38
|
-
end
|
39
|
-
|
40
33
|
. . .
|
34
|
+
config.after_initialize do
|
35
|
+
config.oauth.database = Mongo::Connection.new["my_db"]
|
36
|
+
config.oauth.scopes = %w{read write}
|
37
|
+
config.oauth.authenticator = lambda do |username, password|
|
38
|
+
user = User.find(username)
|
39
|
+
user if user && user.authenticated?(password)
|
40
|
+
end
|
41
|
+
end
|
41
42
|
end
|
42
43
|
|
43
44
|
For Sinatra and Padrino, first require +rack/oauth2/sinatra+ and register
|
@@ -110,8 +111,8 @@ user back to the client application with an authorization code or access token.
|
|
110
111
|
|
111
112
|
To signal that the user denied the authorization requests your application sets
|
112
113
|
the response header oauth.authorization as before, and returns the status code
|
113
|
-
|
114
|
-
|
114
|
+
403 (Forbidden). Rack::OAuth2::Server will then redirect the user back to the
|
115
|
+
client application with a suitable error code.
|
115
116
|
|
116
117
|
In Rails, the entire flow would look something like this:
|
117
118
|
|
@@ -125,11 +126,11 @@ In Rails, the entire flow would look something like this:
|
|
125
126
|
end
|
126
127
|
|
127
128
|
def grant
|
128
|
-
head oauth.grant!(
|
129
|
+
head oauth.grant!(current_user.id)
|
129
130
|
end
|
130
131
|
|
131
132
|
def deny
|
132
|
-
head oauth.deny!
|
133
|
+
head oauth.deny!
|
133
134
|
end
|
134
135
|
end
|
135
136
|
|
@@ -149,11 +150,11 @@ In Sinatra/Padrino, it would look something like this:
|
|
149
150
|
end
|
150
151
|
|
151
152
|
post "/oauth/grant" do
|
152
|
-
oauth.grant!
|
153
|
+
oauth.grant! "Superman"
|
153
154
|
end
|
154
155
|
|
155
156
|
post "/oauth/deny" do
|
156
|
-
oauth.deny!
|
157
|
+
oauth.deny!
|
157
158
|
end
|
158
159
|
|
159
160
|
The view would look something like this:
|
@@ -374,9 +375,7 @@ the console, by granting them access to the +oauth-admin+ scope. For example:
|
|
374
375
|
|
375
376
|
def authorize
|
376
377
|
# Only admins allowed to authorize the scope oauth-admin
|
377
|
-
if oauth.scope.include?("oauth-admin") && !current_user.admin?
|
378
|
-
oauth.deny! oauth.authorization
|
379
|
-
end
|
378
|
+
head oauth.deny! if oauth.scope.include?("oauth-admin") && !current_user.admin?
|
380
379
|
end
|
381
380
|
|
382
381
|
Make sure you do that, or you'll allow anyone access to the OAuth Web console.
|
@@ -386,9 +385,11 @@ client ID/secret. For example, for Rails add this to +config/environment.rb+:
|
|
386
385
|
|
387
386
|
Rails::Initializer.run do |config|
|
388
387
|
. . .
|
389
|
-
config.
|
390
|
-
|
391
|
-
|
388
|
+
config.after_initialize do
|
389
|
+
config.middleware.use Rack::OAuth2::Server::Admin.mount
|
390
|
+
Rack::OAuth2::Server::Admin.set :client_id, "4dca20453e4859cb000007"
|
391
|
+
Rack::OAuth2::Server::Admin.set :client_secret, "981fa734e110496fcf667cbf52fbaf03"
|
392
|
+
end
|
392
393
|
end
|
393
394
|
|
394
395
|
For Sinatra, Padrino and other Rack-based applications, you'll want to mount
|
@@ -404,6 +405,11 @@ like so (e.g. in +config.ru+):
|
|
404
405
|
Next, open your browser to http://example.com/oauth/admin, or wherever you
|
405
406
|
mounted the console.
|
406
407
|
|
408
|
+
Another option, +template_url+ allows you to link access token identities to
|
409
|
+
URLs in your application, using the substitution variable "{id}". For example:
|
410
|
+
|
411
|
+
Rack::OAuth2::Server::Admin.set :template_url, "https://example.com/accounts/{id}"
|
412
|
+
|
407
413
|
The OAuth Web console is a single-page client application that operates by
|
408
414
|
accessing the OAuth API. The API is mounted at /oauth/admin/api (basically /api
|
409
415
|
relative to the console), you can access it yourself if you have an access
|
data/Rakefile
CHANGED
@@ -39,14 +39,14 @@ Rake::TestTask.new do |task|
|
|
39
39
|
end
|
40
40
|
|
41
41
|
namespace :test do
|
42
|
-
task :all=>["test:sinatra", "test:
|
42
|
+
task :all=>["test:sinatra", "test:rails"]
|
43
43
|
desc "Run all tests against Sinatra"
|
44
44
|
task :sinatra do
|
45
45
|
sh "rake test FRAMEWORK=sinatra"
|
46
46
|
end
|
47
47
|
desc "Run all tests against Rails 2.3.x"
|
48
|
-
task :
|
49
|
-
sh "rake test FRAMEWORK=
|
48
|
+
task :rails do
|
49
|
+
sh "rake test FRAMEWORK=rails"
|
50
50
|
end
|
51
51
|
end
|
52
52
|
task :default=>"test:all"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
data/bin/oauth2-server
CHANGED
@@ -62,18 +62,18 @@ when "setup"
|
|
62
62
|
Make sure you ONLY authorize administrators to use the oauth-admin scope.
|
63
63
|
For example:
|
64
64
|
|
65
|
-
|
65
|
+
before_filter do
|
66
66
|
# Only admins allowed to authorize the scope oauth-admin
|
67
|
-
if oauth.scope.include?("oauth-admin") && !current_user.admin?
|
68
|
-
oauth.deny! oauth.authorization
|
69
|
-
end
|
67
|
+
head oauth.deny! if oauth.scope.include?("oauth-admin") && !current_user.admin?
|
70
68
|
end
|
71
69
|
|
72
70
|
Rails 2.x, add the following to config/environment.rb:
|
73
71
|
|
74
|
-
config.
|
75
|
-
|
76
|
-
|
72
|
+
config.after_initialize do
|
73
|
+
config.middleware.use Rack::OAuth2::Server::Admin.mount "#{uri.path}"
|
74
|
+
Rack::OAuth2::Server::Admin.set :client_id, "#{client.id}"
|
75
|
+
Rack::OAuth2::Server::Admin.set :client_secret, "#{client.secret}"
|
76
|
+
end
|
77
77
|
|
78
78
|
Sinatra, Padrino and other Rack applications, mount the console:
|
79
79
|
|
@@ -107,8 +107,10 @@ button:active { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(0
|
|
107
107
|
}
|
108
108
|
|
109
109
|
#main {
|
110
|
+
margin: 0;
|
110
111
|
padding: 0 2em 4em 2em;
|
111
112
|
background: #fff;
|
113
|
+
border: 1px solid #fff;
|
112
114
|
}
|
113
115
|
#footer {
|
114
116
|
background: #eee;
|
@@ -189,7 +191,7 @@ table.clients td.secrets dd:after {
|
|
189
191
|
}
|
190
192
|
|
191
193
|
table.tokens td.token {
|
192
|
-
width:
|
194
|
+
width: 36em;
|
193
195
|
}
|
194
196
|
table.tokens td.scope {
|
195
197
|
}
|
@@ -264,6 +266,14 @@ table.tokens td.scope {
|
|
264
266
|
margin-left: 60px;
|
265
267
|
}
|
266
268
|
|
269
|
+
.no-access {
|
270
|
+
margin: 0;
|
271
|
+
padding: 0;
|
272
|
+
}
|
273
|
+
.no-access h1 {
|
274
|
+
color: red;
|
275
|
+
}
|
276
|
+
|
267
277
|
.loading {
|
268
278
|
background: url("../images/loading.gif") no-repeat 50% 50%;
|
269
279
|
}
|
@@ -6,28 +6,39 @@ Sammy("#main", function(app) {
|
|
6
6
|
|
7
7
|
// Use OAuth access token in all API requests.
|
8
8
|
$(document).ajaxSend(function(e, xhr) {
|
9
|
-
|
9
|
+
if (app.session("oauth.token"))
|
10
|
+
xhr.setRequestHeader("Authorization", "OAuth " + app.session("oauth.token"));
|
10
11
|
});
|
11
12
|
// For all request (except callback), if we don't have an OAuth access token,
|
12
13
|
// ask for one by requesting authorization.
|
13
|
-
this.before({ except: { path:
|
14
|
+
this.before({ except: { path: /^#\w+=.+/ } }, function(context) {
|
14
15
|
if (!app.session("oauth.token"))
|
15
16
|
context.redirect(document.location.pathname + "/authorize?state=" + escape(context.path));
|
16
17
|
})
|
18
|
+
function hashParams(hash) {
|
19
|
+
var pairs = hash.substring(1).split("&"), params = {};
|
20
|
+
for (var i in pairs) {
|
21
|
+
var splat = pairs[i].split("=");
|
22
|
+
params[splat[0]] = splat[1];
|
23
|
+
}
|
24
|
+
return params;
|
25
|
+
}
|
17
26
|
// We recognize the OAuth authorization callback based on one of its
|
18
27
|
// parameters. Crude but works here.
|
19
|
-
this.get(/^#(access_token=|[^\\]
|
28
|
+
this.get(/^#(access_token=|[^\\].*\&access_token=)/, function(context) {
|
20
29
|
// Instead of a hash we get query parameters, so turn those into an object.
|
21
|
-
var params = context.path
|
22
|
-
|
23
|
-
var splat = params[i].split("=");
|
24
|
-
args[splat[0]] = splat[1];
|
25
|
-
}
|
26
|
-
app.session("oauth.token", args.access_token);
|
30
|
+
var params = hashParams(context.path);
|
31
|
+
app.session("oauth.token", params.access_token);
|
27
32
|
// When the filter redirected the original request, it passed the original
|
28
33
|
// request's URL in the state parameter, which we get back after
|
29
34
|
// authorization.
|
30
|
-
context.redirect(
|
35
|
+
context.redirect(params.state.length == 0 ? "#/" : unescape(params.state));
|
36
|
+
});
|
37
|
+
// Authorization error/rejected.
|
38
|
+
this.get(/^#(error=|[^\\].*\&error=)/, function(context) {
|
39
|
+
var params = hashParams(context.path);
|
40
|
+
var error = params.error_description || "You were denied access";
|
41
|
+
context.partial("admin/views/no_access.tmpl", { error: error.replace(/\+/g, " ") });
|
31
42
|
});
|
32
43
|
|
33
44
|
|
@@ -28,7 +28,7 @@
|
|
28
28
|
{{each tokens.list}}
|
29
29
|
<tr>
|
30
30
|
<td class="token">${token}</td>
|
31
|
-
<td class="identity">${identity}</td>
|
31
|
+
<td class="identity">{{if link}}<a href="${link}">${identity}</a>{{else}}${identity}{{/if}}</td>
|
32
32
|
<td class="scope">${scope}</td>
|
33
33
|
<td class="created">{{html $.shortdate(created)}}</td>
|
34
34
|
<td class="revoke">
|
data/lib/rack/oauth2/server.rb
CHANGED
@@ -2,6 +2,7 @@ require "rack/oauth2/models"
|
|
2
2
|
require "rack/oauth2/server/errors"
|
3
3
|
require "rack/oauth2/server/utils"
|
4
4
|
require "rack/oauth2/server/helper"
|
5
|
+
require "rack/oauth2/server/admin"
|
5
6
|
|
6
7
|
|
7
8
|
module Rack
|
@@ -107,7 +108,7 @@ module Rack
|
|
107
108
|
request.env["oauth.access_token"] = token
|
108
109
|
request.env["oauth.identity"] = access_token.identity
|
109
110
|
logger.info "Authorized #{access_token.identity}" if logger
|
110
|
-
rescue
|
111
|
+
rescue OAuthError=>error
|
111
112
|
# 5.2. The WWW-Authenticate Response Header Field
|
112
113
|
logger.info "HTTP authorization failed #{error.code}" if logger
|
113
114
|
return unauthorized(request, error)
|
@@ -154,30 +155,32 @@ module Rack
|
|
154
155
|
# application.
|
155
156
|
def request_authorization(request, logger)
|
156
157
|
state = request.GET["state"]
|
157
|
-
|
158
|
-
auth_request = self.class.get_auth_request(request.GET["authorization"]) rescue nil
|
159
|
-
if !auth_request || auth_request.revoked
|
160
|
-
logger.error "Invalid authorization request #{auth_request}" if logger
|
161
|
-
return bad_request("Invalid authorization request")
|
162
|
-
end
|
163
|
-
client = self.class.get_client(auth_request.client_id)
|
158
|
+
begin
|
164
159
|
|
165
|
-
|
160
|
+
if request.GET["authorization"]
|
161
|
+
auth_request = self.class.get_auth_request(request.GET["authorization"]) rescue nil
|
162
|
+
if !auth_request || auth_request.revoked
|
163
|
+
logger.error "Invalid authorization request #{auth_request}" if logger
|
164
|
+
return bad_request("Invalid authorization request")
|
165
|
+
end
|
166
|
+
response_type = auth_request.response_type # Needed for error handling
|
167
|
+
client = self.class.get_client(auth_request.client_id)
|
166
168
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
169
|
+
else
|
170
|
+
|
171
|
+
# 3. Obtaining End-User Authorization
|
172
|
+
begin
|
173
|
+
redirect_uri = Utils.parse_redirect_uri(request.GET["redirect_uri"])
|
174
|
+
rescue InvalidRequestError=>error
|
175
|
+
logger.error "Authorization request with invalid redirect_uri: #{request.GET["redirect_uri"]} #{error.message}" if logger
|
176
|
+
return bad_request(error.message)
|
177
|
+
end
|
174
178
|
|
175
|
-
begin
|
176
179
|
# 3. Obtaining End-User Authorization
|
180
|
+
response_type = request.GET["response_type"].to_s # Need this first, for error handling
|
177
181
|
client = get_client(request)
|
178
182
|
raise RedirectUriMismatchError unless client.redirect_uri.nil? || client.redirect_uri == redirect_uri.to_s
|
179
183
|
requested_scope = request.GET["scope"].to_s.split.uniq.join(" ")
|
180
|
-
response_type = request.GET["response_type"].to_s
|
181
184
|
raise UnsupportedResponseTypeError unless options.authorization_types.include?(response_type)
|
182
185
|
if scopes = options.scopes
|
183
186
|
allowed_scope = scopes.respond_to?(:all?) ? scopes : scopes.split
|
@@ -186,17 +189,24 @@ module Rack
|
|
186
189
|
# Create object to track authorization request and let application
|
187
190
|
# handle the rest.
|
188
191
|
auth_request = AuthRequest.create(client.id, requested_scope, redirect_uri.to_s, response_type, state)
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
+
request.env["oauth.authorization"] = auth_request.id.to_s
|
193
|
+
end
|
194
|
+
# Pass back to application, watch for 403 (deny!)
|
195
|
+
logger.info "Request #{auth_request.id}: Client #{client.display_name} requested #{auth_request.response_type} with scope #{auth_request.scope}" if logger
|
196
|
+
response = @app.call(request.env)
|
197
|
+
raise AccessDeniedError if response[0] == 403
|
198
|
+
return response
|
199
|
+
rescue OAuthError=>error
|
200
|
+
logger.error "Authorization request error: #{error.code} #{error.message}" if logger
|
201
|
+
params = { :error=>error.code, :error_description=>error.message, :state=>state }
|
202
|
+
if response_type == "token"
|
203
|
+
redirect_uri.fragment = Rack::Utils.build_query(params)
|
204
|
+
else # response type is code, or invalid
|
205
|
+
params = Rack::Utils.parse_query(redirect_uri.query).merge(params)
|
192
206
|
redirect_uri.query = Rack::Utils.build_query(params)
|
193
|
-
return redirect_to(redirect_uri)
|
194
207
|
end
|
208
|
+
return redirect_to(redirect_uri)
|
195
209
|
end
|
196
|
-
|
197
|
-
request.env["oauth.authorization"] = auth_request.id.to_s
|
198
|
-
logger.info "Request #{auth_request.id}: Client #{client.display_name} requested #{auth_request.response_type} with scope #{auth_request.scope}" if logger
|
199
|
-
return @app.call(request.env)
|
200
210
|
end
|
201
211
|
|
202
212
|
# Get here on completion of the authorization. Authorization response in
|
@@ -206,29 +216,33 @@ module Rack
|
|
206
216
|
status, headers, body = response
|
207
217
|
auth_request = self.class.get_auth_request(headers["oauth.authorization"])
|
208
218
|
redirect_uri = URI.parse(auth_request.redirect_uri)
|
209
|
-
if status ==
|
219
|
+
if status == 403
|
210
220
|
auth_request.deny!
|
211
221
|
else
|
212
222
|
auth_request.grant! headers["oauth.identity"]
|
213
223
|
end
|
214
224
|
# 3.1. Authorization Response
|
215
|
-
if auth_request.response_type == "code"
|
216
|
-
|
217
|
-
|
225
|
+
if auth_request.response_type == "code"
|
226
|
+
if auth_request.grant_code
|
227
|
+
logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} granted access code #{auth_request.grant_code}" if logger
|
228
|
+
params = { :code=>auth_request.grant_code, :scope=>auth_request.scope, :state=>auth_request.state }
|
229
|
+
else
|
230
|
+
logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} denied authorization" if logger
|
231
|
+
params = { :error=>:access_denied, :state=>auth_request.state }
|
232
|
+
end
|
218
233
|
params = Rack::Utils.parse_query(redirect_uri.query).merge(params)
|
219
234
|
redirect_uri.query = Rack::Utils.build_query(params)
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
235
|
+
else # response type if token
|
236
|
+
if auth_request.access_token
|
237
|
+
logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} granted access token #{auth_request.access_token}" if logger
|
238
|
+
params = { :access_token=>auth_request.access_token, :scope=>auth_request.scope, :state=>auth_request.state }
|
239
|
+
else
|
240
|
+
logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} denied authorization" if logger
|
241
|
+
params = { :error=>:access_denied, :state=>auth_request.state }
|
242
|
+
end
|
224
243
|
redirect_uri.fragment = Rack::Utils.build_query(params)
|
225
|
-
return redirect_to(redirect_uri)
|
226
|
-
else
|
227
|
-
logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} denied authorization" if logger
|
228
|
-
params = Rack::Utils.parse_query(redirect_uri.query).merge(:error=>:access_denied, :state=>auth_request.state)
|
229
|
-
redirect_uri.query = Rack::Utils.build_query(params)
|
230
|
-
return redirect_to(redirect_uri)
|
231
244
|
end
|
245
|
+
return redirect_to(redirect_uri)
|
232
246
|
end
|
233
247
|
|
234
248
|
# 4. Obtaining an Access Token
|
@@ -264,7 +278,7 @@ module Rack
|
|
264
278
|
response[:scope] = access_token.scope unless access_token.scope.empty?
|
265
279
|
return [200, { "Content-Type"=>"application/json", "Cache-Control"=>"no-store" }, response.to_json]
|
266
280
|
# 4.3. Error Response
|
267
|
-
rescue
|
281
|
+
rescue OAuthError=>error
|
268
282
|
logger.error "Access token request error: #{error.code} #{error.message}" if logger
|
269
283
|
return unauthorized(request, error) if InvalidClientError === error && request.basic?
|
270
284
|
return [400, { "Content-Type"=>"application/json", "Cache-Control"=>"no-store" },
|
@@ -16,7 +16,7 @@ module Rack
|
|
16
16
|
def mount(klass, path)
|
17
17
|
@klass = klass
|
18
18
|
@path = path
|
19
|
-
@match = /^#{Regexp.escape(path)}
|
19
|
+
@match = /^#{Regexp.escape(path)}(\/.*|$)?/
|
20
20
|
end
|
21
21
|
|
22
22
|
attr_reader :klass, :path, :match
|
@@ -31,7 +31,7 @@ module Rack
|
|
31
31
|
path = env["PATH_INFO"].to_s
|
32
32
|
script_name = env['SCRIPT_NAME']
|
33
33
|
if path =~ self.class.match && rest = $1
|
34
|
-
env.merge! "SCRIPT_NAME"=>(script_name + self.class.path), "PATH_INFO"=>
|
34
|
+
env.merge! "SCRIPT_NAME"=>(script_name + self.class.path), "PATH_INFO"=>rest
|
35
35
|
return @admin.call(env)
|
36
36
|
else
|
37
37
|
return @pass.call(env)
|
@@ -63,6 +63,9 @@ module Rack
|
|
63
63
|
# Use this URL to authorize access to this console. If not set, goes to
|
64
64
|
# /oauth/authorize.
|
65
65
|
set :authorize, nil
|
66
|
+
# Map access token identity to URL on your application, by replacing
|
67
|
+
# "{id}" with the token identity (e.g. "http://example.com/user/{id}")
|
68
|
+
set :template_url, nil
|
66
69
|
|
67
70
|
# Number of tokens to return in each page.
|
68
71
|
set :tokens_per_page, 100
|
@@ -213,6 +216,7 @@ module Rack
|
|
213
216
|
def token_as_json(token)
|
214
217
|
{ :token=>token.token, :identity=>token.identity, :scope=>token.scope, :created=>token.created_at,
|
215
218
|
:expired=>token.expires_at, :revoked=>token.revoked,
|
219
|
+
:link=>settings.template_url && settings.template_url.gsub("{id}", token.identity),
|
216
220
|
:revoke=>"#{request.script_name}/api/token/#{token.token}/revoke" }
|
217
221
|
end
|
218
222
|
end
|