oauth2_provider_engine 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/oauth2_provider/application.js +52 -0
- data/app/assets/javascripts/oauth2_provider/highcharts.js +162 -0
- data/app/assets/javascripts/oauth2_provider/jquery.tagsinput.js +218 -0
- data/app/assets/stylesheets/oauth2_provider/gh-buttons.css +388 -0
- data/app/assets/stylesheets/oauth2_provider/gh-icons.png +0 -0
- data/app/assets/stylesheets/oauth2_provider/jquery.tagsinput.css +6 -0
- data/app/assets/stylesheets/oauth2_provider/reset.css +2 -0
- data/app/assets/stylesheets/oauth2_provider/template.css +52 -0
- data/app/controllers/oauth2_provider/accesses_controller.rb +39 -0
- data/app/controllers/oauth2_provider/application_controller.rb +17 -0
- data/app/controllers/oauth2_provider/authorize_controller.rb +141 -0
- data/app/controllers/oauth2_provider/clients_controller.rb +85 -0
- data/app/controllers/oauth2_provider/scopes_controller.rb +63 -0
- data/app/controllers/oauth2_provider/token_controller.rb +187 -0
- data/app/helpers/clients_helper.rb +5 -0
- data/app/helpers/oauth2_provider/application_helper.rb +4 -0
- data/app/models/oauth2_provider/client.rb +129 -0
- data/app/models/oauth2_provider/document.rb +15 -0
- data/app/models/oauth2_provider/oauth_access.rb +80 -0
- data/app/models/oauth2_provider/oauth_authorization.rb +70 -0
- data/app/models/oauth2_provider/oauth_daily_request.rb +54 -0
- data/app/models/oauth2_provider/oauth_refresh_token.rb +20 -0
- data/app/models/oauth2_provider/oauth_token.rb +78 -0
- data/app/models/oauth2_provider/scope.rb +39 -0
- data/app/views/layouts/oauth2_provider/application.html.erb +62 -0
- data/app/views/oauth2_provider/accesses/index.html.erb +25 -0
- data/app/views/oauth2_provider/accesses/show.html.erb +35 -0
- data/app/views/oauth2_provider/clients/_form.html.erb +50 -0
- data/app/views/oauth2_provider/clients/edit.html.erb +9 -0
- data/app/views/oauth2_provider/clients/index.html.erb +43 -0
- data/app/views/oauth2_provider/clients/new.html.erb +8 -0
- data/app/views/oauth2_provider/clients/show.html.erb +49 -0
- data/app/views/oauth2_provider/scopes/_form.html.erb +35 -0
- data/app/views/oauth2_provider/scopes/edit.html.erb +8 -0
- data/app/views/oauth2_provider/scopes/index.html.erb +27 -0
- data/app/views/oauth2_provider/scopes/new.html.erb +7 -0
- data/app/views/oauth2_provider/scopes/show.html.erb +19 -0
- data/app/views/shared/authorize.html.erb +34 -0
- data/app/views/shared/token.json.erb +8 -0
- data/config/locales/en.yml +31 -0
- data/config/oauth.yml +4 -0
- data/config/routes.rb +25 -0
- data/lib/oauth2_provider.rb +38 -0
- data/lib/oauth2_provider/controller_mixin.rb +53 -0
- data/lib/oauth2_provider/engine.rb +4 -0
- data/lib/oauth2_provider_engine.rb +1 -0
- data/lib/oauth2_provider_engine/version.rb +3 -0
- data/test/dummy/CHANGELOG.rdoc +67 -0
- data/test/dummy/Gemfile +53 -0
- data/test/dummy/Gemfile.lock +254 -0
- data/test/dummy/README.rdoc +522 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/VERSION +1 -0
- data/test/dummy/app/assets/stylesheets/reset.css +2 -0
- data/test/dummy/app/assets/stylesheets/template.css +52 -0
- data/test/dummy/app/controllers/application_controller.rb +52 -0
- data/test/dummy/app/controllers/pastas_controller.rb +23 -0
- data/test/dummy/app/controllers/pizzas_controller.rb +23 -0
- data/test/dummy/app/controllers/sessions_controller.rb +26 -0
- data/test/dummy/app/controllers/users_controller.rb +59 -0
- data/test/dummy/app/models/user.rb +50 -0
- data/test/dummy/app/views/layouts/application.html.erb +65 -0
- data/test/dummy/app/views/sessions/new.html.erb +25 -0
- data/test/dummy/app/views/shared/403.json.erb +4 -0
- data/test/dummy/app/views/shared/404.json.erb +6 -0
- data/test/dummy/app/views/shared/422.json.erb +5 -0
- data/test/dummy/app/views/shared/500.json.erb +4 -0
- data/test/dummy/app/views/shared/html/404.html.erb +0 -0
- data/test/dummy/app/views/shared/html/422.html.erb +0 -0
- data/test/dummy/app/views/users/_form.html.erb +27 -0
- data/test/dummy/app/views/users/edit.html.erb +8 -0
- data/test/dummy/app/views/users/index.html.erb +20 -0
- data/test/dummy/app/views/users/new.html.erb +46 -0
- data/test/dummy/app/views/users/show.html.erb +15 -0
- data/test/dummy/app/views/users/show.json.erb +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +57 -0
- data/test/dummy/config/boot.rb +13 -0
- data/test/dummy/config/cucumber.yml +8 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +32 -0
- data/test/dummy/config/environments/production.rb +58 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/test.rb +3 -0
- data/test/dummy/config/locales/en.yml +1 -0
- data/test/dummy/config/mongoid.yml +20 -0
- data/test/dummy/config/routes.rb +22 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/doc/README_FOR_APP +2 -0
- data/test/dummy/lib/tasks/cucumber.rake +53 -0
- data/test/dummy/lib/tasks/watchr.rake +5 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +4 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/script/cucumber +10 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/spec/acceptance/acceptance_helper.rb +5 -0
- data/test/dummy/spec/acceptance/accesses_controller_spec.rb +77 -0
- data/test/dummy/spec/acceptance/clients_controller_spec.rb +218 -0
- data/test/dummy/spec/acceptance/oauth_authorize_controller_spec.rb +241 -0
- data/test/dummy/spec/acceptance/oauth_token_controller_spec.rb +196 -0
- data/test/dummy/spec/acceptance/resource_controller_spec.rb +143 -0
- data/test/dummy/spec/acceptance/scopes_controller_spec.rb +227 -0
- data/test/dummy/spec/acceptance/support/helpers.rb +81 -0
- data/test/dummy/spec/acceptance/support/paths.rb +9 -0
- data/test/dummy/spec/acceptance/support/view_helpers.rb +52 -0
- data/test/dummy/spec/acceptance/users_controller_spec.rb +198 -0
- data/test/dummy/spec/extras/scope_spec.rb +105 -0
- data/test/dummy/spec/factories/oauth.rb +106 -0
- data/test/dummy/spec/models/oauth/client_spec.rb +123 -0
- data/test/dummy/spec/models/oauth/oauth_access_spec.rb +48 -0
- data/test/dummy/spec/models/oauth/oauth_authorization_spec.rb +50 -0
- data/test/dummy/spec/models/oauth/oauth_daily_request_spec.rb +14 -0
- data/test/dummy/spec/models/oauth/oauth_refresh_token_spec.rb +11 -0
- data/test/dummy/spec/models/oauth/oauth_token_spec.rb +55 -0
- data/test/dummy/spec/models/scope_spec.rb +17 -0
- data/test/dummy/spec/spec_helper.rb +39 -0
- data/test/dummy/spec/support/settings_helper.rb +28 -0
- data/test/dummy/test/initializers/capybara_headers_hack.rb +23 -0
- data/test/oauth2_provider_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +387 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
class Oauth2Provider::AccessesController < Oauth2Provider::ApplicationController
|
2
|
+
|
3
|
+
before_filter :_oauth_provider_find_access, except: :index
|
4
|
+
|
5
|
+
def index
|
6
|
+
@accesses = Oauth2Provider::OauthAccess.to_adapter.find_all(resource_owner_uri: user_url(current_user))
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
end
|
11
|
+
|
12
|
+
def block
|
13
|
+
@access.block!
|
14
|
+
redirect_to oauth2_provider_engine.oauth2_provider_accesses_url
|
15
|
+
end
|
16
|
+
|
17
|
+
def unblock
|
18
|
+
@access.unblock!
|
19
|
+
redirect_to oauth2_provider_engine.oauth2_provider_accesses_url
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
private
|
24
|
+
def _oauth_provider_find_access
|
25
|
+
@access = Oauth2Provider::OauthAccess.to_adapter.find_first(resource_owner_uri: user_url(current_user), id: params[:id])
|
26
|
+
unless @access
|
27
|
+
redirect_to root_path, alert: "Resource not found."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: change this behavior with a simple redirect
|
32
|
+
def resource_not_found
|
33
|
+
flash.now.alert = "notifications.document.not_found"
|
34
|
+
@info = { id: params[:id] }
|
35
|
+
render "shared/html/404" and return
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Oauth2Provider
|
2
|
+
class ApplicationController < ::ApplicationController
|
3
|
+
(::ApplicationController._process_action_callbacks - ActionController::Base._process_action_callbacks).each{|callback|skip_before_filter callback.filter if callback.kind == :before}
|
4
|
+
|
5
|
+
before_filter :_oauth_provider_authenticate
|
6
|
+
|
7
|
+
include ControllerMixin
|
8
|
+
layout 'oauth2_provider/application'
|
9
|
+
def _oauth_provider_admin?
|
10
|
+
unless current_user.admin?
|
11
|
+
flash.alert = "Unauthorized access."
|
12
|
+
redirect_to root_path
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class Oauth2Provider::AuthorizeController < Oauth2Provider::ApplicationController
|
2
|
+
|
3
|
+
before_filter :_oauth_provider_authenticate
|
4
|
+
before_filter :_oauth_provider_normalize_scope
|
5
|
+
before_filter :_oauth_provider_find_client
|
6
|
+
before_filter :_oauth_provider_check_scope # check if the access is authorized
|
7
|
+
before_filter :_oauth_provider_client_blocked? # check if the client is blocked
|
8
|
+
before_filter :_oauth_provider_access_blocked? # check if user has blocked the client
|
9
|
+
|
10
|
+
before_filter :_oauth_provider_token_blocked?, only: :show # check for an existing token
|
11
|
+
before_filter :_oauth_provider_refresh_token, only: :show # create a new token
|
12
|
+
|
13
|
+
|
14
|
+
def show
|
15
|
+
render "shared/authorize" and return
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
@client.granted!
|
20
|
+
|
21
|
+
# section 4.1.1 - authorization code flow
|
22
|
+
if params[:response_type] == "code"
|
23
|
+
@authorization = Oauth2Provider::OauthAuthorization.create(client_uri: @client.uri, resource_owner_uri: user_url(current_user), scope: params[:scope])
|
24
|
+
redirect_to authorization_redirect_uri(@client, @authorization, params[:state])
|
25
|
+
end
|
26
|
+
|
27
|
+
# section 4.2.1 - implicit grant flow
|
28
|
+
if params[:response_type] == "token"
|
29
|
+
@token = Oauth2Provider::OauthToken.create(client_uri: @client.uri, resource_owner_uri: user_url(current_user), scope: params[:scope])
|
30
|
+
redirect_to implicit_redirect_uri(@client, @token, params[:state])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
@client.revoked!
|
36
|
+
redirect_to deny_redirect_uri(@client, params[:response_type], params[:state])
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def _oauth_provider_normalize_scope
|
43
|
+
params[:scope] = Oauth2Provider.normalize_scope(params[:scope])
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def _oauth_provider_find_client
|
48
|
+
@client = Oauth2Provider::Client.to_adapter.find_first(uri: params[:client_id], redirect_uri: params[:redirect_uri])
|
49
|
+
client_not_found unless @client
|
50
|
+
end
|
51
|
+
|
52
|
+
def _oauth_provider_check_scope
|
53
|
+
debugger
|
54
|
+
Oauth2Provider::Client.where_uri(params[:client_id], params[:redirect_uri]).where_scope(params[:scope]).first
|
55
|
+
@client = Array(params[:scope]).detect do |s|
|
56
|
+
Oauth2Provider::Client.to_adapter.find_first(uri: params[:client_id], redirect_uri: params[:redirect_uri], scope: s)
|
57
|
+
end
|
58
|
+
scope_not_valid unless @client
|
59
|
+
end
|
60
|
+
|
61
|
+
def _oauth_provider_client_blocked?
|
62
|
+
client_blocked if @client.blocked?
|
63
|
+
end
|
64
|
+
|
65
|
+
def _oauth_provider_access_blocked?
|
66
|
+
access = Oauth2Provider::OauthAccess.find_or_create_by(:client_uri => @client.uri, resource_owner_uri: user_url(current_user))
|
67
|
+
access_blocked if access.blocked?
|
68
|
+
end
|
69
|
+
|
70
|
+
def _oauth_provider_token_blocked?
|
71
|
+
if params[:response_type] == "token"
|
72
|
+
@token = Oauth2Provider::OauthToken.exist(@client.uri, user_url(current_user), params[:scope]).first
|
73
|
+
token_blocked if @token and @token.blocked?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @only refresh token for implicit flow
|
78
|
+
def _oauth_provider_refresh_token
|
79
|
+
if @token
|
80
|
+
@token = Oauth2Provider::OauthToken.create(client_uri: @client.uri, resource_owner_uri: user_url(current_user), scope: params[:scope])
|
81
|
+
redirect_to implicit_redirect_uri(@client, @token, params[:state]) and return
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# helper methods
|
87
|
+
|
88
|
+
def client_not_found
|
89
|
+
flash.now.alert = I18n.t "notifications.oauth.client.not_found"
|
90
|
+
@info = { client_id: params[:client_id], redirect_uri: params[:redirect_uri] }
|
91
|
+
render "shared/authorize" and return
|
92
|
+
end
|
93
|
+
|
94
|
+
def scope_not_valid
|
95
|
+
flash.now.alert = I18n.t "notifications.oauth.client.not_authorized"
|
96
|
+
@info = { scope: params[:scope] }
|
97
|
+
render "shared/authorize" and return
|
98
|
+
end
|
99
|
+
|
100
|
+
def client_blocked
|
101
|
+
flash.now.alert = I18n.t "notifications.oauth.client.blocked"
|
102
|
+
@info = { client_id: params[:client_id] }
|
103
|
+
render "shared/authorize" and return
|
104
|
+
end
|
105
|
+
|
106
|
+
def access_blocked
|
107
|
+
flash.now.alert = I18n.t "notifications.oauth.resource_owner.blocked_client"
|
108
|
+
@info = { client_id: params[:client_id] }
|
109
|
+
render "shared/authorize" and return
|
110
|
+
end
|
111
|
+
|
112
|
+
def token_blocked
|
113
|
+
flash.now.alert = I18n.t "notifications.oauth.token.blocked_token"
|
114
|
+
@info = { client_id: params[:client_id], token: @token.token }
|
115
|
+
render "shared/authorize" and return
|
116
|
+
end
|
117
|
+
|
118
|
+
def authorization_redirect_uri(client, authorization, state)
|
119
|
+
uri = client.redirect_uri
|
120
|
+
uri += "?code=" + authorization.code
|
121
|
+
uri += "&state=" + state if state
|
122
|
+
return uri
|
123
|
+
end
|
124
|
+
|
125
|
+
def implicit_redirect_uri(client, token, state)
|
126
|
+
uri = client.redirect_uri
|
127
|
+
uri += "#token=" + token.token
|
128
|
+
uri += "&expires_in=" + Oauth2Provider.settings["token_expires_in"]
|
129
|
+
uri += "&state=" + state if state
|
130
|
+
return uri
|
131
|
+
end
|
132
|
+
|
133
|
+
def deny_redirect_uri(client, response_type, state)
|
134
|
+
uri = client.redirect_uri
|
135
|
+
uri += (response_type == "code") ? "?" : "#"
|
136
|
+
uri += "error=access_denied"
|
137
|
+
uri += "&state=" + state if state
|
138
|
+
return uri
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Oauth2Provider
|
2
|
+
class ClientsController < Oauth2Provider::ApplicationController
|
3
|
+
before_filter :_oauth_provider_find_clients
|
4
|
+
before_filter :_oauth_provider_find_client, only: ["show", "edit", "update", "destroy", "block", "unblock"]
|
5
|
+
before_filter :_oauth_provider_normalize_scope, only: ["create", "update"]
|
6
|
+
before_filter :_oauth_provider_admin?, only: ["block", "unblock"]
|
7
|
+
|
8
|
+
def index
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
def new
|
15
|
+
@client = Client.new
|
16
|
+
@client.scope = ["all"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
@client = Client.new(params[:client])
|
21
|
+
@client.created_from = user_url(current_user)
|
22
|
+
@client.uri = @client.base_uri(request)
|
23
|
+
@client.scope_values = Oauth2Provider.normalize_scope(params[:client][:scope].clone)
|
24
|
+
|
25
|
+
if @client.save
|
26
|
+
redirect_to oauth2_provider_engine.oauth2_provider_client_path( @client ), notice: "Resource was successfully created."
|
27
|
+
else
|
28
|
+
render "new"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def edit
|
33
|
+
end
|
34
|
+
|
35
|
+
def update
|
36
|
+
@client.scope = params[:client][:scope]
|
37
|
+
@client.scope_values = Oauth2Provider.normalize_scope(params[:client][:scope].clone)
|
38
|
+
|
39
|
+
if @client.update_attributes(params[:client])
|
40
|
+
flash.now.notice = "Resource was successfully updated."
|
41
|
+
render "show"
|
42
|
+
else
|
43
|
+
render action: "edit"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
@client.destroy
|
49
|
+
redirect_to(clients_url, notice: "Resource was successfully destroyed.")
|
50
|
+
end
|
51
|
+
|
52
|
+
# TODO: this is not REST way
|
53
|
+
def block
|
54
|
+
@client.block!
|
55
|
+
redirect_to oauth2_provider_engine.oauth2_provider_clients_url
|
56
|
+
end
|
57
|
+
|
58
|
+
def unblock
|
59
|
+
@client.unblock!
|
60
|
+
redirect_to oauth2_provider_engine.oauth2_provider_clients_url
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def _oauth_provider_find_clients
|
66
|
+
if current_user.admin?
|
67
|
+
@clients = Oauth2Provider::Client.criteria
|
68
|
+
else
|
69
|
+
@clients = Oauth2Provider::Client.where(created_from: user_url(current_user))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def _oauth_provider_find_client
|
74
|
+
@client = @clients.where(_id: params[:id]).first
|
75
|
+
unless @client
|
76
|
+
redirect_to root_path, alert: "Resource not found."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def _oauth_provider_normalize_scope
|
81
|
+
params[:client][:scope] = params[:client][:scope].split(Oauth2Provider.settings["scope_separator"])
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Oauth2Provider::ScopesController < Oauth2Provider::ApplicationController
|
2
|
+
|
3
|
+
before_filter :_oauth_provider_admin?
|
4
|
+
before_filter :_oauth_provider_find_resource, only: ["show", "edit", "update", "destroy"]
|
5
|
+
after_filter :_oauth_provider_sync_existing_scopes, only: ["update", "destroy"]
|
6
|
+
|
7
|
+
def index
|
8
|
+
@scopes = Oauth2Provider::Scope.all
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
def new
|
15
|
+
@scope = Oauth2Provider::Scope.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
@scope = Oauth2Provider::Scope.new(params[:scope])
|
20
|
+
@scope.uri = @scope.base_uri(request)
|
21
|
+
@scope.values = @scope.normalize(params[:scope][:values])
|
22
|
+
|
23
|
+
if @scope.save
|
24
|
+
redirect_to(oauth2_provider_engine.oauth2_provider_scope_path(@scope), notice: "Resource was successfully created.")
|
25
|
+
else
|
26
|
+
render action: "new"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def edit
|
31
|
+
end
|
32
|
+
|
33
|
+
def update
|
34
|
+
@scope.values = @scope.normalize(params[:scope][:values])
|
35
|
+
|
36
|
+
if @scope.update_attributes(params[:scope])
|
37
|
+
render("show", notice: "Resource was successfully updated.")
|
38
|
+
else
|
39
|
+
render action: "edit"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy
|
44
|
+
@scope.destroy
|
45
|
+
redirect_to(scopes_url, notice: "Resource was successfully destroyed.")
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def _oauth_provider_find_resource
|
52
|
+
@scope = Oauth2Provider::Scope.where(_id: params[:id]).first
|
53
|
+
unless @scope
|
54
|
+
redirect_to root_path, alert: "Resource not found."
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# TODO: put into a background process
|
59
|
+
def _oauth_provider_sync_existing_scopes
|
60
|
+
Oauth2Provider::Client.sync_clients_with_scope(@scope.name)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
class Oauth2Provider::TokenController < Oauth2Provider::ApplicationController
|
2
|
+
include ActionView::Helpers::DateHelper
|
3
|
+
|
4
|
+
skip_before_filter :_oauth_provider_authenticate
|
5
|
+
before_filter :_oauth_provider_json_body
|
6
|
+
|
7
|
+
# authorization code flow
|
8
|
+
before_filter :_oauth_provider_client_where_secret_and_redirect
|
9
|
+
before_filter :_oauth_provider_find_authorization
|
10
|
+
before_filter :_oauth_provider_find_authorization_expired
|
11
|
+
|
12
|
+
# password credential flow
|
13
|
+
before_filter :_oauth_provider_normalize_scope
|
14
|
+
before_filter :_oauth_provider_client_where_secret
|
15
|
+
before_filter :_oauth_provider_check_scope
|
16
|
+
before_filter :_oauth_provider_find_resource_owner
|
17
|
+
|
18
|
+
# refresh token flow
|
19
|
+
before_filter :_oauth_provider_find_refresh_token
|
20
|
+
before_filter :_oauth_provider_find_expired_token
|
21
|
+
before_filter :_oauth_provider_token_blocked?
|
22
|
+
|
23
|
+
before_filter :_oauth_provider_client_blocked?, only: "create" # check if the client is blocked
|
24
|
+
before_filter :_oauth_provider_access_blocked?, only: "create" # check if user has blocked the client
|
25
|
+
|
26
|
+
|
27
|
+
def create
|
28
|
+
# section 4.1.3 - authorization code flow
|
29
|
+
if @body[:grant_type] == "authorization_code"
|
30
|
+
@token = Oauth2Provider::OauthToken.create(client_uri: @client.uri, resource_owner_uri: @authorization.resource_owner_uri, scope: @authorization.scope)
|
31
|
+
@refresh_token = Oauth2Provider::OauthRefreshToken.create(access_token: @token.token)
|
32
|
+
render "/shared/token" and return
|
33
|
+
end
|
34
|
+
|
35
|
+
# section 4.3.1 (password credentials flow)
|
36
|
+
if @body[:grant_type] == "password"
|
37
|
+
@token = Oauth2Provider::OauthToken.create(client_uri: @client.uri, resource_owner_uri: user_url(@resource_owner), scope: @body[:scope])
|
38
|
+
@refresh_token = Oauth2Provider::OauthRefreshToken.create(access_token: @token.token)
|
39
|
+
render "/shared/token" and return
|
40
|
+
end
|
41
|
+
|
42
|
+
# section 6.0 (refresh token)
|
43
|
+
if @body[:grant_type] == "refresh_token"
|
44
|
+
@token = Oauth2Provider::OauthToken.create(client_uri: @expired_token.client_uri, resource_owner_uri: @expired_token.resource_owner_uri, scope: @expired_token.scope)
|
45
|
+
render "/shared/token" and return
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# simulate a logout blocking the token
|
50
|
+
# TODO: refactoring
|
51
|
+
def destroy
|
52
|
+
token = Oauth2Provider::OauthToken.where(token: params[:id]).first
|
53
|
+
if token
|
54
|
+
token.block!
|
55
|
+
return head 200
|
56
|
+
else
|
57
|
+
return head 404
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# filters for section 4.1.3 - authorization code flow
|
65
|
+
def _oauth_provider_client_where_secret_and_redirect
|
66
|
+
if @body[:grant_type] == "authorization_code"
|
67
|
+
@client = Oauth2Provider::Client.where_secret(@body[:client_secret], @body[:client_id]).where(redirect_uri: @body[:redirect_uri]).first
|
68
|
+
message = "notifications.oauth.client.not_found"
|
69
|
+
info = { client_secret: @body[:client_secret], client_id: @body[:client_id], redirect_uri: @body[:redirect_uri] }
|
70
|
+
render_422 message, info unless @client
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def _oauth_provider_find_authorization
|
75
|
+
if @body[:grant_type] == "authorization_code"
|
76
|
+
@authorization = Oauth2Provider::OauthAuthorization.where_code_and_client_uri(@body[:code], @client.uri).first
|
77
|
+
@resource_owner_uri = @authorization.resource_owner_uri if @authorization
|
78
|
+
message = "notifications.oauth.authorization.not_found"
|
79
|
+
info = { code: @body[:code], client_id: @client.uri }
|
80
|
+
render_422 message, info unless @authorization
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def _oauth_provider_find_authorization_expired
|
85
|
+
if @body[:grant_type] == "authorization_code"
|
86
|
+
message = "notifications.oauth.authorization.expired"
|
87
|
+
info = { expired_at: @authorization.expire_at, description: distance_of_time_in_words(@authorization.expire_at, Time.now, true) }
|
88
|
+
render_422 message, info if @authorization.expired?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# filters for section 4.3.1 (password credentials flow)
|
94
|
+
def _oauth_provider_normalize_scope
|
95
|
+
if @body[:grant_type] == "password"
|
96
|
+
@body[:scope] ||= ""
|
97
|
+
@body[:scope] = Oauth2Provider.normalize_scope(@body[:scope])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def _oauth_provider_client_where_secret
|
102
|
+
if @body[:grant_type] == "password" or @body[:grant_type] == "refresh_token"
|
103
|
+
@client = Oauth2Provider::Client.where_secret(@body[:client_secret], @body[:client_id])
|
104
|
+
message = "notifications.oauth.client.not_found"
|
105
|
+
info = { client_secret: @body[:client_secret], client_id: @body[:client_id] }
|
106
|
+
render_422 message, info unless @client.first
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def _oauth_provider_check_scope
|
111
|
+
if @body[:grant_type] == "password"
|
112
|
+
@client = @client.where_scope(@body[:scope]).first
|
113
|
+
message = "notifications.oauth.client.not_authorized"
|
114
|
+
info = { scope: @body[:scope] }
|
115
|
+
render_422 message, info unless @client
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def _oauth_provider_find_resource_owner
|
120
|
+
if @body[:grant_type] == "password"
|
121
|
+
@resource_owner = User.authenticate(@body[:username], @body[:password])
|
122
|
+
@resource_owner_uri = user_url(@resource_owner) if @resource_owner
|
123
|
+
message = "notifications.oauth.resource_owner.not_found"
|
124
|
+
info = { username: @body[:username] }
|
125
|
+
render_422 message, info unless @resource_owner
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# filters for refresh token (section 6.0)
|
131
|
+
def _oauth_provider_find_refresh_token
|
132
|
+
if @body[:grant_type] == "refresh_token"
|
133
|
+
@client = @client.first
|
134
|
+
@refresh_token = Oauth2Provider::OauthRefreshToken.where(refresh_token: @body[:refresh_token]).first
|
135
|
+
message = "notifications.oauth.refresh_token.not_found"
|
136
|
+
info = { refresh_token: @body[:refresh_token] }
|
137
|
+
render_422 message, info unless @refresh_token
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def _oauth_provider_find_expired_token
|
142
|
+
if @body[:grant_type] == "refresh_token"
|
143
|
+
@expired_token = Oauth2Provider::OauthToken.where(token: @refresh_token.access_token).first
|
144
|
+
@resource_owner_uri = @expired_token.resource_owner_uri
|
145
|
+
message = "notifications.oauth.token.not_found"
|
146
|
+
info = { token: @refresh_token.access_token }
|
147
|
+
render_422 message, info unless @refresh_token
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def _oauth_provider_token_blocked?
|
152
|
+
if @body[:grant_type] == "refresh_token"
|
153
|
+
message = "notifications.oauth.token.blocked_token"
|
154
|
+
info = { token: @refresh_token.access_token }
|
155
|
+
render_422 message, info if @expired_token.blocked?
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# shared
|
161
|
+
def _oauth_provider_client_blocked?
|
162
|
+
message = "notifications.oauth.client.blocked"
|
163
|
+
info = { client_id: @body[:client_id] }
|
164
|
+
render_422 message, info if @client.blocked?
|
165
|
+
end
|
166
|
+
|
167
|
+
def _oauth_provider_access_blocked?
|
168
|
+
access = Oauth2Provider::OauthAccess.find_or_create_by(:client_uri => @client.uri, resource_owner_uri: @resource_owner_uri)
|
169
|
+
message = "notifications.oauth.resource_owner.blocked_client"
|
170
|
+
info = { client_id: @body[:client_id] }
|
171
|
+
render_422 message, info if access.blocked
|
172
|
+
end
|
173
|
+
|
174
|
+
# visualization
|
175
|
+
def render_404(message, info)
|
176
|
+
@message = I18n.t message
|
177
|
+
@info = info.to_s
|
178
|
+
render "shared/404", status: 404 and return
|
179
|
+
end
|
180
|
+
|
181
|
+
def render_422(message, info)
|
182
|
+
@message = I18n.t message
|
183
|
+
@info = info.to_json
|
184
|
+
render "shared/422", status: 422 and return
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|