doorkeeper 5.0.0 → 5.1.0.rc1
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/.travis.yml +12 -3
- data/Dangerfile +67 -0
- data/Gemfile +3 -1
- data/NEWS.md +49 -5
- data/README.md +19 -4
- data/app/controllers/doorkeeper/application_controller.rb +2 -0
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -0
- data/app/controllers/doorkeeper/applications_controller.rb +4 -2
- 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 +2 -0
- data/app/controllers/doorkeeper/tokens_controller.rb +8 -6
- data/app/helpers/doorkeeper/dashboard_helper.rb +2 -0
- data/app/validators/redirect_uri_validator.rb +2 -0
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
- data/bin/console +15 -0
- data/doorkeeper.gemspec +23 -22
- data/gemfiles/rails_4_2.gemfile +1 -0
- data/gemfiles/rails_5_0.gemfile +1 -0
- data/gemfiles/rails_5_1.gemfile +1 -0
- data/gemfiles/rails_5_2.gemfile +2 -1
- data/gemfiles/rails_master.gemfile +1 -0
- data/lib/doorkeeper/config.rb +80 -8
- data/lib/doorkeeper/engine.rb +2 -0
- data/lib/doorkeeper/errors.rb +17 -0
- data/lib/doorkeeper/grape/authorization_decorator.rb +2 -0
- data/lib/doorkeeper/grape/helpers.rb +2 -0
- data/lib/doorkeeper/helpers/controller.rb +5 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +13 -4
- data/lib/doorkeeper/models/access_token_mixin.rb +45 -12
- data/lib/doorkeeper/models/application_mixin.rb +54 -1
- data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +2 -0
- data/lib/doorkeeper/models/concerns/hashable.rb +137 -0
- data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +2 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +2 -0
- data/lib/doorkeeper/models/concerns/scopes.rb +3 -1
- data/lib/doorkeeper/oauth/authorization/code.rb +3 -1
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +3 -1
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +2 -0
- data/lib/doorkeeper/oauth/authorization_code_request.rb +3 -1
- 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 +6 -3
- data/lib/doorkeeper/oauth/client_credentials_request.rb +2 -0
- 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 +10 -0
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +9 -2
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -0
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +37 -2
- data/lib/doorkeeper/oauth/invalid_token_response.rb +18 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +10 -3
- data/lib/doorkeeper/oauth/refresh_token_request.rb +14 -3
- data/lib/doorkeeper/oauth/scopes.rb +2 -0
- data/lib/doorkeeper/oauth/token.rb +2 -0
- data/lib/doorkeeper/oauth/token_introspection.rb +2 -0
- data/lib/doorkeeper/oauth/token_request.rb +2 -0
- data/lib/doorkeeper/oauth/token_response.rb +4 -2
- data/lib/doorkeeper/orm/active_record/access_grant.rb +22 -2
- data/lib/doorkeeper/orm/active_record/application.rb +16 -2
- data/lib/doorkeeper/orm/active_record.rb +2 -0
- data/lib/doorkeeper/rails/helpers.rb +4 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +2 -0
- data/lib/doorkeeper/rails/routes.rb +9 -2
- data/lib/doorkeeper/rake/db.rake +4 -4
- 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 +2 -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 +2 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +61 -3
- data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -3
- data/spec/controllers/application_metal_controller_spec.rb +18 -4
- data/spec/controllers/applications_controller_spec.rb +37 -41
- data/spec/controllers/authorizations_controller_spec.rb +71 -18
- data/spec/controllers/protected_resources_controller_spec.rb +44 -2
- data/spec/controllers/tokens_controller_spec.rb +11 -16
- data/spec/dummy/Rakefile +1 -1
- data/spec/dummy/app/controllers/application_controller.rb +1 -1
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +1 -1
- data/spec/dummy/app/controllers/home_controller.rb +1 -2
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/boot.rb +2 -4
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/initializers/doorkeeper.rb +2 -1
- data/spec/dummy/config/initializers/new_framework_defaults.rb +1 -3
- data/spec/dummy/config/initializers/secret_token.rb +1 -1
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +4 -4
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
- data/spec/dummy/script/rails +4 -3
- data/spec/factories.rb +9 -9
- data/spec/generators/install_generator_spec.rb +4 -1
- data/spec/generators/templates/routes.rb +0 -1
- data/spec/generators/views_generator_spec.rb +1 -1
- data/spec/grape/grape_integration_spec.rb +1 -1
- data/spec/lib/config_spec.rb +109 -8
- data/spec/lib/doorkeeper_spec.rb +5 -5
- data/spec/lib/models/hashable_spec.rb +183 -0
- data/spec/lib/oauth/authorization_code_request_spec.rb +9 -6
- data/spec/lib/oauth/base_request_spec.rb +10 -10
- data/spec/lib/oauth/client/credentials_spec.rb +2 -2
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -2
- data/spec/lib/oauth/client_credentials/validation_spec.rb +5 -1
- data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
- data/spec/lib/oauth/code_request_spec.rb +2 -2
- data/spec/lib/oauth/code_response_spec.rb +1 -1
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +52 -17
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +37 -8
- data/spec/lib/oauth/password_access_token_request_spec.rb +48 -15
- data/spec/lib/oauth/pre_authorization_spec.rb +24 -0
- data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
- data/spec/lib/oauth/token_request_spec.rb +5 -5
- data/spec/lib/oauth/token_response_spec.rb +13 -13
- data/spec/lib/oauth/token_spec.rb +18 -1
- data/spec/lib/server_spec.rb +6 -6
- data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +14 -4
- data/spec/models/doorkeeper/access_grant_spec.rb +61 -0
- data/spec/models/doorkeeper/access_token_spec.rb +137 -10
- data/spec/models/doorkeeper/application_spec.rb +41 -4
- data/spec/requests/applications/applications_request_spec.rb +2 -2
- data/spec/requests/endpoints/authorization_spec.rb +2 -2
- data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
- data/spec/requests/flows/authorization_code_spec.rb +115 -15
- data/spec/requests/flows/implicit_grant_errors_spec.rb +2 -2
- data/spec/requests/flows/password_spec.rb +10 -4
- data/spec/requests/flows/refresh_token_spec.rb +57 -0
- data/spec/requests/flows/revoke_token_spec.rb +23 -39
- data/spec/requests/protected_resources/private_api_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -1
- data/spec/support/doorkeeper_rspec.rb +2 -1
- data/spec/support/helpers/model_helper.rb +8 -4
- data/spec/support/helpers/url_helper.rb +11 -11
- data/spec/support/ruby_2_6_rails_4_2_patch.rb +14 -0
- data/spec/support/shared/controllers_shared_context.rb +56 -0
- data/spec/support/shared/hashing_shared_context.rb +29 -0
- data/spec/validators/redirect_uri_validator_spec.rb +2 -2
- metadata +31 -8
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
module Authorization
|
|
@@ -60,7 +62,7 @@ module Doorkeeper
|
|
|
60
62
|
{
|
|
61
63
|
controller: controller,
|
|
62
64
|
action: :show,
|
|
63
|
-
access_token: token.
|
|
65
|
+
access_token: token.plaintext_token
|
|
64
66
|
}
|
|
65
67
|
end
|
|
66
68
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class Client
|
|
@@ -16,7 +18,7 @@ module Doorkeeper
|
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def self.authenticate(credentials, method = Application.method(:by_uid_and_secret))
|
|
19
|
-
return
|
|
21
|
+
return if credentials.blank?
|
|
20
22
|
|
|
21
23
|
if (application = method.call(credentials.uid, credentials.secret))
|
|
22
24
|
new(application)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class ClientCredentialsRequest < BaseRequest
|
|
@@ -32,9 +34,10 @@ module Doorkeeper
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
ScopeChecker.valid?(
|
|
35
|
-
@request.scopes.to_s,
|
|
36
|
-
@server.scopes,
|
|
37
|
-
application_scopes
|
|
37
|
+
scope_str: @request.scopes.to_s,
|
|
38
|
+
server_scopes: @server.scopes,
|
|
39
|
+
app_scopes: application_scopes,
|
|
40
|
+
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS
|
|
38
41
|
)
|
|
39
42
|
end
|
|
40
43
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class CodeResponse < BaseResponse
|
|
@@ -21,7 +23,7 @@ module Doorkeeper
|
|
|
21
23
|
elsif response_on_fragment
|
|
22
24
|
Authorization::URIBuilder.uri_with_fragment(
|
|
23
25
|
pre_auth.redirect_uri,
|
|
24
|
-
access_token: auth.token.
|
|
26
|
+
access_token: auth.token.plaintext_token,
|
|
25
27
|
token_type: auth.token.token_type,
|
|
26
28
|
expires_in: auth.token.expires_in_seconds,
|
|
27
29
|
state: pre_auth.state
|
|
@@ -29,7 +31,7 @@ module Doorkeeper
|
|
|
29
31
|
else
|
|
30
32
|
Authorization::URIBuilder.uri_with_query(
|
|
31
33
|
pre_auth.redirect_uri,
|
|
32
|
-
code: auth.token.
|
|
34
|
+
code: auth.token.plaintext_token,
|
|
33
35
|
state: pre_auth.state
|
|
34
36
|
)
|
|
35
37
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class ErrorResponse < BaseResponse
|
|
@@ -55,6 +57,10 @@ module Doorkeeper
|
|
|
55
57
|
}
|
|
56
58
|
end
|
|
57
59
|
|
|
60
|
+
def raise_exception!
|
|
61
|
+
raise exception_class.new(self), description
|
|
62
|
+
end
|
|
63
|
+
|
|
58
64
|
protected
|
|
59
65
|
|
|
60
66
|
delegate :realm, to: :configuration
|
|
@@ -63,6 +69,10 @@ module Doorkeeper
|
|
|
63
69
|
Doorkeeper.configuration
|
|
64
70
|
end
|
|
65
71
|
|
|
72
|
+
def exception_class
|
|
73
|
+
raise NotImplementedError, "error response must define #exception_class"
|
|
74
|
+
end
|
|
75
|
+
|
|
66
76
|
private
|
|
67
77
|
|
|
68
78
|
def authenticate_info
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class ForbiddenTokenResponse < ErrorResponse
|
|
@@ -21,8 +23,13 @@ module Doorkeeper
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def description
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
@description ||= @scopes.map { |s| I18n.t(s, scope: %i[doorkeeper scopes]) }.join("\n")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def exception_class
|
|
32
|
+
Doorkeeper::Errors::TokenForbidden
|
|
26
33
|
end
|
|
27
34
|
end
|
|
28
35
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
module Helpers
|
|
@@ -5,31 +7,46 @@ module Doorkeeper
|
|
|
5
7
|
class Validator
|
|
6
8
|
attr_reader :parsed_scopes, :scope_str
|
|
7
9
|
|
|
8
|
-
def initialize(scope_str, server_scopes,
|
|
10
|
+
def initialize(scope_str, server_scopes, app_scopes, grant_type)
|
|
9
11
|
@parsed_scopes = OAuth::Scopes.from_string(scope_str)
|
|
10
12
|
@scope_str = scope_str
|
|
11
|
-
@valid_scopes = valid_scopes(server_scopes,
|
|
13
|
+
@valid_scopes = valid_scopes(server_scopes, app_scopes)
|
|
14
|
+
|
|
15
|
+
if grant_type
|
|
16
|
+
@scopes_by_grant_type = Doorkeeper.configuration.scopes_by_grant_type[grant_type.to_sym]
|
|
17
|
+
end
|
|
12
18
|
end
|
|
13
19
|
|
|
14
20
|
def valid?
|
|
15
21
|
scope_str.present? &&
|
|
16
22
|
scope_str !~ /[\n\r\t]/ &&
|
|
17
|
-
@valid_scopes.has_scopes?(parsed_scopes)
|
|
23
|
+
@valid_scopes.has_scopes?(parsed_scopes) &&
|
|
24
|
+
permitted_to_grant_type?
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
private
|
|
21
28
|
|
|
22
|
-
def valid_scopes(server_scopes,
|
|
23
|
-
if
|
|
24
|
-
|
|
29
|
+
def valid_scopes(server_scopes, app_scopes)
|
|
30
|
+
if app_scopes.present?
|
|
31
|
+
app_scopes
|
|
25
32
|
else
|
|
26
33
|
server_scopes
|
|
27
34
|
end
|
|
28
35
|
end
|
|
36
|
+
|
|
37
|
+
def permitted_to_grant_type?
|
|
38
|
+
return true unless @scopes_by_grant_type
|
|
39
|
+
|
|
40
|
+
OAuth::Scopes.from_array(@scopes_by_grant_type)
|
|
41
|
+
.has_scopes?(parsed_scopes)
|
|
42
|
+
end
|
|
29
43
|
end
|
|
30
44
|
|
|
31
|
-
def self.valid?(scope_str
|
|
32
|
-
Validator.new(scope_str,
|
|
45
|
+
def self.valid?(scope_str:, server_scopes:, app_scopes: nil, grant_type: nil)
|
|
46
|
+
Validator.new(scope_str,
|
|
47
|
+
server_scopes,
|
|
48
|
+
app_scopes,
|
|
49
|
+
grant_type).valid?
|
|
33
50
|
end
|
|
34
51
|
end
|
|
35
52
|
end
|
|
@@ -1,4 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'ipaddr'
|
|
3
|
+
|
|
1
4
|
module Doorkeeper
|
|
5
|
+
module IPAddrLoopback
|
|
6
|
+
def loopback?
|
|
7
|
+
case @family
|
|
8
|
+
when Socket::AF_INET
|
|
9
|
+
@addr & 0xff000000 == 0x7f000000
|
|
10
|
+
when Socket::AF_INET6
|
|
11
|
+
@addr == 1
|
|
12
|
+
else
|
|
13
|
+
raise AddressFamilyError, "unsupported address family"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# For backward compatibility with old rubies
|
|
19
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5.0")
|
|
20
|
+
IPAddr.send(:include, Doorkeeper::IPAddrLoopback)
|
|
21
|
+
end
|
|
22
|
+
|
|
2
23
|
module OAuth
|
|
3
24
|
module Helpers
|
|
4
25
|
module URIChecker
|
|
@@ -14,16 +35,30 @@ module Doorkeeper
|
|
|
14
35
|
url = as_uri(url)
|
|
15
36
|
client_url = as_uri(client_url)
|
|
16
37
|
|
|
17
|
-
|
|
38
|
+
unless client_url.query.nil?
|
|
18
39
|
return false unless query_matches?(url.query, client_url.query)
|
|
19
40
|
# Clear out queries so rest of URI can be tested. This allows query
|
|
20
41
|
# params to be in the request but order not mattering.
|
|
21
42
|
client_url.query = nil
|
|
22
43
|
end
|
|
44
|
+
|
|
45
|
+
# RFC8252, Paragraph 7.3
|
|
46
|
+
# @see https://tools.ietf.org/html/rfc8252#section-7.3
|
|
47
|
+
if loopback_uri?(url) && loopback_uri?(client_url)
|
|
48
|
+
url.port = nil
|
|
49
|
+
client_url.port = nil
|
|
50
|
+
end
|
|
51
|
+
|
|
23
52
|
url.query = nil
|
|
24
53
|
url == client_url
|
|
25
54
|
end
|
|
26
55
|
|
|
56
|
+
def self.loopback_uri?(uri)
|
|
57
|
+
IPAddr.new(uri.host).loopback?
|
|
58
|
+
rescue IPAddr::Error
|
|
59
|
+
false
|
|
60
|
+
end
|
|
61
|
+
|
|
27
62
|
def self.valid_for_authorization?(url, client_url)
|
|
28
63
|
valid?(url) && client_url.split.any? { |other_url| matches?(url, other_url) }
|
|
29
64
|
end
|
|
@@ -33,7 +68,7 @@ module Doorkeeper
|
|
|
33
68
|
end
|
|
34
69
|
|
|
35
70
|
def self.query_matches?(query, client_query)
|
|
36
|
-
return true if client_query.
|
|
71
|
+
return true if client_query.blank? && query.blank?
|
|
37
72
|
return false if client_query.nil? || query.nil?
|
|
38
73
|
# Will return true independent of query order
|
|
39
74
|
client_query.split('&').sort == query.split('&').sort
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class InvalidTokenResponse < ErrorResponse
|
|
@@ -24,6 +26,22 @@ module Doorkeeper
|
|
|
24
26
|
scope = { scope: %i[doorkeeper errors messages invalid_token] }
|
|
25
27
|
@description ||= I18n.translate @reason, scope
|
|
26
28
|
end
|
|
29
|
+
|
|
30
|
+
protected
|
|
31
|
+
|
|
32
|
+
def exception_class
|
|
33
|
+
errors_mapping.fetch(reason)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def errors_mapping
|
|
39
|
+
{
|
|
40
|
+
expired: Doorkeeper::Errors::TokenExpired,
|
|
41
|
+
revoked: Doorkeeper::Errors::TokenRevoked,
|
|
42
|
+
unknown: Doorkeeper::Errors::TokenUnknown
|
|
43
|
+
}
|
|
44
|
+
end
|
|
27
45
|
end
|
|
28
46
|
end
|
|
29
47
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class PasswordAccessTokenRequest < BaseRequest
|
|
@@ -30,7 +32,12 @@ module Doorkeeper
|
|
|
30
32
|
client_scopes = client.try(:scopes)
|
|
31
33
|
return true if scopes.blank?
|
|
32
34
|
|
|
33
|
-
ScopeChecker.valid?(
|
|
35
|
+
ScopeChecker.valid?(
|
|
36
|
+
scope_str: scopes.to_s,
|
|
37
|
+
server_scopes: server.scopes,
|
|
38
|
+
app_scopes: client_scopes,
|
|
39
|
+
grant_type: grant_type
|
|
40
|
+
)
|
|
34
41
|
end
|
|
35
42
|
|
|
36
43
|
def validate_resource_owner
|
|
@@ -38,7 +45,7 @@ module Doorkeeper
|
|
|
38
45
|
end
|
|
39
46
|
|
|
40
47
|
def validate_client
|
|
41
|
-
!parameters[:client_id] ||
|
|
48
|
+
!parameters[:client_id] || client.present?
|
|
42
49
|
end
|
|
43
50
|
end
|
|
44
51
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class PreAuthorization
|
|
@@ -75,12 +77,17 @@ module Doorkeeper
|
|
|
75
77
|
return true if scope.blank?
|
|
76
78
|
|
|
77
79
|
Helpers::ScopeChecker.valid?(
|
|
78
|
-
scope,
|
|
79
|
-
server.scopes,
|
|
80
|
-
client.application.scopes
|
|
80
|
+
scope_str: scope,
|
|
81
|
+
server_scopes: server.scopes,
|
|
82
|
+
app_scopes: client.application.scopes,
|
|
83
|
+
grant_type: grant_type
|
|
81
84
|
)
|
|
82
85
|
end
|
|
83
86
|
|
|
87
|
+
def grant_type
|
|
88
|
+
response_type == 'code' ? AUTHORIZATION_CODE : IMPLICIT
|
|
89
|
+
end
|
|
90
|
+
|
|
84
91
|
def validate_redirect_uri
|
|
85
92
|
return false if redirect_uri.blank?
|
|
86
93
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class RefreshTokenRequest < BaseRequest
|
|
@@ -82,16 +84,25 @@ module Doorkeeper
|
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
def validate_client
|
|
85
|
-
|
|
87
|
+
return true if credentials.blank?
|
|
88
|
+
|
|
89
|
+
client.present?
|
|
86
90
|
end
|
|
87
91
|
|
|
92
|
+
# @see https://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-1.5
|
|
93
|
+
#
|
|
88
94
|
def validate_client_match
|
|
89
|
-
|
|
95
|
+
return true if refresh_token.application_id.blank?
|
|
96
|
+
|
|
97
|
+
client && refresh_token.application_id == client.id
|
|
90
98
|
end
|
|
91
99
|
|
|
92
100
|
def validate_scope
|
|
93
101
|
if @original_scopes.present?
|
|
94
|
-
ScopeChecker.valid?(
|
|
102
|
+
ScopeChecker.valid?(
|
|
103
|
+
scope_str: @original_scopes,
|
|
104
|
+
server_scopes: refresh_token.scopes
|
|
105
|
+
)
|
|
95
106
|
else
|
|
96
107
|
true
|
|
97
108
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module OAuth
|
|
3
5
|
class TokenResponse
|
|
@@ -9,10 +11,10 @@ module Doorkeeper
|
|
|
9
11
|
|
|
10
12
|
def body
|
|
11
13
|
{
|
|
12
|
-
'access_token' => token.
|
|
14
|
+
'access_token' => token.plaintext_token,
|
|
13
15
|
'token_type' => token.token_type,
|
|
14
16
|
'expires_in' => token.expires_in_seconds,
|
|
15
|
-
'refresh_token' => token.
|
|
17
|
+
'refresh_token' => token.plaintext_refresh_token,
|
|
16
18
|
'scope' => token.scopes_string,
|
|
17
19
|
'created_at' => token.created_at.to_i
|
|
18
20
|
}.reject { |_, value| value.blank? }
|
|
@@ -16,11 +16,30 @@ module Doorkeeper
|
|
|
16
16
|
|
|
17
17
|
belongs_to :application, belongs_to_options
|
|
18
18
|
|
|
19
|
-
validates :resource_owner_id,
|
|
19
|
+
validates :resource_owner_id,
|
|
20
|
+
:application_id,
|
|
21
|
+
:token,
|
|
22
|
+
:expires_in,
|
|
23
|
+
:redirect_uri,
|
|
24
|
+
presence: true
|
|
25
|
+
|
|
20
26
|
validates :token, uniqueness: true
|
|
21
27
|
|
|
22
28
|
before_validation :generate_token, on: :create
|
|
23
29
|
|
|
30
|
+
# Keep a reference to the generated token during generation
|
|
31
|
+
# of this access grant. The actual token may be mapped by
|
|
32
|
+
# the configuration hasher and may not be available in plaintext.
|
|
33
|
+
#
|
|
34
|
+
# If hash tokens are enabled, this will return nil on fetched tokens
|
|
35
|
+
def plaintext_token
|
|
36
|
+
if perform_secret_hashing?
|
|
37
|
+
@raw_token
|
|
38
|
+
else
|
|
39
|
+
token
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
24
43
|
private
|
|
25
44
|
|
|
26
45
|
# Generates token value with UniqueToken class.
|
|
@@ -28,7 +47,8 @@ module Doorkeeper
|
|
|
28
47
|
# @return [String] token value
|
|
29
48
|
#
|
|
30
49
|
def generate_token
|
|
31
|
-
|
|
50
|
+
@raw_token = UniqueToken.generate
|
|
51
|
+
self.token = hashed_or_plain_token(@raw_token)
|
|
32
52
|
end
|
|
33
53
|
end
|
|
34
54
|
end
|
|
@@ -45,6 +45,16 @@ module Doorkeeper
|
|
|
45
45
|
AccessGrant.revoke_all_for(id, resource_owner)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
# We keep a volatile copy of the raw client_secret for initial communication
|
|
49
|
+
# The stored secret may be mapped and not available in cleartext.
|
|
50
|
+
def plaintext_secret
|
|
51
|
+
if perform_secret_hashing?
|
|
52
|
+
@raw_secret
|
|
53
|
+
else
|
|
54
|
+
secret
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
48
58
|
private
|
|
49
59
|
|
|
50
60
|
def generate_uid
|
|
@@ -52,12 +62,16 @@ module Doorkeeper
|
|
|
52
62
|
end
|
|
53
63
|
|
|
54
64
|
def generate_secret
|
|
55
|
-
|
|
65
|
+
return unless secret.blank?
|
|
66
|
+
|
|
67
|
+
@raw_secret = UniqueToken.generate
|
|
68
|
+
self.secret = hashed_or_plain_token(@raw_secret)
|
|
56
69
|
end
|
|
57
70
|
|
|
58
71
|
def scopes_match_configured
|
|
59
72
|
if scopes.present? &&
|
|
60
|
-
!ScopeChecker.valid?(scopes.to_s,
|
|
73
|
+
!ScopeChecker.valid?(scope_str: scopes.to_s,
|
|
74
|
+
server_scopes: Doorkeeper.configuration.scopes)
|
|
61
75
|
errors.add(:scopes, :not_match_configured)
|
|
62
76
|
end
|
|
63
77
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Doorkeeper
|
|
2
4
|
module Rails
|
|
3
5
|
module Helpers
|
|
@@ -19,6 +21,8 @@ module Doorkeeper
|
|
|
19
21
|
|
|
20
22
|
def doorkeeper_render_error
|
|
21
23
|
error = doorkeeper_error
|
|
24
|
+
error.raise_exception! if Doorkeeper.configuration.raise_on_errors?
|
|
25
|
+
|
|
22
26
|
headers.merge!(error.headers.reject { |k| k == "Content-Type" })
|
|
23
27
|
doorkeeper_render_error_with(error)
|
|
24
28
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'doorkeeper/rails/routes/mapping'
|
|
2
4
|
require 'doorkeeper/rails/routes/mapper'
|
|
3
5
|
|
|
@@ -91,11 +93,16 @@ module Doorkeeper
|
|
|
91
93
|
end
|
|
92
94
|
|
|
93
95
|
def application_routes(mapping)
|
|
94
|
-
routes.resources :doorkeeper_applications,
|
|
96
|
+
routes.resources :doorkeeper_applications,
|
|
97
|
+
controller: mapping[:controllers],
|
|
98
|
+
as: :applications,
|
|
99
|
+
path: 'applications'
|
|
95
100
|
end
|
|
96
101
|
|
|
97
102
|
def authorized_applications_routes(mapping)
|
|
98
|
-
routes.resources :authorized_applications,
|
|
103
|
+
routes.resources :authorized_applications,
|
|
104
|
+
only: %i[index destroy],
|
|
105
|
+
controller: mapping[:controllers]
|
|
99
106
|
end
|
|
100
107
|
end
|
|
101
108
|
end
|