doorkeeper 5.0.0 → 5.1.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.
- checksums.yaml +5 -5
- data/.hound.yml +2 -1
- data/.rubocop.yml +37 -4
- data/.travis.yml +16 -21
- data/Appraisals +29 -7
- data/Dangerfile +67 -0
- data/Gemfile +19 -5
- data/NEWS.md +107 -10
- data/README.md +75 -470
- data/Rakefile +10 -8
- data/app/controllers/doorkeeper/application_controller.rb +3 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +4 -13
- data/app/controllers/doorkeeper/applications_controller.rb +21 -7
- data/app/controllers/doorkeeper/authorizations_controller.rb +3 -3
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -0
- data/app/controllers/doorkeeper/token_info_controller.rb +4 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +13 -11
- data/app/helpers/doorkeeper/dashboard_helper.rb +3 -1
- data/app/validators/redirect_uri_validator.rb +7 -2
- data/app/views/doorkeeper/applications/_form.html.erb +6 -0
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
- data/bin/console +16 -0
- data/config/locales/en.yml +1 -0
- data/doorkeeper.gemspec +28 -24
- data/gemfiles/rails_5_0.gemfile +9 -4
- data/gemfiles/rails_5_1.gemfile +9 -4
- data/gemfiles/rails_5_2.gemfile +10 -5
- data/gemfiles/rails_6_0.gemfile +17 -0
- data/gemfiles/rails_master.gemfile +9 -9
- data/lib/doorkeeper/config/option.rb +64 -0
- data/lib/doorkeeper/config.rb +197 -76
- data/lib/doorkeeper/engine.rb +3 -1
- data/lib/doorkeeper/errors.rb +17 -0
- data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
- data/lib/doorkeeper/grape/helpers.rb +5 -3
- data/lib/doorkeeper/helpers/controller.rb +5 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +25 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +68 -22
- data/lib/doorkeeper/models/application_mixin.rb +45 -1
- data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +6 -2
- data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +3 -6
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +4 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +7 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +4 -2
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +14 -7
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +3 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +8 -4
- data/lib/doorkeeper/oauth/base_request.rb +2 -0
- data/lib/doorkeeper/oauth/base_response.rb +2 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -0
- data/lib/doorkeeper/oauth/client.rb +3 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +7 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +3 -1
- data/lib/doorkeeper/oauth/code_request.rb +2 -0
- data/lib/doorkeeper/oauth/code_response.rb +4 -2
- data/lib/doorkeeper/oauth/error.rb +2 -0
- data/lib/doorkeeper/oauth/error_response.rb +20 -6
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +15 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +22 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +13 -5
- data/lib/doorkeeper/oauth/refresh_token_request.rb +15 -4
- data/lib/doorkeeper/oauth/scopes.rb +7 -3
- data/lib/doorkeeper/oauth/token.rb +4 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +76 -8
- data/lib/doorkeeper/oauth/token_request.rb +2 -0
- data/lib/doorkeeper/oauth/token_response.rb +11 -9
- data/lib/doorkeeper/oauth.rb +5 -5
- data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
- data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
- data/lib/doorkeeper/orm/active_record/application.rb +26 -7
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
- data/lib/doorkeeper/orm/active_record.rb +8 -6
- data/lib/doorkeeper/rails/helpers.rb +5 -1
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
- data/lib/doorkeeper/rails/routes.rb +19 -12
- data/lib/doorkeeper/rake/db.rake +17 -17
- data/lib/doorkeeper/rake.rb +1 -1
- data/lib/doorkeeper/request/authorization_code.rb +2 -0
- data/lib/doorkeeper/request/client_credentials.rb +2 -0
- data/lib/doorkeeper/request/code.rb +2 -0
- data/lib/doorkeeper/request/password.rb +2 -0
- data/lib/doorkeeper/request/refresh_token.rb +2 -0
- data/lib/doorkeeper/request/strategy.rb +2 -0
- data/lib/doorkeeper/request/token.rb +2 -0
- data/lib/doorkeeper/request.rb +3 -1
- data/lib/doorkeeper/secret_storing/base.rb +64 -0
- data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
- data/lib/doorkeeper/secret_storing/plain.rb +33 -0
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
- data/lib/doorkeeper/server.rb +2 -0
- data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
- data/lib/doorkeeper/validations.rb +2 -0
- data/lib/doorkeeper/version.rb +4 -2
- data/lib/doorkeeper.rb +69 -59
- data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
- data/lib/generators/doorkeeper/install_generator.rb +11 -9
- data/lib/generators/doorkeeper/migration_generator.rb +9 -9
- data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
- data/lib/generators/doorkeeper/templates/initializer.rb +138 -13
- data/lib/generators/doorkeeper/templates/migration.rb.erb +17 -10
- data/lib/generators/doorkeeper/views_generator.rb +6 -4
- data/spec/controllers/application_metal_controller_spec.rb +24 -10
- data/spec/controllers/applications_controller_spec.rb +76 -78
- data/spec/controllers/authorizations_controller_spec.rb +189 -142
- data/spec/controllers/protected_resources_controller_spec.rb +111 -67
- data/spec/controllers/token_info_controller_spec.rb +14 -12
- data/spec/controllers/tokens_controller_spec.rb +170 -112
- data/spec/dummy/Rakefile +3 -1
- data/spec/dummy/app/controllers/application_controller.rb +3 -1
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +3 -1
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/controllers/home_controller.rb +6 -5
- data/spec/dummy/app/controllers/metal_controller.rb +2 -0
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/config/application.rb +26 -2
- data/spec/dummy/config/boot.rb +2 -4
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +4 -2
- data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +7 -3
- data/spec/dummy/config/initializers/secret_token.rb +3 -1
- data/spec/dummy/config/initializers/session_store.rb +3 -1
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/spec/dummy/config.ru +3 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +20 -13
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/script/rails +7 -4
- data/spec/factories.rb +11 -9
- data/spec/generators/application_owner_generator_spec.rb +13 -26
- data/spec/generators/confidential_applications_generator_spec.rb +12 -28
- data/spec/generators/install_generator_spec.rb +19 -14
- data/spec/generators/migration_generator_spec.rb +13 -26
- data/spec/generators/pkce_generator_spec.rb +11 -26
- data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
- data/spec/generators/templates/routes.rb +2 -1
- data/spec/generators/views_generator_spec.rb +14 -12
- data/spec/grape/grape_integration_spec.rb +35 -33
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
- data/spec/lib/config_spec.rb +290 -104
- data/spec/lib/doorkeeper_spec.rb +8 -6
- data/spec/lib/models/expirable_spec.rb +22 -8
- data/spec/lib/models/reusable_spec.rb +40 -0
- data/spec/lib/models/revocable_spec.rb +8 -6
- data/spec/lib/models/scopes_spec.rb +27 -13
- data/spec/lib/models/secret_storable_spec.rb +135 -0
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
- data/spec/lib/oauth/authorization_code_request_spec.rb +43 -17
- data/spec/lib/oauth/base_request_spec.rb +24 -12
- data/spec/lib/oauth/base_response_spec.rb +3 -1
- data/spec/lib/oauth/client/credentials_spec.rb +26 -24
- data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -20
- data/spec/lib/oauth/client_credentials/validation_spec.rb +21 -15
- data/spec/lib/oauth/client_credentials_integration_spec.rb +8 -6
- data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
- data/spec/lib/oauth/client_spec.rb +15 -13
- data/spec/lib/oauth/code_request_spec.rb +10 -8
- data/spec/lib/oauth/code_response_spec.rb +9 -7
- data/spec/lib/oauth/error_response_spec.rb +19 -11
- data/spec/lib/oauth/error_spec.rb +4 -2
- data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +68 -31
- data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +124 -93
- data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +95 -34
- data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
- data/spec/lib/oauth/refresh_token_request_spec.rb +46 -39
- data/spec/lib/oauth/scopes_spec.rb +63 -61
- data/spec/lib/oauth/token_request_spec.rb +80 -25
- data/spec/lib/oauth/token_response_spec.rb +40 -38
- data/spec/lib/oauth/token_spec.rb +64 -45
- data/spec/lib/request/strategy_spec.rb +3 -1
- data/spec/lib/secret_storing/base_spec.rb +60 -0
- data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
- data/spec/lib/secret_storing/plain_spec.rb +44 -0
- data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
- data/spec/lib/server_spec.rb +20 -18
- data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +28 -18
- data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
- data/spec/models/doorkeeper/access_token_spec.rb +212 -83
- data/spec/models/doorkeeper/application_spec.rb +146 -49
- data/spec/requests/applications/applications_request_spec.rb +100 -68
- data/spec/requests/applications/authorized_applications_spec.rb +20 -18
- data/spec/requests/endpoints/authorization_spec.rb +27 -25
- data/spec/requests/endpoints/token_spec.rb +38 -36
- data/spec/requests/flows/authorization_code_errors_spec.rb +27 -25
- data/spec/requests/flows/authorization_code_spec.rb +260 -158
- data/spec/requests/flows/client_credentials_spec.rb +54 -52
- data/spec/requests/flows/implicit_grant_errors_spec.rb +11 -9
- data/spec/requests/flows/implicit_grant_spec.rb +27 -25
- data/spec/requests/flows/password_spec.rb +64 -56
- data/spec/requests/flows/refresh_token_spec.rb +91 -32
- data/spec/requests/flows/revoke_token_spec.rb +49 -63
- data/spec/requests/flows/skip_authorization_spec.rb +23 -21
- data/spec/requests/protected_resources/metal_spec.rb +7 -5
- data/spec/requests/protected_resources/private_api_spec.rb +37 -35
- data/spec/routing/custom_controller_routes_spec.rb +71 -65
- data/spec/routing/default_routes_spec.rb +22 -20
- data/spec/routing/scoped_routes_spec.rb +20 -18
- data/spec/spec_helper.rb +15 -13
- data/spec/spec_helper_integration.rb +3 -1
- data/spec/support/dependencies/factory_bot.rb +3 -1
- data/spec/support/doorkeeper_rspec.rb +5 -2
- data/spec/support/helpers/access_token_request_helper.rb +3 -1
- data/spec/support/helpers/authorization_request_helper.rb +4 -2
- data/spec/support/helpers/config_helper.rb +2 -0
- data/spec/support/helpers/model_helper.rb +11 -5
- data/spec/support/helpers/request_spec_helper.rb +5 -3
- data/spec/support/helpers/url_helper.rb +20 -18
- data/spec/support/http_method_shim.rb +4 -9
- data/spec/support/orm/active_record.rb +3 -1
- data/spec/support/shared/controllers_shared_context.rb +68 -10
- data/spec/support/shared/hashing_shared_context.rb +36 -0
- data/spec/support/shared/models_shared_examples.rb +12 -10
- data/spec/validators/redirect_uri_validator_spec.rb +76 -47
- data/spec/version/version_spec.rb +7 -5
- metadata +70 -21
- data/gemfiles/rails_4_2.gemfile +0 -13
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/active_record"
|
|
5
5
|
|
|
6
6
|
module Doorkeeper
|
|
7
|
+
# Generates migration to add previous refresh token column to the
|
|
8
|
+
# database for Doorkeeper tables.
|
|
9
|
+
#
|
|
7
10
|
class PreviousRefreshTokenGenerator < ::Rails::Generators::Base
|
|
8
11
|
include ::Rails::Generators::Migration
|
|
9
|
-
source_root File.expand_path(
|
|
10
|
-
desc
|
|
12
|
+
source_root File.expand_path("templates", __dir__)
|
|
13
|
+
desc "Support revoke refresh token on access token use"
|
|
11
14
|
|
|
12
15
|
def self.next_migration_number(path)
|
|
13
16
|
ActiveRecord::Generators::Base.next_migration_number(path)
|
|
@@ -16,8 +19,8 @@ module Doorkeeper
|
|
|
16
19
|
def previous_refresh_token
|
|
17
20
|
if no_previous_refresh_token_column?
|
|
18
21
|
migration_template(
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
"add_previous_refresh_token_to_access_tokens.rb.erb",
|
|
23
|
+
"db/migrate/add_previous_refresh_token_to_access_tokens.rb"
|
|
21
24
|
)
|
|
22
25
|
end
|
|
23
26
|
end
|
|
@@ -25,9 +28,7 @@ module Doorkeeper
|
|
|
25
28
|
private
|
|
26
29
|
|
|
27
30
|
def migration_version
|
|
28
|
-
|
|
29
|
-
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
|
30
|
-
end
|
|
31
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def no_previous_refresh_token_column?
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
Doorkeeper.configure do
|
|
2
4
|
# Change the ORM that doorkeeper will use (needs plugins)
|
|
3
5
|
orm :active_record
|
|
@@ -47,7 +49,12 @@ Doorkeeper.configure do
|
|
|
47
49
|
# access_token_expires_in 2.hours
|
|
48
50
|
|
|
49
51
|
# Assign custom TTL for access tokens. Will be used instead of access_token_expires_in
|
|
50
|
-
# option if defined. `
|
|
52
|
+
# option if defined. In case the block returns `nil` value Doorkeeper fallbacks to
|
|
53
|
+
# `access_token_expires_in` configuration option value. If you really need to issue a
|
|
54
|
+
# non-expiring access token (which is not recommended) then you need to return
|
|
55
|
+
# Float::INFINITY from this block.
|
|
56
|
+
#
|
|
57
|
+
# `context` has the following properties available:
|
|
51
58
|
#
|
|
52
59
|
# `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
|
|
53
60
|
# `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
|
|
@@ -64,15 +71,74 @@ Doorkeeper.configure do
|
|
|
64
71
|
|
|
65
72
|
# The controller Doorkeeper::ApplicationController inherits from.
|
|
66
73
|
# Defaults to ActionController::Base.
|
|
67
|
-
# See https://
|
|
74
|
+
# See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-base-controller
|
|
68
75
|
#
|
|
69
76
|
# base_controller 'ApplicationController'
|
|
70
77
|
|
|
71
|
-
# Reuse access token for the same resource owner within an application (disabled by default)
|
|
78
|
+
# Reuse access token for the same resource owner within an application (disabled by default).
|
|
79
|
+
#
|
|
80
|
+
# This option protects your application from creating new tokens before old valid one becomes
|
|
81
|
+
# expired so your database doesn't bloat. Keep in mind that when this option is `on` Doorkeeper
|
|
82
|
+
# doesn't updates existing token expiration time, it will create a new token instead.
|
|
72
83
|
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
|
|
73
84
|
#
|
|
85
|
+
# You can not enable this option together with +hash_token_secrets+.
|
|
86
|
+
#
|
|
74
87
|
# reuse_access_token
|
|
75
88
|
|
|
89
|
+
# Set a limit for token_reuse if using reuse_access_token option
|
|
90
|
+
#
|
|
91
|
+
# This option limits token_reusability to some extent.
|
|
92
|
+
# If not set then access_token will be reused unless it expires.
|
|
93
|
+
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
|
|
94
|
+
#
|
|
95
|
+
# This option should be a percentage(i.e. (0,100])
|
|
96
|
+
#
|
|
97
|
+
# token_reuse_limit 100
|
|
98
|
+
|
|
99
|
+
# Hash access and refresh tokens before persisting them.
|
|
100
|
+
# This will disable the possibility to use +reuse_access_token+
|
|
101
|
+
# since plain values can no longer be retrieved.
|
|
102
|
+
#
|
|
103
|
+
# Note: If you are already a user of doorkeeper and have existing tokens
|
|
104
|
+
# in your installation, they will be invalid without enabling the additional
|
|
105
|
+
# setting `fallback_to_plain_secrets` below.
|
|
106
|
+
#
|
|
107
|
+
# hash_token_secrets
|
|
108
|
+
# By default, token secrets will be hashed using the
|
|
109
|
+
# +Doorkeeper::Hashing::SHA256+ strategy.
|
|
110
|
+
#
|
|
111
|
+
# If you wish to use another hashing implementation, you can override
|
|
112
|
+
# this strategy as follows:
|
|
113
|
+
#
|
|
114
|
+
# hash_token_secrets using: '::Doorkeeper::Hashing::MyCustomHashImpl'
|
|
115
|
+
#
|
|
116
|
+
# Keep in mind that changing the hashing function will invalidate all existing
|
|
117
|
+
# secrets, if there are any.
|
|
118
|
+
|
|
119
|
+
# Hash application secrets before persisting them.
|
|
120
|
+
#
|
|
121
|
+
# hash_application_secrets
|
|
122
|
+
#
|
|
123
|
+
# By default, applications will be hashed
|
|
124
|
+
# with the +Doorkeeper::SecretStoring::SHA256+ strategy.
|
|
125
|
+
#
|
|
126
|
+
# If you wish to use bcrypt for application secret hashing, uncomment
|
|
127
|
+
# this line instead:
|
|
128
|
+
#
|
|
129
|
+
# hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt'
|
|
130
|
+
|
|
131
|
+
# When the above option is enabled,
|
|
132
|
+
# and a hashed token or secret is not found,
|
|
133
|
+
# you can allow to fall back to another strategy.
|
|
134
|
+
# For users upgrading doorkeeper and wishing to enable hashing,
|
|
135
|
+
# you will probably want to enable the fallback to plain tokens.
|
|
136
|
+
#
|
|
137
|
+
# This will ensure that old access tokens and secrets
|
|
138
|
+
# will remain valid even if the hashing above is enabled.
|
|
139
|
+
#
|
|
140
|
+
# fallback_to_plain_secrets
|
|
141
|
+
|
|
76
142
|
# Issue access tokens with refresh token (disabled by default), you may also
|
|
77
143
|
# pass a block which accepts `context` to customize when to give a refresh
|
|
78
144
|
# token or not. Similar to `custom_access_token_expires_in`, `context` has
|
|
@@ -84,16 +150,11 @@ Doorkeeper.configure do
|
|
|
84
150
|
#
|
|
85
151
|
# use_refresh_token
|
|
86
152
|
|
|
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
|
-
|
|
93
153
|
# Provide support for an owner to be assigned to each registered application (disabled by default)
|
|
94
154
|
# Optional parameter confirmation: true (default false) if you want to enforce ownership of
|
|
95
155
|
# a registered application
|
|
96
|
-
#
|
|
156
|
+
# NOTE: you must also run the rails g doorkeeper:application_owner generator
|
|
157
|
+
# to provide the necessary support
|
|
97
158
|
#
|
|
98
159
|
# enable_application_owner confirmation: false
|
|
99
160
|
|
|
@@ -104,6 +165,21 @@ Doorkeeper.configure do
|
|
|
104
165
|
# default_scopes :public
|
|
105
166
|
# optional_scopes :write, :update
|
|
106
167
|
|
|
168
|
+
# Define scopes_by_grant_type to restrict only certain scopes for grant_type
|
|
169
|
+
# By default, all the scopes will be available for all the grant types.
|
|
170
|
+
#
|
|
171
|
+
# Keys to this hash should be the name of grant_type and
|
|
172
|
+
# values should be the array of scopes for that grant type.
|
|
173
|
+
# Note: scopes should be from configured_scopes(i.e. deafult or optional)
|
|
174
|
+
#
|
|
175
|
+
# scopes_by_grant_type password: [:write], client_credentials: [:update]
|
|
176
|
+
|
|
177
|
+
# Forbids creating/updating applications with arbitrary scopes that are
|
|
178
|
+
# not in configuration, i.e. `default_scopes` or `optional_scopes`.
|
|
179
|
+
# (disabled by default)
|
|
180
|
+
#
|
|
181
|
+
# enforce_configured_scopes
|
|
182
|
+
|
|
107
183
|
# Change the way client credentials are retrieved from the request object.
|
|
108
184
|
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
|
|
109
185
|
# falls back to the `:client_id` and `:client_secret` params from the `params` object.
|
|
@@ -121,8 +197,10 @@ Doorkeeper.configure do
|
|
|
121
197
|
# access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
|
|
122
198
|
|
|
123
199
|
# Change the native redirect uri for client apps
|
|
124
|
-
# When clients register with the following redirect uri, they won't be redirected to
|
|
125
|
-
#
|
|
200
|
+
# When clients register with the following redirect uri, they won't be redirected to
|
|
201
|
+
# any server and the authorizationcode will be displayed within the provider
|
|
202
|
+
# The value can be any string. Use nil to disable this feature. When disabled, clients
|
|
203
|
+
# must providea valid URL
|
|
126
204
|
# (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
|
|
127
205
|
#
|
|
128
206
|
# native_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
|
|
@@ -147,6 +225,53 @@ Doorkeeper.configure do
|
|
|
147
225
|
#
|
|
148
226
|
# forbid_redirect_uri { |uri| uri.scheme.to_s.downcase == 'javascript' }
|
|
149
227
|
|
|
228
|
+
# Allows to set blank redirect URIs for Applications in case Doorkeeper configured
|
|
229
|
+
# to use URI-less OAuth grant flows like Client Credentials or Resource Owner
|
|
230
|
+
# Password Credentials. The option is on by default and checks configured grant
|
|
231
|
+
# types, but you **need** to manually drop `NOT NULL` constraint from `redirect_uri`
|
|
232
|
+
# column for `oauth_applications` database table.
|
|
233
|
+
#
|
|
234
|
+
# You can completely disable this feature with:
|
|
235
|
+
#
|
|
236
|
+
# allow_blank_redirect_uri false
|
|
237
|
+
#
|
|
238
|
+
# Or you can define your custom check:
|
|
239
|
+
#
|
|
240
|
+
# allow_blank_redirect_uri do |grant_flows, client|
|
|
241
|
+
# client.superapp?
|
|
242
|
+
# end
|
|
243
|
+
|
|
244
|
+
# Specify how authorization errors should be handled.
|
|
245
|
+
# By default, doorkeeper renders json errors when access token
|
|
246
|
+
# is invalid, expired, revoked or has invalid scopes.
|
|
247
|
+
#
|
|
248
|
+
# If you want to render error response yourself (i.e. rescue exceptions),
|
|
249
|
+
# set handle_auth_errors to `:raise` and rescue Doorkeeper::Errors::InvalidToken
|
|
250
|
+
# or following specific errors:
|
|
251
|
+
#
|
|
252
|
+
# Doorkeeper::Errors::TokenForbidden, Doorkeeper::Errors::TokenExpired,
|
|
253
|
+
# Doorkeeper::Errors::TokenRevoked, Doorkeeper::Errors::TokenUnknown
|
|
254
|
+
#
|
|
255
|
+
# handle_auth_errors :raise
|
|
256
|
+
|
|
257
|
+
# Customize token introspection response.
|
|
258
|
+
# Allows to add your own fields to default one that are required by the OAuth spec
|
|
259
|
+
# for the introspection response. It could be `sub`, `aud` and so on.
|
|
260
|
+
# This configuration option can be a proc, lambda or any Ruby object responds
|
|
261
|
+
# to `.call` method and result of it's invocation must be a Hash.
|
|
262
|
+
#
|
|
263
|
+
# custom_introspection_response do |token, context|
|
|
264
|
+
# {
|
|
265
|
+
# "sub": "Z5O3upPC88QrAjx00dis",
|
|
266
|
+
# "aud": "https://protected.example.net/resource",
|
|
267
|
+
# "username": User.find(token.resource_owner_id).username
|
|
268
|
+
# }
|
|
269
|
+
# end
|
|
270
|
+
#
|
|
271
|
+
# or
|
|
272
|
+
#
|
|
273
|
+
# custom_introspection_response CustomIntrospectionResponder
|
|
274
|
+
|
|
150
275
|
# Specify what grant flows are enabled in array of Strings. The valid
|
|
151
276
|
# strings and the flows they enable are:
|
|
152
277
|
#
|
|
@@ -177,7 +302,7 @@ Doorkeeper.configure do
|
|
|
177
302
|
# end
|
|
178
303
|
|
|
179
304
|
# Hook into Authorization flow in order to implement Single Sign Out
|
|
180
|
-
# or add
|
|
305
|
+
# or add any other functionality.
|
|
181
306
|
#
|
|
182
307
|
# before_successful_authorization do |controller|
|
|
183
308
|
# Rails.logger.info(params.inspect)
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
2
2
|
def change
|
|
3
3
|
create_table :oauth_applications do |t|
|
|
4
|
-
t.string :name,
|
|
5
|
-
t.string :uid,
|
|
6
|
-
t.string :secret,
|
|
4
|
+
t.string :name, null: false
|
|
5
|
+
t.string :uid, null: false
|
|
6
|
+
t.string :secret, null: false
|
|
7
|
+
|
|
8
|
+
# Remove `null: false` if you are planning to use grant flows
|
|
9
|
+
# that doesn't require redirect URI to be used during authorization
|
|
10
|
+
# like Client Credentials flow or Resource Owner Password.
|
|
7
11
|
t.text :redirect_uri, null: false
|
|
8
12
|
t.string :scopes, null: false, default: ''
|
|
9
13
|
t.boolean :confidential, null: false, default: true
|
|
@@ -13,7 +17,7 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
13
17
|
add_index :oauth_applications, :uid, unique: true
|
|
14
18
|
|
|
15
19
|
create_table :oauth_access_grants do |t|
|
|
16
|
-
t.
|
|
20
|
+
t.references :resource_owner, null: false
|
|
17
21
|
t.references :application, null: false
|
|
18
22
|
t.string :token, null: false
|
|
19
23
|
t.integer :expires_in, null: false
|
|
@@ -31,21 +35,21 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
31
35
|
)
|
|
32
36
|
|
|
33
37
|
create_table :oauth_access_tokens do |t|
|
|
34
|
-
t.
|
|
35
|
-
t.references :application
|
|
38
|
+
t.references :resource_owner, index: true
|
|
39
|
+
t.references :application, null: false
|
|
36
40
|
|
|
37
41
|
# If you use a custom token generator you may need to change this column
|
|
38
42
|
# from string to text, so that it accepts tokens larger than 255
|
|
39
43
|
# characters. More info on custom token generators in:
|
|
40
44
|
# https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
|
|
41
45
|
#
|
|
42
|
-
# t.text
|
|
43
|
-
t.string
|
|
46
|
+
# t.text :token, null: false
|
|
47
|
+
t.string :token, null: false
|
|
44
48
|
|
|
45
49
|
t.string :refresh_token
|
|
46
50
|
t.integer :expires_in
|
|
47
51
|
t.datetime :revoked_at
|
|
48
|
-
t.datetime :created_at,
|
|
52
|
+
t.datetime :created_at, null: false
|
|
49
53
|
t.string :scopes
|
|
50
54
|
|
|
51
55
|
# If there is a previous_refresh_token column,
|
|
@@ -58,12 +62,15 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
58
62
|
end
|
|
59
63
|
|
|
60
64
|
add_index :oauth_access_tokens, :token, unique: true
|
|
61
|
-
add_index :oauth_access_tokens, :resource_owner_id
|
|
62
65
|
add_index :oauth_access_tokens, :refresh_token, unique: true
|
|
63
66
|
add_foreign_key(
|
|
64
67
|
:oauth_access_tokens,
|
|
65
68
|
:oauth_applications,
|
|
66
69
|
column: :application_id
|
|
67
70
|
)
|
|
71
|
+
|
|
72
|
+
# Uncomment below to ensure a valid reference to the resource owner's table
|
|
73
|
+
# add_foreign_key :oauth_access_grants, <model>, column: :resource_owner_id
|
|
74
|
+
# add_foreign_key :oauth_access_tokens, <model>, column: :resource_owner_id
|
|
68
75
|
end
|
|
69
76
|
end
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module Doorkeeper
|
|
4
4
|
module Generators
|
|
5
|
+
# Generates doorkeeper views for Rails application
|
|
6
|
+
#
|
|
5
7
|
class ViewsGenerator < ::Rails::Generators::Base
|
|
6
|
-
source_root File.expand_path(
|
|
8
|
+
source_root File.expand_path("../../../app/views", __dir__)
|
|
7
9
|
|
|
8
|
-
desc
|
|
10
|
+
desc "Copies default Doorkeeper views and layouts to your application."
|
|
9
11
|
|
|
10
12
|
def manifest
|
|
11
|
-
directory
|
|
12
|
-
directory
|
|
13
|
+
directory "doorkeeper", "app/views/doorkeeper"
|
|
14
|
+
directory "layouts/doorkeeper", "app/views/layouts/doorkeeper"
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
end
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper_integration"
|
|
4
4
|
|
|
5
5
|
describe Doorkeeper::ApplicationMetalController do
|
|
6
6
|
controller(Doorkeeper::ApplicationMetalController) do
|
|
7
7
|
def index
|
|
8
8
|
render json: {}, status: 200
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
def create
|
|
12
|
+
render json: {}, status: 200
|
|
13
|
+
end
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
it "lazy run hooks" do
|
|
@@ -16,35 +20,45 @@ describe Doorkeeper::ApplicationMetalController do
|
|
|
16
20
|
expect(i).to eq 1
|
|
17
21
|
end
|
|
18
22
|
|
|
19
|
-
describe
|
|
23
|
+
describe "enforce_content_type" do
|
|
20
24
|
before { allow(Doorkeeper.configuration).to receive(:enforce_content_type).and_return(flag) }
|
|
21
25
|
|
|
22
|
-
context
|
|
26
|
+
context "enabled" do
|
|
23
27
|
let(:flag) { true }
|
|
24
28
|
|
|
25
|
-
it
|
|
26
|
-
get :index, params: {}
|
|
29
|
+
it "returns a 200 for the requests without body" do
|
|
30
|
+
get :index, params: {}
|
|
27
31
|
expect(response).to have_http_status 200
|
|
28
32
|
end
|
|
29
33
|
|
|
30
|
-
it
|
|
31
|
-
|
|
34
|
+
it "returns a 200 for the requests with body and correct media type" do
|
|
35
|
+
post :create, params: {}, as: :url_encoded_form
|
|
36
|
+
expect(response).to have_http_status 200
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "returns a 415 for the requests with body and incorrect media type" do
|
|
40
|
+
post :create, params: {}, as: :json
|
|
32
41
|
expect(response).to have_http_status 415
|
|
33
42
|
end
|
|
34
43
|
end
|
|
35
44
|
|
|
36
|
-
context
|
|
45
|
+
context "disabled" do
|
|
37
46
|
let(:flag) { false }
|
|
38
47
|
|
|
39
|
-
it
|
|
48
|
+
it "returns a 200 for the correct media type" do
|
|
40
49
|
get :index, as: :url_encoded_form
|
|
41
50
|
expect(response).to have_http_status 200
|
|
42
51
|
end
|
|
43
52
|
|
|
44
|
-
it
|
|
53
|
+
it "returns a 200 for an incorrect media type" do
|
|
45
54
|
get :index, as: :json
|
|
46
55
|
expect(response).to have_http_status 200
|
|
47
56
|
end
|
|
57
|
+
|
|
58
|
+
it "returns a 200 for the requests with body and incorrect media type" do
|
|
59
|
+
post :create, params: {}, as: :json
|
|
60
|
+
expect(response).to have_http_status 200
|
|
61
|
+
end
|
|
48
62
|
end
|
|
49
63
|
end
|
|
50
64
|
end
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
2
4
|
|
|
3
5
|
module Doorkeeper
|
|
4
6
|
describe ApplicationsController do
|
|
5
|
-
context
|
|
7
|
+
context "JSON API" do
|
|
6
8
|
render_views
|
|
7
9
|
|
|
8
10
|
before do
|
|
@@ -10,81 +12,81 @@ module Doorkeeper
|
|
|
10
12
|
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
it
|
|
15
|
+
it "creates an application" do
|
|
14
16
|
expect do
|
|
15
17
|
post :create, params: {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
end.to
|
|
18
|
+
doorkeeper_application: {
|
|
19
|
+
name: "Example",
|
|
20
|
+
redirect_uri: "https://example.com",
|
|
21
|
+
}, format: :json,
|
|
22
|
+
}
|
|
23
|
+
end.to(change { Doorkeeper::Application.count })
|
|
22
24
|
|
|
23
25
|
expect(response).to be_successful
|
|
24
26
|
|
|
25
|
-
expect(json_response).to include(
|
|
27
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
26
28
|
|
|
27
|
-
expect(json_response[
|
|
28
|
-
expect(json_response[
|
|
29
|
+
expect(json_response["name"]).to eq("Example")
|
|
30
|
+
expect(json_response["redirect_uri"]).to eq("https://example.com")
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
it
|
|
33
|
+
it "returns validation errors on wrong create params" do
|
|
32
34
|
expect do
|
|
33
35
|
post :create, params: {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end.not_to
|
|
36
|
+
doorkeeper_application: {
|
|
37
|
+
name: "Example",
|
|
38
|
+
}, format: :json,
|
|
39
|
+
}
|
|
40
|
+
end.not_to(change { Doorkeeper::Application.count })
|
|
39
41
|
|
|
40
42
|
expect(response).to have_http_status(422)
|
|
41
43
|
|
|
42
|
-
expect(json_response).to include(
|
|
44
|
+
expect(json_response).to include("errors")
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
it
|
|
46
|
-
application = FactoryBot.create(:application, name:
|
|
47
|
+
it "returns application info" do
|
|
48
|
+
application = FactoryBot.create(:application, name: "Change me")
|
|
47
49
|
|
|
48
50
|
get :show, params: { id: application.id, format: :json }
|
|
49
51
|
|
|
50
52
|
expect(response).to be_successful
|
|
51
53
|
|
|
52
|
-
expect(json_response).to include(
|
|
54
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
it
|
|
56
|
-
application = FactoryBot.create(:application, name:
|
|
57
|
+
it "updates application" do
|
|
58
|
+
application = FactoryBot.create(:application, name: "Change me")
|
|
57
59
|
|
|
58
60
|
put :update, params: {
|
|
59
61
|
id: application.id,
|
|
60
62
|
doorkeeper_application: {
|
|
61
|
-
name:
|
|
62
|
-
redirect_uri:
|
|
63
|
-
}, format: :json
|
|
63
|
+
name: "Example App",
|
|
64
|
+
redirect_uri: "https://example.com",
|
|
65
|
+
}, format: :json,
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
expect(application.reload.name).to eq
|
|
68
|
+
expect(application.reload.name).to eq "Example App"
|
|
67
69
|
|
|
68
|
-
expect(json_response).to include(
|
|
70
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
69
71
|
end
|
|
70
72
|
|
|
71
|
-
it
|
|
72
|
-
application = FactoryBot.create(:application, name:
|
|
73
|
+
it "returns validation errors on wrong update params" do
|
|
74
|
+
application = FactoryBot.create(:application, name: "Change me")
|
|
73
75
|
|
|
74
76
|
put :update, params: {
|
|
75
77
|
id: application.id,
|
|
76
78
|
doorkeeper_application: {
|
|
77
|
-
name:
|
|
78
|
-
redirect_uri:
|
|
79
|
-
}, format: :json
|
|
79
|
+
name: "Example App",
|
|
80
|
+
redirect_uri: "localhost:3000",
|
|
81
|
+
}, format: :json,
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
expect(response).to have_http_status(422)
|
|
83
85
|
|
|
84
|
-
expect(json_response).to include(
|
|
86
|
+
expect(json_response).to include("errors")
|
|
85
87
|
end
|
|
86
88
|
|
|
87
|
-
it
|
|
89
|
+
it "destroys an application" do
|
|
88
90
|
application = FactoryBot.create(:application)
|
|
89
91
|
|
|
90
92
|
delete :destroy, params: { id: application.id, format: :json }
|
|
@@ -94,39 +96,38 @@ module Doorkeeper
|
|
|
94
96
|
end
|
|
95
97
|
end
|
|
96
98
|
|
|
97
|
-
context
|
|
99
|
+
context "when admin is not authenticated" do
|
|
98
100
|
before do
|
|
99
101
|
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(proc do
|
|
100
102
|
redirect_to main_app.root_url
|
|
101
103
|
end)
|
|
102
104
|
end
|
|
103
105
|
|
|
104
|
-
it
|
|
106
|
+
it "redirects as set in Doorkeeper.authenticate_admin" do
|
|
105
107
|
get :index
|
|
106
108
|
expect(response).to redirect_to(controller.main_app.root_url)
|
|
107
109
|
end
|
|
108
110
|
|
|
109
|
-
it
|
|
111
|
+
it "does not create application" do
|
|
110
112
|
expect do
|
|
111
|
-
post :create,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
end.not_to change { Doorkeeper::Application.count }
|
|
113
|
+
post :create, params: {
|
|
114
|
+
doorkeeper_application: {
|
|
115
|
+
name: "Example",
|
|
116
|
+
redirect_uri: "https://example.com",
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
end.not_to(change { Doorkeeper::Application.count })
|
|
119
120
|
end
|
|
120
121
|
end
|
|
121
122
|
|
|
122
|
-
context
|
|
123
|
+
context "when admin is authenticated" do
|
|
123
124
|
render_views
|
|
124
125
|
|
|
125
126
|
before do
|
|
126
127
|
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
|
|
127
128
|
end
|
|
128
129
|
|
|
129
|
-
it
|
|
130
|
+
it "sorts applications by created_at" do
|
|
130
131
|
first_application = FactoryBot.create(:application)
|
|
131
132
|
second_application = FactoryBot.create(:application)
|
|
132
133
|
expect(Doorkeeper::Application).to receive(:ordered_by).and_call_original
|
|
@@ -137,45 +138,42 @@ module Doorkeeper
|
|
|
137
138
|
expect(response.body).to have_selector("tbody tr:last-child#application_#{second_application.id}")
|
|
138
139
|
end
|
|
139
140
|
|
|
140
|
-
it
|
|
141
|
+
it "creates application" do
|
|
141
142
|
expect do
|
|
142
|
-
post :create,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
143
|
+
post :create, params: {
|
|
144
|
+
doorkeeper_application: {
|
|
145
|
+
name: "Example",
|
|
146
|
+
redirect_uri: "https://example.com",
|
|
147
|
+
},
|
|
148
|
+
}
|
|
149
149
|
end.to change { Doorkeeper::Application.count }.by(1)
|
|
150
150
|
|
|
151
151
|
expect(response).to be_redirect
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
it
|
|
154
|
+
it "does not allow mass assignment of uid or secret" do
|
|
155
155
|
application = FactoryBot.create(:application)
|
|
156
|
-
put :update,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
expect(application.reload.uid).not_to eq '1A2B3C4D'
|
|
156
|
+
put :update, params: {
|
|
157
|
+
id: application.id,
|
|
158
|
+
doorkeeper_application: {
|
|
159
|
+
uid: "1A2B3C4D",
|
|
160
|
+
secret: "1A2B3C4D",
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
expect(application.reload.uid).not_to eq "1A2B3C4D"
|
|
166
165
|
end
|
|
167
166
|
|
|
168
|
-
it
|
|
167
|
+
it "updates application" do
|
|
169
168
|
application = FactoryBot.create(:application)
|
|
170
|
-
put :update,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
expect(application.reload.name).to eq 'Example'
|
|
169
|
+
put :update, params: {
|
|
170
|
+
id: application.id, doorkeeper_application: {
|
|
171
|
+
name: "Example",
|
|
172
|
+
redirect_uri: "https://example.com",
|
|
173
|
+
},
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
expect(application.reload.name).to eq "Example"
|
|
179
177
|
end
|
|
180
178
|
end
|
|
181
179
|
end
|