doorkeeper 4.3.2 → 5.0.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.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +16 -0
  4. data/.rubocop.yml +4 -0
  5. data/.travis.yml +2 -0
  6. data/Appraisals +2 -2
  7. data/Gemfile +1 -1
  8. data/NEWS.md +70 -0
  9. data/README.md +92 -9
  10. data/Rakefile +6 -0
  11. data/UPGRADE.md +2 -0
  12. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  13. data/app/controllers/doorkeeper/application_controller.rb +4 -3
  14. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  15. data/app/controllers/doorkeeper/applications_controller.rb +43 -22
  16. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  17. data/app/controllers/doorkeeper/authorized_applications_controller.rb +19 -2
  18. data/app/controllers/doorkeeper/tokens_controller.rb +11 -16
  19. data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
  20. data/app/validators/redirect_uri_validator.rb +3 -2
  21. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  22. data/app/views/doorkeeper/applications/_form.html.erb +31 -19
  23. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  24. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  25. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  26. data/app/views/doorkeeper/applications/show.html.erb +8 -5
  27. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  28. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  29. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  30. data/config/locales/en.yml +16 -1
  31. data/doorkeeper.gemspec +18 -18
  32. data/gemfiles/rails_5_2.gemfile +1 -1
  33. data/gemfiles/rails_master.gemfile +4 -1
  34. data/lib/doorkeeper/config.rb +77 -27
  35. data/lib/doorkeeper/engine.rb +4 -0
  36. data/lib/doorkeeper/errors.rb +2 -5
  37. data/lib/doorkeeper/grape/helpers.rb +1 -1
  38. data/lib/doorkeeper/helpers/controller.rb +7 -2
  39. data/lib/doorkeeper/models/access_grant_mixin.rb +71 -0
  40. data/lib/doorkeeper/models/access_token_mixin.rb +40 -23
  41. data/lib/doorkeeper/models/application_mixin.rb +8 -1
  42. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  43. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  44. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  45. data/lib/doorkeeper/oauth/authorization/token.rb +36 -14
  46. data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
  47. data/lib/doorkeeper/oauth/base_request.rb +20 -9
  48. data/lib/doorkeeper/oauth/client/credentials.rb +4 -2
  49. data/lib/doorkeeper/oauth/client.rb +0 -2
  50. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
  51. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -3
  52. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -6
  53. data/lib/doorkeeper/oauth/client_credentials_request.rb +0 -4
  54. data/lib/doorkeeper/oauth/error_response.rb +11 -3
  55. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  56. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -0
  57. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
  58. data/lib/doorkeeper/oauth/pre_authorization.rb +45 -13
  59. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
  60. data/lib/doorkeeper/oauth/scopes.rb +1 -1
  61. data/lib/doorkeeper/oauth/token.rb +5 -2
  62. data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
  63. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  64. data/lib/doorkeeper/oauth.rb +13 -0
  65. data/lib/doorkeeper/orm/active_record/application.rb +25 -0
  66. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  67. data/lib/doorkeeper/orm/active_record.rb +2 -0
  68. data/lib/doorkeeper/rails/helpers.rb +2 -4
  69. data/lib/doorkeeper/rails/routes.rb +13 -1
  70. data/lib/doorkeeper/rake/db.rake +40 -0
  71. data/lib/doorkeeper/rake/setup.rake +6 -0
  72. data/lib/doorkeeper/rake.rb +14 -0
  73. data/lib/doorkeeper/request/authorization_code.rb +0 -2
  74. data/lib/doorkeeper/request/client_credentials.rb +0 -2
  75. data/lib/doorkeeper/request/code.rb +0 -2
  76. data/lib/doorkeeper/request/password.rb +1 -13
  77. data/lib/doorkeeper/request/refresh_token.rb +0 -2
  78. data/lib/doorkeeper/request/token.rb +0 -2
  79. data/lib/doorkeeper/request.rb +28 -35
  80. data/lib/doorkeeper/version.rb +5 -4
  81. data/lib/doorkeeper.rb +19 -17
  82. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  83. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  84. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  85. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  86. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  87. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  88. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  89. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  90. data/lib/generators/doorkeeper/templates/initializer.rb +76 -11
  91. data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -0
  92. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  93. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  94. data/spec/controllers/applications_controller_spec.rb +126 -13
  95. data/spec/controllers/authorizations_controller_spec.rb +279 -17
  96. data/spec/controllers/protected_resources_controller_spec.rb +16 -16
  97. data/spec/controllers/token_info_controller_spec.rb +4 -12
  98. data/spec/controllers/tokens_controller_spec.rb +72 -22
  99. data/spec/dummy/app/assets/config/manifest.js +2 -0
  100. data/spec/dummy/config/environments/test.rb +4 -5
  101. data/spec/dummy/config/initializers/doorkeeper.rb +11 -1
  102. data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
  103. data/spec/dummy/config/routes.rb +3 -42
  104. data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
  105. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
  106. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -1
  107. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +3 -1
  108. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +3 -1
  109. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  110. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +13 -0
  111. data/spec/dummy/db/schema.rb +38 -37
  112. data/spec/generators/application_owner_generator_spec.rb +1 -1
  113. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  114. data/spec/generators/install_generator_spec.rb +1 -1
  115. data/spec/generators/migration_generator_spec.rb +1 -1
  116. data/spec/generators/pkce_generator_spec.rb +43 -0
  117. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  118. data/spec/generators/views_generator_spec.rb +1 -1
  119. data/spec/grape/grape_integration_spec.rb +1 -1
  120. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  121. data/spec/lib/config_spec.rb +88 -14
  122. data/spec/lib/doorkeeper_spec.rb +1 -126
  123. data/spec/lib/models/expirable_spec.rb +0 -3
  124. data/spec/lib/models/revocable_spec.rb +0 -2
  125. data/spec/lib/models/scopes_spec.rb +0 -4
  126. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  127. data/spec/lib/oauth/authorization_code_request_spec.rb +24 -2
  128. data/spec/lib/oauth/base_request_spec.rb +40 -2
  129. data/spec/lib/oauth/base_response_spec.rb +1 -1
  130. data/spec/lib/oauth/client/credentials_spec.rb +5 -5
  131. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  132. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  133. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  134. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  135. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  136. data/spec/lib/oauth/client_spec.rb +0 -3
  137. data/spec/lib/oauth/code_request_spec.rb +4 -2
  138. data/spec/lib/oauth/error_response_spec.rb +0 -3
  139. data/spec/lib/oauth/error_spec.rb +0 -2
  140. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  141. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  142. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  143. data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -2
  144. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  145. data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
  146. data/spec/lib/oauth/pre_authorization_spec.rb +40 -6
  147. data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
  148. data/spec/lib/oauth/scopes_spec.rb +0 -3
  149. data/spec/lib/oauth/token_request_spec.rb +4 -5
  150. data/spec/lib/oauth/token_response_spec.rb +0 -1
  151. data/spec/lib/oauth/token_spec.rb +37 -14
  152. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  153. data/spec/lib/request/strategy_spec.rb +0 -1
  154. data/spec/lib/server_spec.rb +1 -1
  155. data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
  156. data/spec/models/doorkeeper/access_token_spec.rb +66 -22
  157. data/spec/models/doorkeeper/application_spec.rb +64 -6
  158. data/spec/requests/applications/applications_request_spec.rb +134 -1
  159. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  160. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  161. data/spec/requests/endpoints/token_spec.rb +7 -5
  162. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
  163. data/spec/requests/flows/authorization_code_spec.rb +198 -2
  164. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  165. data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
  166. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  167. data/spec/requests/flows/password_spec.rb +120 -23
  168. data/spec/requests/flows/refresh_token_spec.rb +2 -2
  169. data/spec/requests/flows/revoke_token_spec.rb +11 -11
  170. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  171. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  172. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  173. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  174. data/spec/routing/default_routes_spec.rb +2 -2
  175. data/spec/routing/scoped_routes_spec.rb +16 -2
  176. data/spec/spec_helper.rb +54 -3
  177. data/spec/spec_helper_integration.rb +2 -74
  178. data/spec/support/doorkeeper_rspec.rb +19 -0
  179. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  180. data/spec/support/helpers/request_spec_helper.rb +10 -2
  181. data/spec/support/helpers/url_helper.rb +7 -3
  182. data/spec/support/http_method_shim.rb +12 -16
  183. data/spec/validators/redirect_uri_validator_spec.rb +7 -1
  184. data/spec/version/version_spec.rb +3 -3
  185. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  186. metadata +36 -10
  187. data/spec/controllers/application_metal_controller.rb +0 -10
  188. /data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
@@ -4,56 +4,103 @@ Doorkeeper.configure do
4
4
 
5
5
  # This block will be called to check whether the resource owner is authenticated or not.
6
6
  resource_owner_authenticator do
7
- fail "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
7
+ raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
8
8
  # Put your resource owner authentication logic here.
9
9
  # Example implementation:
10
10
  # User.find_by_id(session[:user_id]) || redirect_to(new_user_session_url)
11
11
  end
12
12
 
13
- # If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
13
+ # If you didn't skip applications controller from Doorkeeper routes in your application routes.rb
14
+ # file then you need to declare this block in order to restrict access to the web interface for
15
+ # adding oauth authorized applications. In other case it will return 403 Forbidden response
16
+ # every time somebody will try to access the admin web interface.
17
+ #
14
18
  # admin_authenticator do
15
19
  # # Put your admin authentication logic here.
16
20
  # # Example implementation:
17
- # Admin.find_by_id(session[:admin_id]) || redirect_to(new_admin_session_url)
21
+ #
22
+ # if current_user
23
+ # head :forbidden unless current_user.admin?
24
+ # else
25
+ # redirect_to sign_in_url
26
+ # end
18
27
  # end
19
28
 
29
+ # If you are planning to use Doorkeeper in Rails 5 API-only application, then you might
30
+ # want to use API mode that will skip all the views management and change the way how
31
+ # Doorkeeper responds to a requests.
32
+ #
33
+ # api_only
34
+
35
+ # Enforce token request content type to application/x-www-form-urlencoded.
36
+ # It is not enabled by default to not break prior versions of the gem.
37
+ #
38
+ # enforce_content_type
39
+
20
40
  # Authorization Code expiration time (default 10 minutes).
41
+ #
21
42
  # authorization_code_expires_in 10.minutes
22
43
 
23
44
  # Access token expiration time (default 2 hours).
24
45
  # If you want to disable expiration, set this to nil.
46
+ #
25
47
  # access_token_expires_in 2.hours
26
48
 
27
- # Assign a custom TTL for implicit grants.
28
- # custom_access_token_expires_in do |oauth_client|
29
- # oauth_client.application.additional_settings.implicit_oauth_expiration
49
+ # Assign custom TTL for access tokens. Will be used instead of access_token_expires_in
50
+ # option if defined. `context` has the following properties available
51
+ #
52
+ # `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
53
+ # `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
54
+ # `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
55
+ #
56
+ # custom_access_token_expires_in do |context|
57
+ # context.client.application.additional_settings.implicit_oauth_expiration
30
58
  # end
31
59
 
32
60
  # Use a custom class for generating the access token.
33
- # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
61
+ # See https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
62
+ #
34
63
  # access_token_generator '::Doorkeeper::JWT'
35
64
 
36
65
  # The controller Doorkeeper::ApplicationController inherits from.
37
66
  # Defaults to ActionController::Base.
38
- # https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller
67
+ # See https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller
68
+ #
39
69
  # base_controller 'ApplicationController'
40
70
 
41
71
  # Reuse access token for the same resource owner within an application (disabled by default)
42
72
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
73
+ #
43
74
  # reuse_access_token
44
75
 
45
- # Issue access tokens with refresh token (disabled by default)
76
+ # Issue access tokens with refresh token (disabled by default), you may also
77
+ # pass a block which accepts `context` to customize when to give a refresh
78
+ # token or not. Similar to `custom_access_token_expires_in`, `context` has
79
+ # the properties:
80
+ #
81
+ # `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
82
+ # `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
83
+ # `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
84
+ #
46
85
  # use_refresh_token
47
86
 
87
+ # Forbids creating/updating applications with arbitrary scopes that are
88
+ # not in configuration, i.e. `default_scopes` or `optional_scopes`.
89
+ # (disabled by default)
90
+ #
91
+ # enforce_configured_scopes
92
+
48
93
  # Provide support for an owner to be assigned to each registered application (disabled by default)
49
94
  # Optional parameter confirmation: true (default false) if you want to enforce ownership of
50
95
  # a registered application
51
96
  # Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
97
+ #
52
98
  # enable_application_owner confirmation: false
53
99
 
54
100
  # Define access token scopes for your provider
55
101
  # For more information go to
56
102
  # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
103
+ #
57
104
  # default_scopes :public
58
105
  # optional_scopes :write, :update
59
106
 
@@ -62,6 +109,7 @@ Doorkeeper.configure do
62
109
  # falls back to the `:client_id` and `:client_secret` params from the `params` object.
63
110
  # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated
64
111
  # for more information on customization
112
+ #
65
113
  # client_credentials :from_basic, :from_params
66
114
 
67
115
  # Change the way access token is authenticated from the request object.
@@ -69,6 +117,7 @@ Doorkeeper.configure do
69
117
  # falls back to the `:access_token` or `:bearer_token` params from the `params` object.
70
118
  # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated
71
119
  # for more information on customization
120
+ #
72
121
  # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
73
122
 
74
123
  # Change the native redirect uri for client apps
@@ -90,8 +139,8 @@ Doorkeeper.configure do
90
139
  #
91
140
  # force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
92
141
 
93
- # Specify what redirect URI's you want to block during creation. Any redirect
94
- # URI is whitelisted by default.
142
+ # Specify what redirect URI's you want to block during Application creation.
143
+ # Any redirect URI is whitelisted by default.
95
144
  #
96
145
  # You can use this option in order to forbid URI's with 'javascript' scheme
97
146
  # for example.
@@ -127,13 +176,29 @@ Doorkeeper.configure do
127
176
  # puts "AFTER HOOK FIRED! #{request}, #{response}"
128
177
  # end
129
178
 
179
+ # Hook into Authorization flow in order to implement Single Sign Out
180
+ # or add ny other functionality.
181
+ #
182
+ # before_successful_authorization do |controller|
183
+ # Rails.logger.info(params.inspect)
184
+ # end
185
+ #
186
+ # after_successful_authorization do |controller|
187
+ # controller.session[:logout_urls] <<
188
+ # Doorkeeper::Application
189
+ # .find_by(controller.request.params.slice(:redirect_uri))
190
+ # .logout_uri
191
+ # end
192
+
130
193
  # Under some circumstances you might want to have applications auto-approved,
131
194
  # so that the user skips the authorization step.
132
195
  # For example if dealing with a trusted application.
196
+ #
133
197
  # skip_authorization do |resource_owner, client|
134
198
  # client.superapp? or resource_owner.admin?
135
199
  # end
136
200
 
137
201
  # WWW-Authenticate Realm (default "Doorkeeper").
202
+ #
138
203
  # realm "Doorkeeper"
139
204
  end
@@ -6,6 +6,7 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
6
6
  t.string :secret, null: false
7
7
  t.text :redirect_uri, null: false
8
8
  t.string :scopes, null: false, default: ''
9
+ t.boolean :confidential, null: false, default: true
9
10
  t.timestamps null: false
10
11
  end
11
12
 
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Generators
3
5
  class ViewsGenerator < ::Rails::Generators::Base
4
- source_root File.expand_path('../../../../app/views', __FILE__)
6
+ source_root File.expand_path('../../../app/views', __dir__)
5
7
 
6
8
  desc 'Copies default Doorkeeper views and layouts to your application.'
7
9
 
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper_integration'
4
+
5
+ describe Doorkeeper::ApplicationMetalController do
6
+ controller(Doorkeeper::ApplicationMetalController) do
7
+ def index
8
+ render json: {}, status: 200
9
+ end
10
+ end
11
+
12
+ it "lazy run hooks" do
13
+ i = 0
14
+ ActiveSupport.on_load(:doorkeeper_metal_controller) { i += 1 }
15
+
16
+ expect(i).to eq 1
17
+ end
18
+
19
+ describe 'enforce_content_type' do
20
+ before { allow(Doorkeeper.configuration).to receive(:enforce_content_type).and_return(flag) }
21
+
22
+ context 'enabled' do
23
+ let(:flag) { true }
24
+
25
+ it '200 for the correct media type' do
26
+ get :index, params: {}, as: :url_encoded_form
27
+ expect(response).to have_http_status 200
28
+ end
29
+
30
+ it 'returns a 415 for an incorrect media type' do
31
+ get :index, as: :json
32
+ expect(response).to have_http_status 415
33
+ end
34
+ end
35
+
36
+ context 'disabled' do
37
+ let(:flag) { false }
38
+
39
+ it 'returns a 200 for the correct media type' do
40
+ get :index, as: :url_encoded_form
41
+ expect(response).to have_http_status 200
42
+ end
43
+
44
+ it 'returns a 200 for an incorrect media type' do
45
+ get :index, as: :json
46
+ expect(response).to have_http_status 200
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,7 +1,99 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper
4
4
  describe ApplicationsController do
5
+ context 'JSON API' do
6
+ render_views
7
+
8
+ before do
9
+ allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
10
+ allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
11
+ end
12
+
13
+ it 'creates an application' do
14
+ expect do
15
+ post :create, params: {
16
+ doorkeeper_application: {
17
+ name: 'Example',
18
+ redirect_uri: 'https://example.com'
19
+ }, format: :json
20
+ }
21
+ end.to change { Doorkeeper::Application.count }
22
+
23
+ expect(response).to be_successful
24
+
25
+ expect(json_response).to include('id', 'name', 'uid', 'secret', 'redirect_uri', 'scopes')
26
+
27
+ expect(json_response['name']).to eq('Example')
28
+ expect(json_response['redirect_uri']).to eq('https://example.com')
29
+ end
30
+
31
+ it 'returns validation errors on wrong create params' do
32
+ expect do
33
+ post :create, params: {
34
+ doorkeeper_application: {
35
+ name: 'Example'
36
+ }, format: :json
37
+ }
38
+ end.not_to change { Doorkeeper::Application.count }
39
+
40
+ expect(response).to have_http_status(422)
41
+
42
+ expect(json_response).to include('errors')
43
+ end
44
+
45
+ it 'returns application info' do
46
+ application = FactoryBot.create(:application, name: 'Change me')
47
+
48
+ get :show, params: { id: application.id, format: :json }
49
+
50
+ expect(response).to be_successful
51
+
52
+ expect(json_response).to include('id', 'name', 'uid', 'secret', 'redirect_uri', 'scopes')
53
+ end
54
+
55
+ it 'updates application' do
56
+ application = FactoryBot.create(:application, name: 'Change me')
57
+
58
+ put :update, params: {
59
+ id: application.id,
60
+ doorkeeper_application: {
61
+ name: 'Example App',
62
+ redirect_uri: 'https://example.com'
63
+ }, format: :json
64
+ }
65
+
66
+ expect(application.reload.name).to eq 'Example App'
67
+
68
+ expect(json_response).to include('id', 'name', 'uid', 'secret', 'redirect_uri', 'scopes')
69
+ end
70
+
71
+ it 'returns validation errors on wrong update params' do
72
+ application = FactoryBot.create(:application, name: 'Change me')
73
+
74
+ put :update, params: {
75
+ id: application.id,
76
+ doorkeeper_application: {
77
+ name: 'Example App',
78
+ redirect_uri: 'localhost:3000'
79
+ }, format: :json
80
+ }
81
+
82
+ expect(response).to have_http_status(422)
83
+
84
+ expect(json_response).to include('errors')
85
+ end
86
+
87
+ it 'destroys an application' do
88
+ application = FactoryBot.create(:application)
89
+
90
+ delete :destroy, params: { id: application.id, format: :json }
91
+
92
+ expect(response).to have_http_status(204)
93
+ expect(Application.count).to be_zero
94
+ end
95
+ end
96
+
5
97
  context 'when admin is not authenticated' do
6
98
  before do
7
99
  allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(proc do
@@ -16,9 +108,13 @@ module Doorkeeper
16
108
 
17
109
  it 'does not create application' do
18
110
  expect do
19
- post :create, doorkeeper_application: {
20
- name: 'Example',
21
- redirect_uri: 'https://example.com' }
111
+ post :create,
112
+ params: {
113
+ doorkeeper_application: {
114
+ name: 'Example',
115
+ redirect_uri: 'https://example.com'
116
+ }
117
+ }
22
118
  end.not_to change { Doorkeeper::Application.count }
23
119
  end
24
120
  end
@@ -34,34 +130,51 @@ module Doorkeeper
34
130
  first_application = FactoryBot.create(:application)
35
131
  second_application = FactoryBot.create(:application)
36
132
  expect(Doorkeeper::Application).to receive(:ordered_by).and_call_original
133
+
37
134
  get :index
135
+
38
136
  expect(response.body).to have_selector("tbody tr:first-child#application_#{first_application.id}")
39
137
  expect(response.body).to have_selector("tbody tr:last-child#application_#{second_application.id}")
40
138
  end
41
139
 
42
140
  it 'creates application' do
43
141
  expect do
44
- post :create, doorkeeper_application: {
45
- name: 'Example',
46
- redirect_uri: 'https://example.com' }
142
+ post :create,
143
+ params: {
144
+ doorkeeper_application: {
145
+ name: 'Example',
146
+ redirect_uri: 'https://example.com'
147
+ }
148
+ }
47
149
  end.to change { Doorkeeper::Application.count }.by(1)
150
+
48
151
  expect(response).to be_redirect
49
152
  end
50
153
 
51
154
  it 'does not allow mass assignment of uid or secret' do
52
155
  application = FactoryBot.create(:application)
53
- put :update, id: application.id, doorkeeper_application: {
54
- uid: '1A2B3C4D',
55
- secret: '1A2B3C4D' }
156
+ put :update,
157
+ params: {
158
+ id: application.id,
159
+ doorkeeper_application: {
160
+ uid: '1A2B3C4D',
161
+ secret: '1A2B3C4D'
162
+ }
163
+ }
56
164
 
57
165
  expect(application.reload.uid).not_to eq '1A2B3C4D'
58
166
  end
59
167
 
60
168
  it 'updates application' do
61
169
  application = FactoryBot.create(:application)
62
- put :update, id: application.id, doorkeeper_application: {
63
- name: 'Example',
64
- redirect_uri: 'https://example.com' }
170
+ put :update,
171
+ params: {
172
+ id: application.id, doorkeeper_application: {
173
+ name: 'Example',
174
+ redirect_uri: 'https://example.com'
175
+ }
176
+ }
177
+
65
178
  expect(application.reload.name).to eq 'Example'
66
179
  end
67
180
  end