oauth2_provider_engine 0.0.1
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/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
|