oauth2_provider 0.2.0 → 0.3.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/CHANGELOG +306 -0
- data/HACKING.textile +45 -0
- data/NOTICE.textile +6 -0
- data/README.textile +11 -3
- data/WHAT_IS_OAUTH.textile +165 -0
- data/app/controllers/oauth_authorize_controller.rb +69 -0
- data/app/controllers/oauth_clients_controller.rb +79 -0
- data/app/controllers/oauth_token_controller.rb +59 -0
- data/app/controllers/oauth_user_tokens_controller.rb +61 -0
- data/app/models/oauth2/provider/oauth_authorization.rb +4 -0
- data/app/models/oauth2/provider/oauth_client.rb +14 -3
- data/app/views/{oauth2/provider/layouts → layouts}/oauth_clients.html.erb +0 -0
- data/app/views/oauth_authorize/index.html.erb +17 -0
- data/app/views/oauth_clients/_form.html.erb +27 -0
- data/app/views/oauth_clients/edit.html.erb +7 -0
- data/app/views/oauth_clients/index.html.erb +53 -0
- data/app/views/oauth_clients/new.html.erb +7 -0
- data/app/views/{oauth2/provider/oauth_clients → oauth_clients}/show.html.erb +0 -0
- data/app/views/oauth_user_tokens/index.html.erb +28 -0
- data/config/routes.rb +15 -9
- data/generators/oauth2_provider/USAGE +12 -0
- data/generators/oauth2_provider/templates/config/initializers/oauth2_provider.rb +3 -0
- data/lib/ext/validatable_ext.rb +27 -0
- data/lib/oauth2/provider/a_r_datasource.rb +13 -1
- data/lib/oauth2/provider/application_controller_methods.rb +32 -20
- data/lib/oauth2/provider/configuration.rb +39 -0
- data/lib/oauth2/provider/in_memory_datasource.rb +8 -0
- data/lib/oauth2/provider/model_base.rb +59 -10
- data/lib/oauth2/provider/ssl_helper.rb +42 -0
- data/lib/oauth2/provider/transaction_helper.rb +24 -0
- data/lib/oauth2/provider/url_parser.rb +17 -0
- data/lib/oauth2_provider.rb +3 -6
- data/oauth2_provider.gemspec +15 -6
- metadata +81 -26
- data/app/controllers/oauth2/provider/oauth_authorize_controller.rb +0 -68
- data/app/controllers/oauth2/provider/oauth_clients_controller.rb +0 -56
- data/app/controllers/oauth2/provider/oauth_token_controller.rb +0 -58
- data/app/controllers/oauth2/provider/oauth_user_tokens_controller.rb +0 -29
- data/app/views/oauth2/provider/oauth_authorize/index.html.erb +0 -8
- data/app/views/oauth2/provider/oauth_clients/edit.html.erb +0 -20
- data/app/views/oauth2/provider/oauth_clients/index.html.erb +0 -28
- data/app/views/oauth2/provider/oauth_clients/new.html.erb +0 -21
- data/app/views/oauth2/provider/oauth_user_tokens/index.html.erb +0 -14
- data/tasks/gem.rake +0 -88
@@ -0,0 +1,69 @@
|
|
1
|
+
# Copyright (c) 2010 ThoughtWorks Inc. (http://thoughtworks.com)
|
2
|
+
# Licenced under the MIT License (http://www.opensource.org/licenses/mit-license.php)
|
3
|
+
|
4
|
+
class OauthAuthorizeController < ::ApplicationController
|
5
|
+
|
6
|
+
include Oauth2::Provider::SslHelper
|
7
|
+
include Oauth2::Provider::TransactionHelper
|
8
|
+
|
9
|
+
transaction_actions :authorize
|
10
|
+
|
11
|
+
def index
|
12
|
+
return unless validate_params
|
13
|
+
end
|
14
|
+
|
15
|
+
def authorize
|
16
|
+
return unless validate_params
|
17
|
+
|
18
|
+
unless params[:authorize] == 'Yes'
|
19
|
+
redirect_to "#{params[:redirect_uri]}?error=access-denied"
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
authorization = @client.create_authorization_for_user_id(current_user_id_for_oauth)
|
24
|
+
state_param = if params[:state].blank?
|
25
|
+
""
|
26
|
+
else
|
27
|
+
"&state=#{CGI.escape(params[:state])}"
|
28
|
+
end
|
29
|
+
|
30
|
+
redirect_to "#{params[:redirect_uri]}?code=#{authorization.code}&expires_in=#{authorization.expires_in}#{state_param}"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# TODO: support 'code', 'token', 'code-and-token'
|
36
|
+
VALID_RESPONSE_TYPES = ['code']
|
37
|
+
|
38
|
+
def validate_params
|
39
|
+
if params[:client_id].blank? || params[:response_type].blank?
|
40
|
+
redirect_to "#{params[:redirect_uri]}?error=invalid-request"
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
unless VALID_RESPONSE_TYPES.include?(params[:response_type])
|
45
|
+
redirect_to "#{params[:redirect_uri]}?error=unsupported-response-type"
|
46
|
+
return
|
47
|
+
end
|
48
|
+
|
49
|
+
if params[:redirect_uri].blank?
|
50
|
+
render :text => "You did not specify the 'redirect_uri' parameter!", :status => :bad_request
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
@client = Oauth2::Provider::OauthClient.find_one(:client_id, params[:client_id])
|
55
|
+
|
56
|
+
if @client.nil?
|
57
|
+
redirect_to "#{params[:redirect_uri]}?error=invalid-client-id"
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
61
|
+
if @client.redirect_uri != params[:redirect_uri]
|
62
|
+
redirect_to "#{params[:redirect_uri]}?error=redirect-uri-mismatch"
|
63
|
+
return false
|
64
|
+
end
|
65
|
+
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (c) 2010 ThoughtWorks Inc. (http://thoughtworks.com)
|
2
|
+
# Licenced under the MIT License (http://www.opensource.org/licenses/mit-license.php)
|
3
|
+
|
4
|
+
class OauthClientsController < ApplicationController
|
5
|
+
|
6
|
+
include Oauth2::Provider::SslHelper
|
7
|
+
include Oauth2::Provider::TransactionHelper
|
8
|
+
|
9
|
+
transaction_actions :create, :update, :destroy
|
10
|
+
|
11
|
+
|
12
|
+
def index
|
13
|
+
@oauth_clients = Oauth2::Provider::OauthClient.all.sort{|a, b| a.name.casecmp(b.name)}
|
14
|
+
respond_to do |format|
|
15
|
+
format.html
|
16
|
+
format.xml { render :xml => @oauth_clients.to_xml(:root => 'oauth_clients', :dasherize => false) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def show
|
21
|
+
@oauth_client = Oauth2::Provider::OauthClient.find(params[:id])
|
22
|
+
respond_to do |format|
|
23
|
+
format.html
|
24
|
+
format.xml { render :xml => @oauth_client.to_xml(:dasherize => false) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def new
|
29
|
+
@oauth_client = Oauth2::Provider::OauthClient.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def edit
|
33
|
+
@oauth_client = Oauth2::Provider::OauthClient.find(params[:id])
|
34
|
+
end
|
35
|
+
|
36
|
+
def create
|
37
|
+
@oauth_client = Oauth2::Provider::OauthClient.new(params[:oauth_client])
|
38
|
+
|
39
|
+
respond_to do |format|
|
40
|
+
if @oauth_client.save
|
41
|
+
flash[:notice] = 'OAuth client was successfully created.'
|
42
|
+
format.html { redirect_to :action => 'index' }
|
43
|
+
format.xml { render :xml => @oauth_client, :status => :created, :location => @oauth_client }
|
44
|
+
else
|
45
|
+
flash.now[:error] = @oauth_client.errors.full_messages
|
46
|
+
format.html { render :action => "new" }
|
47
|
+
format.xml { render :xml => @oauth_client.errors, :status => :unprocessable_entity }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def update
|
53
|
+
@oauth_client = Oauth2::Provider::OauthClient.find(params[:id])
|
54
|
+
|
55
|
+
respond_to do |format|
|
56
|
+
if @oauth_client.update_attributes(params[:oauth_client])
|
57
|
+
flash[:notice] = 'OAuth client was successfully updated.'
|
58
|
+
format.html { redirect_to :action => 'index' }
|
59
|
+
format.xml { head :ok }
|
60
|
+
else
|
61
|
+
flash.now[:error] = @oauth_client.errors.full_messages
|
62
|
+
format.html { render :action => "edit" }
|
63
|
+
format.xml { render :xml => @oauth_client.errors, :status => :unprocessable_entity }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
def destroy
|
70
|
+
@oauth_client = Oauth2::Provider::OauthClient.find(params[:id])
|
71
|
+
@oauth_client.destroy
|
72
|
+
|
73
|
+
respond_to do |format|
|
74
|
+
flash[:notice] = 'OAuth client was successfully deleted.'
|
75
|
+
format.html { redirect_to(oauth_clients_url) }
|
76
|
+
format.xml { head :ok }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2010 ThoughtWorks Inc. (http://thoughtworks.com)
|
2
|
+
# Licenced under the MIT License (http://www.opensource.org/licenses/mit-license.php)
|
3
|
+
|
4
|
+
class OauthTokenController < ApplicationController
|
5
|
+
skip_before_filter :verify_authenticity_token
|
6
|
+
|
7
|
+
include Oauth2::Provider::SslHelper
|
8
|
+
include Oauth2::Provider::TransactionHelper
|
9
|
+
|
10
|
+
transaction_actions :get_token
|
11
|
+
|
12
|
+
def get_token
|
13
|
+
|
14
|
+
authorization = Oauth2::Provider::OauthAuthorization.find_one(:code, params[:code])
|
15
|
+
authorization.destroy unless authorization.nil?
|
16
|
+
|
17
|
+
original_token = Oauth2::Provider::OauthToken.find_one(:refresh_token, params[:refresh_token])
|
18
|
+
original_token.destroy unless original_token.nil?
|
19
|
+
|
20
|
+
unless ['authorization-code', 'refresh-token'].include?(params[:grant_type])
|
21
|
+
render_error('unsupported-grant-type', "Grant type #{params[:grant_type]} is not supported!")
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
client = Oauth2::Provider::OauthClient.find_one(:client_id, params[:client_id])
|
26
|
+
|
27
|
+
if client.nil? || client.client_secret != params[:client_secret]
|
28
|
+
render_error('invalid-client-credentials', 'Invalid client credentials!')
|
29
|
+
return
|
30
|
+
end
|
31
|
+
|
32
|
+
if client.redirect_uri != params[:redirect_uri]
|
33
|
+
render_error('invalid-grant', 'Redirect uri mismatch!')
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
if params[:grant_type] == 'authorization-code'
|
38
|
+
if authorization.nil? || authorization.expired? || authorization.oauth_client.id != client.id
|
39
|
+
render_error('invalid-grant', "Authorization expired or invalid!")
|
40
|
+
return
|
41
|
+
end
|
42
|
+
token = authorization.generate_access_token
|
43
|
+
else # refresh-token
|
44
|
+
if original_token.nil? || original_token.oauth_client.id != client.id
|
45
|
+
render_error('invalid-grant', 'Refresh token is invalid!')
|
46
|
+
return
|
47
|
+
end
|
48
|
+
token = original_token.refresh
|
49
|
+
end
|
50
|
+
|
51
|
+
render :content_type => 'application/json', :text => token.access_token_attributes.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def render_error(error_code, description)
|
56
|
+
render :status => :bad_request, :json => {:error => error_code, :error_description => description}.to_json
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Copyright (c) 2010 ThoughtWorks Inc. (http://thoughtworks.com)
|
2
|
+
# Licenced under the MIT License (http://www.opensource.org/licenses/mit-license.php)
|
3
|
+
|
4
|
+
class OauthUserTokensController < ApplicationController
|
5
|
+
|
6
|
+
include Oauth2::Provider::TransactionHelper
|
7
|
+
|
8
|
+
transaction_actions :revoke, :revoke_by_admin
|
9
|
+
|
10
|
+
def index
|
11
|
+
@tokens = Oauth2::Provider::OauthToken.find_all_with(:user_id, current_user_id_for_oauth)
|
12
|
+
end
|
13
|
+
|
14
|
+
def revoke
|
15
|
+
token = Oauth2::Provider::OauthToken.find_by_id(params[:token_id])
|
16
|
+
if token.nil?
|
17
|
+
render_not_authorized
|
18
|
+
return
|
19
|
+
end
|
20
|
+
if token.user_id.to_s != current_user_id_for_oauth
|
21
|
+
render_not_authorized
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
token.destroy
|
26
|
+
redirect_after_revoke
|
27
|
+
end
|
28
|
+
|
29
|
+
def revoke_by_admin
|
30
|
+
|
31
|
+
if params[:token_id].blank? && params[:user_id].blank?
|
32
|
+
render_not_authorized
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
if !params[:token_id].blank?
|
37
|
+
token = Oauth2::Provider::OauthToken.find_by_id(params[:token_id])
|
38
|
+
if token.nil?
|
39
|
+
render_not_authorized
|
40
|
+
return
|
41
|
+
end
|
42
|
+
token.destroy
|
43
|
+
else
|
44
|
+
Oauth2::Provider::OauthToken.find_all_with(:user_id, params[:user_id]).map(&:destroy)
|
45
|
+
end
|
46
|
+
|
47
|
+
redirect_after_revoke
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def render_not_authorized
|
53
|
+
render :text => "You are not authorized to perform this action!", :status => :bad_request
|
54
|
+
end
|
55
|
+
|
56
|
+
def redirect_after_revoke
|
57
|
+
flash[:notice] = "OAuth access token was successfully deleted."
|
58
|
+
redirect_to params[:redirect_url] || {:action => 'index'}
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -13,6 +13,10 @@ module Oauth2
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def generate_access_token
|
16
|
+
OauthToken.find_all_with(:user_id, user_id).each do |token|
|
17
|
+
token.destroy if token.oauth_client_id == oauth_client_id
|
18
|
+
end
|
19
|
+
|
16
20
|
token = oauth_client.create_token_for_user_id(user_id)
|
17
21
|
self.destroy
|
18
22
|
token
|
@@ -6,7 +6,8 @@ module Oauth2
|
|
6
6
|
class OauthClient < ModelBase
|
7
7
|
|
8
8
|
validates_presence_of :name, :redirect_uri
|
9
|
-
validates_format_of :redirect_uri, :with => Regexp.new("^(https|http)://.+$")
|
9
|
+
validates_format_of :redirect_uri, :with => Regexp.new("^(https|http)://.+$"), :if => proc { |client| !client.redirect_uri.blank? }
|
10
|
+
validates_uniqueness_of :name
|
10
11
|
|
11
12
|
columns :name, :client_id, :client_secret, :redirect_uri
|
12
13
|
|
@@ -15,8 +16,12 @@ module Oauth2
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def create_authorization_for_user_id(user_id)
|
19
|
+
oauth_authorizations.each do |authorization|
|
20
|
+
authorization.destroy if authorization.user_id == user_id
|
21
|
+
end
|
18
22
|
OauthAuthorization.create!(:user_id => user_id, :oauth_client_id => id)
|
19
23
|
end
|
24
|
+
|
20
25
|
def self.model_name
|
21
26
|
ActiveSupport::ModelName.new('OauthClient')
|
22
27
|
end
|
@@ -38,7 +43,13 @@ module Oauth2
|
|
38
43
|
oauth_tokens.each(&:destroy)
|
39
44
|
oauth_authorizations.each(&:destroy)
|
40
45
|
end
|
41
|
-
|
46
|
+
|
47
|
+
def before_save
|
48
|
+
self.name.strip! if self.name
|
49
|
+
self.redirect_uri.strip! if self.redirect_uri
|
50
|
+
end
|
51
|
+
|
42
52
|
end
|
43
53
|
end
|
44
|
-
end
|
54
|
+
end
|
55
|
+
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="content_wrapper_outer">
|
2
|
+
<div class="content_wrapper_inner">
|
3
|
+
<% form_for(url_for(:action => :authorize), :html => {:id => 'oauth_authorize_form'}) do |f| -%>
|
4
|
+
<div class="label">Do you wish to allow the service named '<%= @client.name %>' to access this application on your behalf?</div>
|
5
|
+
<div>
|
6
|
+
<%= link_to_function 'Yes', 'document.getElementById("oauth_authorize_allow").value="Yes";document.getElementById("oauth_authorize_form").submit()', {:class => 'link_as_button primary_link_as_button primary', :href => 'javascript:void(0)', :id => 'authorize-yes'} %>
|
7
|
+
<%= link_to_function 'No', 'document.getElementById("oauth_authorize_allow").value="No";document.getElementById("oauth_authorize_form").submit()', {:class => 'link_as_button link_as_button', :href => 'javascript:void(0)', :id => "authorize-no"} %>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<input type="hidden" name="authorize" id="oauth_authorize_allow" value="No"/>
|
11
|
+
<input type="hidden" name="client_id" id="client_id" value="<%= params[:client_id] %>" />
|
12
|
+
<input type="hidden" name="redirect_uri" id="redirect_uri" value="<%= params[:redirect_uri] %>" />
|
13
|
+
<input type="hidden" name="response_type" id="response_type" value="<%= params[:response_type] %>" />
|
14
|
+
<input type="hidden" name="state" id="state" value="<%= params[:state] %>" />
|
15
|
+
<% end -%>
|
16
|
+
</div>
|
17
|
+
</div>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<% form_for(@oauth_client, :html => {:id => 'oauth_client_edit_form', :class => nil}) do |f| %>
|
2
|
+
|
3
|
+
<div class="form_item">
|
4
|
+
<label for='name'>
|
5
|
+
Name:
|
6
|
+
<span class="notes">
|
7
|
+
(The name of the client which will be accessing data from this server.)
|
8
|
+
</span>
|
9
|
+
</label>
|
10
|
+
<%= f.text_field :name, :class => 'width-large' %>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div class="form_item">
|
14
|
+
<label for='redirect_uri'>
|
15
|
+
OAuth Redirect URI:
|
16
|
+
<span class="notes">
|
17
|
+
(The redirect URI provided by the client.)
|
18
|
+
</span>
|
19
|
+
</label>
|
20
|
+
<%= f.text_field :redirect_uri, :class => 'width-large' %>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div class="action-bar">
|
24
|
+
<%= link_to_function 'Submit', 'document.getElementById("oauth_client_edit_form").submit()', {:class => 'link_as_button primary', :href => 'javascript:void(0)'} %>
|
25
|
+
<%= link_to 'Cancel', {:controller => 'oauth_clients'}, {:class => 'link_as_button back_link'} %>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<div id="oauth_page">
|
2
|
+
<%= render_help_link('OAuth 2.0 Clients', :class => 'page-help-at-action-bar') if defined?(render_help_link) %>
|
3
|
+
|
4
|
+
<h1>OAuth clients configuration</h1>
|
5
|
+
|
6
|
+
<% if request.ssl? || !::Oauth2::Provider::Configuration.require_ssl_for_oauth %>
|
7
|
+
<h2>OAuth 2.0 (v9) provider endpoints for this server</h2>
|
8
|
+
|
9
|
+
<% if Oauth2::Provider::Configuration.ssl_base_url_as_url_options[:protocol] == 'https' %>
|
10
|
+
<div class='summary info-box oauth_config_info'>
|
11
|
+
<p><span>Authorization URL:</span> <%= url_for Oauth2::Provider::Configuration.ssl_base_url_as_url_options.merge(:controller => :oauth_authorize, :action => :index) %></p>
|
12
|
+
<p><span>Token URL:</span> <%= url_for Oauth2::Provider::Configuration.ssl_base_url_as_url_options.merge(:controller => :oauth_token, :action => :get_token) %></p>
|
13
|
+
</div>
|
14
|
+
<% else %>
|
15
|
+
<div class="error-box">Please set mingle.secureSiteURL property in mingle.properties in order to see both the Authorization URL and Token URL in this box.</div>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% if @oauth_clients.empty? %>
|
20
|
+
<div class="info-box">You have not configured any OAuth clients. Click the 'Add client' button to add one.</div>
|
21
|
+
<% else %>
|
22
|
+
|
23
|
+
<h2>OAuth clients configured for this server</h2>
|
24
|
+
|
25
|
+
<table id="oauth_clients_table" class="list_table">
|
26
|
+
<tr>
|
27
|
+
<th>Name</th>
|
28
|
+
<th>OAuth Redirect URI</th>
|
29
|
+
<th>OAuth Client Credentials</th>
|
30
|
+
<th>Action</th>
|
31
|
+
</tr>
|
32
|
+
|
33
|
+
<% @oauth_clients.each do |oauth_client| %>
|
34
|
+
<tr>
|
35
|
+
<td><%= link_to h(oauth_client.name), {:controller => 'oauth_clients', :action => :edit, :id => oauth_client.id}, {:class => 'edit_link'} %></td>
|
36
|
+
<td><%=h oauth_client.redirect_uri %></td>
|
37
|
+
<td>
|
38
|
+
<p><b>Client ID</b>: <%=h oauth_client.client_id %></p>
|
39
|
+
<p><b>Client Secret</b>: <%=h oauth_client.client_secret %></p>
|
40
|
+
</td>
|
41
|
+
<td>
|
42
|
+
<%= link_to '<span>Delete</span>', {:controller => 'oauth_clients', :action => :destroy, :id => oauth_client.id}, {:confirm => 'Are you sure?', :method => :delete, :class => 'delete_link', :title => 'Click to delete this client'} %>
|
43
|
+
</td>
|
44
|
+
</tr>
|
45
|
+
<% end %>
|
46
|
+
</table>
|
47
|
+
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
<div class="table_actions">
|
51
|
+
<%= link_to 'Add client', {:controller => 'oauth_clients', :action => :new}, {:class => 'link_as_button primary', :id => 'new_oauth_client_button'} %>
|
52
|
+
</div>
|
53
|
+
</div>
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div id="oauth_page">
|
2
|
+
<%= render_help_link('OAuth 2.0 User Token', :class => 'page-help-at-action-bar') if defined?(render_help_link) %>
|
3
|
+
|
4
|
+
<div class="page_header"><h1 class="entity_title">OAuth Tokens</h1></div>
|
5
|
+
|
6
|
+
<div class="content_wrapper_outer">
|
7
|
+
<div class="content_wrapper_inner">
|
8
|
+
<% if @tokens.empty? %>
|
9
|
+
<div class="info-box">There are no tokens.</div>
|
10
|
+
<% else %>
|
11
|
+
<table id="oauth_user_token_table" class="list_table">
|
12
|
+
<tr>
|
13
|
+
<th>Client</th>
|
14
|
+
<th>Action</th>
|
15
|
+
</tr>
|
16
|
+
<% @tokens.each do |token| -%>
|
17
|
+
<tr>
|
18
|
+
<td><%= h(token.oauth_client.name) %></td>
|
19
|
+
<td><%= link_to '<span>Delete</span>',
|
20
|
+
{:action => :revoke, :token_id => token.id, :controller => 'oauth_user_tokens'},
|
21
|
+
{:confirm => 'Are you sure?', :method => :delete, :class => 'delete_link', :title => 'Click to revoke this token'}%></td>
|
22
|
+
</tr>
|
23
|
+
<% end -%>
|
24
|
+
</table>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
</div>
|