doorkeeper 5.3.3 → 5.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +0 -14
  3. data/CHANGELOG.md +35 -10
  4. data/Dangerfile +7 -7
  5. data/Dockerfile +2 -2
  6. data/Gemfile +9 -9
  7. data/README.md +6 -4
  8. data/app/controllers/doorkeeper/applications_controller.rb +7 -7
  9. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  11. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  12. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  13. data/bin/console +14 -0
  14. data/config/locales/en.yml +3 -1
  15. data/doorkeeper.gemspec +1 -1
  16. data/gemfiles/rails_5_0.gemfile +8 -7
  17. data/gemfiles/rails_5_1.gemfile +8 -7
  18. data/gemfiles/rails_5_2.gemfile +8 -7
  19. data/gemfiles/rails_6_0.gemfile +8 -7
  20. data/gemfiles/rails_master.gemfile +8 -7
  21. data/lib/doorkeeper.rb +106 -79
  22. data/lib/doorkeeper/config.rb +40 -17
  23. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  24. data/lib/doorkeeper/config/option.rb +28 -14
  25. data/lib/doorkeeper/grape/helpers.rb +1 -1
  26. data/lib/doorkeeper/models/access_grant_mixin.rb +9 -11
  27. data/lib/doorkeeper/models/access_token_mixin.rb +100 -41
  28. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  29. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  30. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  31. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  32. data/lib/doorkeeper/oauth/authorization/code.rb +14 -5
  33. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  34. data/lib/doorkeeper/oauth/authorization/token.rb +7 -11
  35. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  36. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  37. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  38. data/lib/doorkeeper/oauth/client.rb +1 -1
  39. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  40. data/lib/doorkeeper/oauth/client_credentials/creator.rb +25 -7
  41. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  42. data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -1
  43. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  44. data/lib/doorkeeper/oauth/code_request.rb +1 -1
  45. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  46. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  47. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  48. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  49. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  50. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -5
  51. data/lib/doorkeeper/oauth/pre_authorization.rb +32 -27
  52. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  53. data/lib/doorkeeper/oauth/token.rb +1 -1
  54. data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
  55. data/lib/doorkeeper/oauth/token_request.rb +2 -2
  56. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  57. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +7 -2
  58. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +6 -2
  59. data/lib/doorkeeper/orm/active_record/mixins/application.rb +9 -64
  60. data/lib/doorkeeper/rails/routes.rb +13 -17
  61. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  62. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  63. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  64. data/lib/doorkeeper/request/strategy.rb +2 -2
  65. data/lib/doorkeeper/server.rb +3 -3
  66. data/lib/doorkeeper/version.rb +3 -3
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  69. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  70. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  71. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  72. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  73. data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
  74. data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -0
  75. data/spec/controllers/applications_controller_spec.rb +2 -2
  76. data/spec/controllers/authorizations_controller_spec.rb +165 -30
  77. data/spec/controllers/tokens_controller_spec.rb +6 -5
  78. data/spec/dummy/app/helpers/application_helper.rb +1 -1
  79. data/spec/dummy/app/models/user.rb +5 -1
  80. data/spec/dummy/config/application.rb +6 -4
  81. data/spec/dummy/config/boot.rb +4 -4
  82. data/spec/dummy/config/environment.rb +1 -1
  83. data/spec/dummy/config/routes.rb +4 -4
  84. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +2 -2
  85. data/spec/dummy/db/schema.rb +3 -1
  86. data/spec/factories.rb +1 -1
  87. data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +47 -0
  88. data/spec/lib/config_spec.rb +15 -11
  89. data/spec/lib/models/revocable_spec.rb +2 -3
  90. data/spec/lib/models/scopes_spec.rb +8 -0
  91. data/spec/lib/oauth/authorization_code_request_spec.rb +25 -15
  92. data/spec/lib/oauth/base_request_spec.rb +6 -20
  93. data/spec/lib/oauth/client_credentials/creator_spec.rb +90 -89
  94. data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
  95. data/spec/lib/oauth/client_credentials/validation_spec.rb +38 -40
  96. data/spec/lib/oauth/client_credentials_request_spec.rb +5 -4
  97. data/spec/lib/oauth/code_request_spec.rb +1 -1
  98. data/spec/lib/oauth/code_response_spec.rb +5 -1
  99. data/spec/lib/oauth/error_response_spec.rb +1 -1
  100. data/spec/lib/oauth/password_access_token_request_spec.rb +24 -13
  101. data/spec/lib/oauth/pre_authorization_spec.rb +13 -18
  102. data/spec/lib/oauth/refresh_token_request_spec.rb +19 -30
  103. data/spec/lib/oauth/token_request_spec.rb +14 -7
  104. data/spec/lib/option_spec.rb +51 -0
  105. data/spec/lib/stale_records_cleaner_spec.rb +18 -5
  106. data/spec/models/doorkeeper/access_grant_spec.rb +18 -4
  107. data/spec/models/doorkeeper/access_token_spec.rb +507 -479
  108. data/spec/models/doorkeeper/application_spec.rb +22 -62
  109. data/spec/requests/endpoints/token_spec.rb +5 -1
  110. data/spec/requests/flows/authorization_code_errors_spec.rb +4 -1
  111. data/spec/requests/flows/authorization_code_spec.rb +6 -1
  112. data/spec/requests/flows/client_credentials_spec.rb +41 -0
  113. data/spec/requests/flows/refresh_token_spec.rb +16 -8
  114. data/spec/requests/flows/revoke_token_spec.rb +143 -104
  115. data/spec/support/helpers/access_token_request_helper.rb +1 -0
  116. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  117. data/spec/support/helpers/config_helper.rb +1 -1
  118. data/spec/support/shared/controllers_shared_context.rb +2 -2
  119. data/spec/support/shared/models_shared_examples.rb +6 -4
  120. metadata +16 -5
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module OAuth
5
+ module Hooks
6
+ class Context
7
+ attr_reader :auth, :pre_auth
8
+
9
+ def initialize(**attributes)
10
+ attributes.each do |name, value|
11
+ instance_variable_set(:"@#{name}", value) if respond_to?(name)
12
+ end
13
+ end
14
+
15
+ def issued_token
16
+ auth&.issued_token
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -6,9 +6,9 @@ module Doorkeeper
6
6
  attr_reader :reason
7
7
 
8
8
  def self.from_access_token(access_token, attributes = {})
9
- reason = if access_token.try(:revoked?)
9
+ reason = if access_token&.revoked?
10
10
  :revoked
11
- elsif access_token.try(:expired?)
11
+ elsif access_token&.expired?
12
12
  :expired
13
13
  else
14
14
  :unknown
@@ -10,8 +10,7 @@ module Doorkeeper
10
10
  validate :resource_owner, error: :invalid_grant
11
11
  validate :scopes, error: :invalid_scope
12
12
 
13
- attr_accessor :server, :client, :resource_owner, :parameters,
14
- :access_token
13
+ attr_reader :client, :resource_owner, :parameters, :access_token
15
14
 
16
15
  def initialize(server, client, resource_owner, parameters = {})
17
16
  @server = server
@@ -25,18 +24,17 @@ module Doorkeeper
25
24
  private
26
25
 
27
26
  def before_successful_response
28
- find_or_create_access_token(client, resource_owner.id, scopes, server)
27
+ find_or_create_access_token(client, resource_owner, scopes, server)
29
28
  super
30
29
  end
31
30
 
32
31
  def validate_scopes
33
- client_scopes = client.try(:scopes)
34
32
  return true if scopes.blank?
35
33
 
36
34
  ScopeChecker.valid?(
37
35
  scope_str: scopes.to_s,
38
36
  server_scopes: server.scopes,
39
- app_scopes: client_scopes,
37
+ app_scopes: client.try(:scopes),
40
38
  grant_type: grant_type,
41
39
  )
42
40
  end
@@ -5,39 +5,37 @@ module Doorkeeper
5
5
  class PreAuthorization
6
6
  include Validations
7
7
 
8
- validate :client_id, error: :invalid_request
9
- validate :client, error: :invalid_client
10
- validate :redirect_uri, error: :invalid_redirect_uri
11
- validate :params, error: :invalid_request
12
- validate :response_type, error: :unsupported_response_type
13
- validate :scopes, error: :invalid_scope
8
+ validate :client_id, error: :invalid_request
9
+ validate :client, error: :invalid_client
10
+ validate :resource_owner_authorize_for_client, error: :invalid_client
11
+ validate :redirect_uri, error: :invalid_redirect_uri
12
+ validate :params, error: :invalid_request
13
+ validate :response_type, error: :unsupported_response_type
14
+ validate :scopes, error: :invalid_scope
14
15
  validate :code_challenge_method, error: :invalid_code_challenge_method
15
16
  validate :client_supports_grant_flow, error: :unauthorized_client
16
17
 
17
18
  attr_reader :server, :client_id, :client, :redirect_uri, :response_type, :state,
18
- :code_challenge, :code_challenge_method, :missing_param
19
+ :code_challenge, :code_challenge_method, :missing_param, :resource_owner
19
20
 
20
- def initialize(server, attrs = {})
21
+ def initialize(server, parameters = {}, resource_owner = nil)
21
22
  @server = server
22
- @client_id = attrs[:client_id]
23
- @response_type = attrs[:response_type]
24
- @redirect_uri = attrs[:redirect_uri]
25
- @scope = attrs[:scope]
26
- @state = attrs[:state]
27
- @code_challenge = attrs[:code_challenge]
28
- @code_challenge_method = attrs[:code_challenge_method]
23
+ @client_id = parameters[:client_id]
24
+ @response_type = parameters[:response_type]
25
+ @redirect_uri = parameters[:redirect_uri]
26
+ @scope = parameters[:scope]
27
+ @state = parameters[:state]
28
+ @code_challenge = parameters[:code_challenge]
29
+ @code_challenge_method = parameters[:code_challenge_method]
30
+ @resource_owner = resource_owner
29
31
  end
30
32
 
31
33
  def authorizable?
32
34
  valid?
33
35
  end
34
36
 
35
- def validate_client_supports_grant_flow
36
- Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client.application)
37
- end
38
-
39
37
  def scopes
40
- Scopes.from_string scope
38
+ Scopes.from_string(scope)
41
39
  end
42
40
 
43
41
  def scope
@@ -55,9 +53,7 @@ module Doorkeeper
55
53
  end
56
54
  end
57
55
 
58
- def as_json(attributes = {})
59
- return pre_auth_hash.merge(attributes.to_h) if attributes.respond_to?(:to_h)
60
-
56
+ def as_json(_options = nil)
61
57
  pre_auth_hash
62
58
  end
63
59
 
@@ -83,6 +79,10 @@ module Doorkeeper
83
79
  @client.present?
84
80
  end
85
81
 
82
+ def validate_client_supports_grant_flow
83
+ Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client.application)
84
+ end
85
+
86
86
  def validate_redirect_uri
87
87
  return false if redirect_uri.blank?
88
88
 
@@ -115,19 +115,24 @@ module Doorkeeper
115
115
  )
116
116
  end
117
117
 
118
- def grant_type
119
- response_type == "code" ? AUTHORIZATION_CODE : IMPLICIT
120
- end
121
-
122
118
  def validate_code_challenge_method
123
119
  code_challenge.blank? ||
124
120
  (code_challenge_method.present? && code_challenge_method =~ /^plain$|^S256$/)
125
121
  end
126
122
 
123
+ def validate_resource_owner_authorize_for_client
124
+ # The `authorize_resource_owner_for_client` config option is used for this validation
125
+ client.application.authorized_for_resource_owner?(@resource_owner)
126
+ end
127
+
127
128
  def response_on_fragment?
128
129
  response_type == "token"
129
130
  end
130
131
 
132
+ def grant_type
133
+ response_type == "code" ? AUTHORIZATION_CODE : IMPLICIT
134
+ end
135
+
131
136
  def pre_auth_hash
132
137
  {
133
138
  client_id: client.uid,
@@ -11,9 +11,8 @@ module Doorkeeper
11
11
  validate :client_match, error: :invalid_grant
12
12
  validate :scope, error: :invalid_scope
13
13
 
14
- attr_accessor :access_token, :client, :credentials, :refresh_token,
15
- :server
16
- attr_reader :missing_param
14
+ attr_reader :access_token, :client, :credentials, :refresh_token
15
+ attr_reader :missing_param
17
16
 
18
17
  def initialize(server, refresh_token, credentials, parameters = {})
19
18
  @server = server
@@ -50,30 +49,27 @@ module Doorkeeper
50
49
  end
51
50
 
52
51
  def create_access_token
53
- @access_token = server_config.access_token_model.create!(access_token_attributes)
54
- end
52
+ attributes = {}
55
53
 
56
- def access_token_attributes
57
- {
58
- application_id: refresh_token.application_id,
59
- resource_owner_id: refresh_token.resource_owner_id,
60
- scopes: scopes.to_s,
61
- expires_in: access_token_expires_in,
62
- use_refresh_token: true,
63
- }.tap do |attributes|
64
- if refresh_token_revoked_on_use?
65
- attributes[:previous_refresh_token] = refresh_token.refresh_token
54
+ resource_owner =
55
+ if Doorkeeper.config.polymorphic_resource_owner?
56
+ refresh_token.resource_owner
57
+ else
58
+ refresh_token.resource_owner_id
66
59
  end
60
+
61
+ if refresh_token_revoked_on_use?
62
+ attributes[:previous_refresh_token] = refresh_token.refresh_token
67
63
  end
68
- end
69
64
 
70
- def access_token_expires_in
71
- context = Authorization::Token.build_context(
72
- client,
73
- Doorkeeper::OAuth::REFRESH_TOKEN,
74
- scopes,
65
+ @access_token = server_config.access_token_model.create_for(
66
+ application: refresh_token.application,
67
+ resource_owner: resource_owner,
68
+ scopes: scopes,
69
+ expires_in: refresh_token.expires_in,
70
+ use_refresh_token: true,
71
+ **attributes,
75
72
  )
76
- Authorization::Token.access_token_expires_in(server, context)
77
73
  end
78
74
 
79
75
  def validate_token_presence
@@ -8,7 +8,7 @@ module Doorkeeper
8
8
  methods.inject(nil) do |_, method|
9
9
  method = self.method(method) if method.is_a?(Symbol)
10
10
  credentials = method.call(request)
11
- break credentials unless credentials.blank?
11
+ break credentials if credentials.present?
12
12
  end
13
13
  end
14
14
 
@@ -6,9 +6,6 @@ module Doorkeeper
6
6
  #
7
7
  # @see https://tools.ietf.org/html/rfc7662
8
8
  class TokenIntrospection
9
- attr_reader :server, :token
10
- attr_reader :error, :invalid_request_reason
11
-
12
9
  def initialize(server, token)
13
10
  @server = server
14
11
  @token = token
@@ -38,6 +35,9 @@ module Doorkeeper
38
35
 
39
36
  private
40
37
 
38
+ attr_reader :server, :token
39
+ attr_reader :error, :invalid_request_reason
40
+
41
41
  # If the protected resource uses OAuth 2.0 client credentials to
42
42
  # authenticate to the introspection endpoint and its credentials are
43
43
  # invalid, the authorization server responds with an HTTP 401
@@ -3,10 +3,10 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class TokenRequest
6
- attr_accessor :pre_auth, :resource_owner
6
+ attr_reader :pre_auth, :resource_owner
7
7
 
8
8
  def initialize(pre_auth, resource_owner)
9
- @pre_auth = pre_auth
9
+ @pre_auth = pre_auth
10
10
  @resource_owner = resource_owner
11
11
  end
12
12
 
@@ -3,7 +3,7 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class TokenResponse
6
- attr_accessor :token
6
+ attr_reader :token
7
7
 
8
8
  def initialize(token)
9
9
  @token = token
@@ -13,8 +13,13 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
13
13
  optional: true,
14
14
  inverse_of: :access_grants
15
15
 
16
- validates :resource_owner_id,
17
- :application_id,
16
+ if Doorkeeper.config.polymorphic_resource_owner?
17
+ belongs_to :resource_owner, polymorphic: true, optional: false
18
+ else
19
+ validates :resource_owner_id, presence: true
20
+ end
21
+
22
+ validates :application_id,
18
23
  :token,
19
24
  :expires_in,
20
25
  :redirect_uri,
@@ -13,6 +13,10 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
13
13
  inverse_of: :access_tokens,
14
14
  optional: true
15
15
 
16
+ if Doorkeeper.config.polymorphic_resource_owner?
17
+ belongs_to :resource_owner, polymorphic: true, optional: true
18
+ end
19
+
16
20
  validates :token, presence: true, uniqueness: { case_sensitive: true }
17
21
  validates :refresh_token, uniqueness: { case_sensitive: true }, if: :use_refresh_token?
18
22
 
@@ -25,7 +29,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
25
29
  on: :create, if: :use_refresh_token?
26
30
  end
27
31
 
28
- class_methods do
32
+ module ClassMethods
29
33
  # Searches for not revoked Access Tokens associated with the
30
34
  # specific Resource Owner.
31
35
  #
@@ -36,7 +40,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
36
40
  # active Access Tokens for Resource Owner
37
41
  #
38
42
  def active_for(resource_owner)
39
- where(resource_owner_id: resource_owner.id, revoked_at: nil)
43
+ by_resource_owner(resource_owner).where(revoked_at: nil)
40
44
  end
41
45
 
42
46
  def refresh_token_revoked_on_use?
@@ -12,12 +12,12 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
12
12
  has_many :access_grants,
13
13
  foreign_key: :application_id,
14
14
  dependent: :delete_all,
15
- class_name: Doorkeeper.config.access_grant_class.to_s
15
+ class_name: Doorkeeper.config.access_grant_class
16
16
 
17
17
  has_many :access_tokens,
18
18
  foreign_key: :application_id,
19
19
  dependent: :delete_all,
20
- class_name: Doorkeeper.config.access_token_class.to_s
20
+ class_name: Doorkeeper.config.access_token_class
21
21
 
22
22
  validates :name, :secret, :uid, presence: true
23
23
  validates :uid, uniqueness: { case_sensitive: true }
@@ -31,7 +31,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
31
31
  has_many :authorized_tokens,
32
32
  -> { where(revoked_at: nil) },
33
33
  foreign_key: :application_id,
34
- class_name: Doorkeeper.config.access_token_class.to_s
34
+ class_name: Doorkeeper.config.access_token_class
35
35
 
36
36
  has_many :authorized_applications,
37
37
  through: :authorized_tokens,
@@ -61,44 +61,21 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
61
61
  end
62
62
  end
63
63
 
64
- # Represents client as set of it's attributes in JSON format.
65
- # This is the right way how we want to override ActiveRecord #to_json.
64
+ # This is the right way how we want to override ActiveRecord #to_json
66
65
  #
67
- # Respects privacy settings and serializes minimum set of attributes
68
- # for public/private clients and full set for authorized owners.
69
- #
70
- # @return [Hash] entity attributes for JSON
66
+ # @return [String] entity attributes as JSON
71
67
  #
72
68
  def as_json(options = {})
73
- # if application belongs to some owner we need to check if it's the same as
74
- # the one passed in the options or check if we render the client as an owner
75
- if (respond_to?(:owner) && owner && owner == options[:current_resource_owner]) ||
76
- options[:as_owner]
77
- # Owners can see all the client attributes, fallback to ActiveModel serialization
78
- super
79
- else
80
- # if application has no owner or it's owner doesn't match one from the options
81
- # we render only minimum set of attributes that could be exposed to a public
82
- only = extract_serializable_attributes(options)
83
- super(options.merge(only: only))
84
- end
69
+ hash = super
70
+
71
+ hash["secret"] = plaintext_secret if hash.key?("secret")
72
+ hash
85
73
  end
86
74
 
87
75
  def authorized_for_resource_owner?(resource_owner)
88
76
  Doorkeeper.configuration.authorize_resource_owner_for_client.call(self, resource_owner)
89
77
  end
90
78
 
91
- # We need to hook into this method to allow serializing plan-text secrets
92
- # when secrets hashing enabled.
93
- #
94
- # @param key [String] attribute name
95
- #
96
- def read_attribute_for_serialization(key)
97
- return super unless key.to_s == "secret"
98
-
99
- plaintext_secret || secret
100
- end
101
-
102
79
  private
103
80
 
104
81
  def generate_uid
@@ -123,38 +100,6 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
123
100
  def enforce_scopes?
124
101
  Doorkeeper.config.enforce_configured_scopes?
125
102
  end
126
-
127
- # Helper method to extract collection of serializable attribute names
128
- # considering serialization options (like `only`, `except` and so on).
129
- #
130
- # @param options [Hash] serialization options
131
- #
132
- # @return [Array<String>]
133
- # collection of attributes to be serialized using #as_json
134
- #
135
- def extract_serializable_attributes(options = {})
136
- opts = options.try(:dup) || {}
137
- only = Array.wrap(opts[:only]).map(&:to_s)
138
-
139
- only = if only.blank?
140
- serializable_attributes
141
- else
142
- only & serializable_attributes
143
- end
144
-
145
- only -= Array.wrap(opts[:except]).map(&:to_s) if opts.key?(:except)
146
- only.uniq
147
- end
148
-
149
- # Collection of attributes that could be serialized for public.
150
- # Override this method if you need additional attributes to be serialized.
151
- #
152
- # @return [Array<String>] collection of serializable attributes
153
- def serializable_attributes
154
- attributes = %w[id name created_at]
155
- attributes << "uid" unless confidential?
156
- attributes
157
- end
158
103
  end
159
104
 
160
105
  module ClassMethods
@@ -2,29 +2,33 @@
2
2
 
3
3
  require "doorkeeper/rails/routes/mapping"
4
4
  require "doorkeeper/rails/routes/mapper"
5
+ require "doorkeeper/rails/routes/abstract_router"
6
+ require "doorkeeper/rails/routes/registry"
5
7
 
6
8
  module Doorkeeper
7
9
  module Rails
8
10
  class Routes # :nodoc:
9
- mattr_reader :mapping do
10
- {}
11
- end
12
-
13
11
  module Helper
14
12
  def use_doorkeeper(options = {}, &block)
15
13
  Doorkeeper::Rails::Routes.new(self, &block).generate_routes!(options)
16
14
  end
17
15
  end
18
16
 
17
+ include AbstractRouter
18
+ extend Registry
19
+
20
+ mattr_reader :mapping do
21
+ {}
22
+ end
23
+
19
24
  def self.install!
20
25
  ActionDispatch::Routing::Mapper.include Doorkeeper::Rails::Routes::Helper
21
- end
22
26
 
23
- attr_reader :routes
27
+ registered_routes.each(&:install!)
28
+ end
24
29
 
25
- def initialize(routes, &block)
26
- @routes = routes
27
- @mapping = Mapper.new.map(&block)
30
+ def initialize(routes, mapper = Mapper.new, &block)
31
+ super
28
32
 
29
33
  @mapping.skips.push(:applications, :authorized_applications) if Doorkeeper.config.api_only
30
34
  end
@@ -43,14 +47,6 @@ module Doorkeeper
43
47
 
44
48
  private
45
49
 
46
- def map_route(name, method)
47
- return if @mapping.skipped?(name)
48
-
49
- send(method, @mapping[name])
50
-
51
- mapping[name] = @mapping[name]
52
- end
53
-
54
50
  def authorization_routes(mapping)
55
51
  routes.resource(
56
52
  :authorization,