doorkeeper-openid_connect 1.7.2 → 1.7.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd500337bf3593b1f15ab64da67dd2da940797271fd1a169e47f2542371d6930
4
- data.tar.gz: 4c3fdae9aca104f74f2bcf2e2805d09fe784e75326e3fa2382de8ba74133987a
3
+ metadata.gz: ab0de01b3be4241280fd4846f9c38b4c915685918a6401e464dce609fb588ace
4
+ data.tar.gz: 999e38663483020d9c84b525f38842e0d9a5811c72ddfd04bdb7c86e1e018b2a
5
5
  SHA512:
6
- metadata.gz: 887f767a61bd22be260dfb2b3d37de2e3334b25ff53aacbf9b6b41aecb88a287ae308d9fd65950e7c850ab023569d08cb1c31cceda4182cb667c3b61a984406e
7
- data.tar.gz: 670454a6c3e5dbe69dcb511e68acbb63b2b558410a3ae0268400918dd11e3ae4d320fb1bd7d876cade2b7313132c925befcd51ad0bd023bfb826f36ee9d127b9
6
+ metadata.gz: '09f0860be72310e44989febad8997e4fce1a82bf8d2986cfa3dfe56a0c9e55414d74f19a6dae35636aa5871c5778baad7b8776627835a30bd356bbb251fc4e32'
7
+ data.tar.gz: d6d42d010bd3e216dd1f1c84d60f86b4944f43a64d48db2cd613fddb189c7ac6ef079b713a86dd0b95a3551756b15a4868287c1af836fc0ada87efc6e1efc630
@@ -1,5 +1,15 @@
1
1
  ## Unreleased
2
2
 
3
+ ## v1.7.3 (2020-07-06)
4
+
5
+ - [#111] Add configuration callback `select_account_for_resource_owner` to support the `prompt=select_account` param
6
+ - [#112] Add grant_types_supported to discovery response
7
+ - [#114] Fix user_info endpoint when used in api mode
8
+ - [#116] Support Doorkeeper API (> 5.4) for registering custom grant flows.
9
+ - [#117] Fix migration template to use Rails migrations DSL for association.
10
+ - [#118] Use fragment urls for implicit flow error redirects (thanks to @joeljunstrom)
11
+ - [#119] Execute end_session_endpoint in the controllers context (thanks to @joeljunstrom)
12
+
3
13
  ## v1.7.2 (2020-05-20)
4
14
 
5
15
  ### Changes
data/README.md CHANGED
@@ -139,6 +139,10 @@ The following settings are optional, but recommended for better client compatibi
139
139
  - Defines how to trigger reauthentication for the current user (e.g. display a password prompt, or sign-out the user and redirect to the login form).
140
140
  - Required to support the `max_age` and `prompt=login` parameters.
141
141
  - The block is executed in the controller's scope, so you have access to methods like `params`, `redirect_to` etc.
142
+ - `select_account_for_resource_owner`
143
+ - Defines how to trigger account selection to choose the current login user.
144
+ - Required to support the `prompt=select_account` parameter.
145
+ - The block is executed in the controller's scope, so you have access to methods like `params`, `redirect_to` etc.
142
146
 
143
147
  The following settings are optional:
144
148
 
@@ -155,6 +159,7 @@ The following settings are optional:
155
159
  - `end_session_endpoint`
156
160
  - The URL that the user is redirected to after ending the session on the client.
157
161
  - Used by implementations like https://github.com/IdentityModel/oidc-client-js.
162
+ - The block is executed in the controller's scope, so you have access to your route helpers.
158
163
 
159
164
  ### Scopes
160
165
 
@@ -38,16 +38,13 @@ module Doorkeeper
38
38
 
39
39
  # TODO: support id_token response type
40
40
  response_types_supported: doorkeeper.authorization_response_types,
41
- response_modes_supported: ['query', 'fragment'],
41
+ response_modes_supported: %w[query fragment],
42
+ grant_types_supported: grant_types_supported(doorkeeper),
42
43
 
43
- token_endpoint_auth_methods_supported: [
44
- 'client_secret_basic',
45
- 'client_secret_post',
46
-
47
- # TODO: look into doorkeeper-jwt_assertion for these
48
- # 'client_secret_jwt',
49
- # 'private_key_jwt'
50
- ],
44
+ # TODO: look into doorkeeper-jwt_assertion for these
45
+ # 'client_secret_jwt',
46
+ # 'private_key_jwt'
47
+ token_endpoint_auth_methods_supported: %w[client_secret_basic client_secret_post],
51
48
 
52
49
  subject_types_supported: openid_connect.subject_types_supported,
53
50
 
@@ -73,6 +70,12 @@ module Doorkeeper
73
70
  }.compact
74
71
  end
75
72
 
73
+ def grant_types_supported(doorkeeper)
74
+ grant_types_supported = doorkeeper.grant_flows
75
+ grant_types_supported << 'refresh_token' if doorkeeper.refresh_token_enabled?
76
+ grant_types_supported
77
+ end
78
+
76
79
  def webfinger_response
77
80
  {
78
81
  subject: params.require(:resource),
@@ -3,7 +3,9 @@
3
3
  module Doorkeeper
4
4
  module OpenidConnect
5
5
  class UserinfoController < ::Doorkeeper::ApplicationController
6
- skip_before_action :verify_authenticity_token
6
+ unless Doorkeeper.config.api_only
7
+ skip_before_action :verify_authenticity_token
8
+ end
7
9
  before_action -> { doorkeeper_authorize! :openid }
8
10
 
9
11
  def show
@@ -19,4 +19,5 @@ en:
19
19
  resource_owner_from_access_token_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.resource_owner_from_access_token missing configuration.'
20
20
  auth_time_from_resource_owner_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.auth_time_from_resource_owner missing configuration.'
21
21
  reauthenticate_resource_owner_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.reauthenticate_resource_owner missing configuration.'
22
+ select_account_for_resource_owner_not_configured: 'Failure due to Doorkeeper::OpenidConnect.configure.select_account_for_resource_owner missing configuration.'
22
23
  subject_not_configured: 'ID Token generation failed due to Doorkeeper::OpenidConnect.configure.subject missing configuration.'
@@ -22,6 +22,7 @@ require 'doorkeeper/openid_connect/errors'
22
22
  require 'doorkeeper/openid_connect/id_token'
23
23
  require 'doorkeeper/openid_connect/id_token_token'
24
24
  require 'doorkeeper/openid_connect/user_info'
25
+ require 'doorkeeper/openid_connect/response_mode'
25
26
  require 'doorkeeper/openid_connect/version'
26
27
 
27
28
  require 'doorkeeper/openid_connect/helpers/controller'
@@ -63,5 +64,27 @@ module Doorkeeper
63
64
  key.slice(:kty, :kid)
64
65
  end
65
66
  end
67
+
68
+ if defined?(::Doorkeeper::GrantFlow)
69
+ Doorkeeper::GrantFlow.register(
70
+ :id_token,
71
+ response_type_matches: 'id_token',
72
+ response_type_strategy: Doorkeeper::OpenidConnect::IdToken,
73
+ )
74
+
75
+ Doorkeeper::GrantFlow.register(
76
+ 'id_token token',
77
+ response_type_matches: 'id_token token',
78
+ response_type_strategy: Doorkeeper::OpenidConnect::IdTokenToken,
79
+ )
80
+
81
+ Doorkeeper::GrantFlow.register_alias(
82
+ 'implicit_oidc', as: ['implicit', 'id_token', 'id_token token']
83
+ )
84
+ else
85
+ # TODO: drop this and corresponding file when we will set minimal
86
+ # required Doorkeeper version to 5.5.
87
+ Doorkeeper::Config.prepend OpenidConnect::ResponseTypeConfig
88
+ end
66
89
  end
67
90
  end
@@ -115,6 +115,10 @@ module Doorkeeper
115
115
  raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.reauthenticate_resource_owner_not_configured')
116
116
  }
117
117
 
118
+ option :select_account_for_resource_owner, default: lambda { |*_|
119
+ raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.select_account_for_resource_owner_not_configured')
120
+ }
121
+
118
122
  option :subject, default: lambda { |*_|
119
123
  raise Errors::InvalidConfiguration, I18n.translate('doorkeeper.openid_connect.errors.messages.subject_not_configured')
120
124
  }
@@ -26,7 +26,6 @@ module Doorkeeper
26
26
  class LoginRequired < OpenidConnectError; end
27
27
  class ConsentRequired < OpenidConnectError; end
28
28
  class InteractionRequired < OpenidConnectError; end
29
- class AccountSelectionRequired < OpenidConnectError; end
30
29
  end
31
30
  end
32
31
  end
@@ -43,12 +43,14 @@ module Doorkeeper
43
43
  name: exception.type,
44
44
  state: params[:state],
45
45
  redirect_uri: params[:redirect_uri],
46
+ response_on_fragment: pre_auth.response_on_fragment?,
46
47
  )
47
48
  else
48
49
  ::Doorkeeper::OAuth::ErrorResponse.new(
49
50
  name: exception.type,
50
51
  state: params[:state],
51
52
  redirect_uri: params[:redirect_uri],
53
+ response_on_fragment: pre_auth.response_on_fragment?,
52
54
  )
53
55
  end
54
56
 
@@ -75,8 +77,7 @@ module Doorkeeper
75
77
  when 'consent'
76
78
  render :new
77
79
  when 'select_account'
78
- # TODO: let the user implement this
79
- raise Errors::AccountSelectionRequired
80
+ select_account_for_oidc_resource_owner(owner)
80
81
  else
81
82
  raise Errors::InvalidRequest
82
83
  end
@@ -97,16 +98,21 @@ module Doorkeeper
97
98
  end
98
99
  end
99
100
 
100
- def reauthenticate_oidc_resource_owner(owner)
101
+ def return_without_oidc_prompt_param(prompt_value)
101
102
  return_to = URI.parse(request.path)
102
103
  return_to.query = request.query_parameters.tap do |params|
103
- params['prompt'] = params['prompt'].to_s.sub(/\blogin\s*\b/, '').strip
104
+ params['prompt'] = params['prompt'].to_s.sub(/\b#{prompt_value}\s*\b/, '').strip
104
105
  params.delete('prompt') if params['prompt'].blank?
105
106
  end.to_query
107
+ return_to.to_s
108
+ end
109
+
110
+ def reauthenticate_oidc_resource_owner(owner)
111
+ return_to = return_without_oidc_prompt_param('login')
106
112
 
107
113
  instance_exec(
108
114
  owner,
109
- return_to.to_s,
115
+ return_to,
110
116
  &Doorkeeper::OpenidConnect.configuration.reauthenticate_resource_owner
111
117
  )
112
118
 
@@ -116,6 +122,16 @@ module Doorkeeper
116
122
  def oidc_consent_required?
117
123
  !skip_authorization? && !matching_token?
118
124
  end
125
+
126
+ def select_account_for_oidc_resource_owner(owner)
127
+ return_to = return_without_oidc_prompt_param('select_account')
128
+
129
+ instance_exec(
130
+ owner,
131
+ return_to,
132
+ &Doorkeeper::OpenidConnect.configuration.select_account_for_resource_owner
133
+ )
134
+ end
119
135
  end
120
136
  end
121
137
  end
@@ -26,10 +26,8 @@ module Doorkeeper
26
26
  end
27
27
  end
28
28
 
29
- private
30
-
31
29
  def response_on_fragment?
32
- response_type == 'token' || response_type == 'id_token' || response_type == 'id_token token'
30
+ Doorkeeper::OpenidConnect::ResponseMode.new(response_type).fragment?
33
31
  end
34
32
  end
35
33
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module OpenidConnect
5
+ class ResponseMode
6
+ attr_reader :type
7
+
8
+ def initialize(response_type)
9
+ @type = response_type
10
+ end
11
+
12
+ def fragment?
13
+ mode == 'fragment'
14
+ end
15
+
16
+ def query?
17
+ mode == 'query'
18
+ end
19
+
20
+ def mode
21
+ case type
22
+ when 'token', 'id_token', 'id_token token'
23
+ 'fragment'
24
+ else
25
+ 'query'
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -14,6 +14,4 @@ module Doorkeeper
14
14
  end
15
15
  end
16
16
  end
17
-
18
- Config.prepend OpenidConnect::ResponseTypeConfig
19
17
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Doorkeeper
4
4
  module OpenidConnect
5
- VERSION = '1.7.2'
5
+ VERSION = '1.7.3'
6
6
  end
7
7
  end
@@ -28,6 +28,18 @@ Doorkeeper::OpenidConnect.configure do
28
28
  # redirect_to new_user_session_url
29
29
  end
30
30
 
31
+ # Depending on your configuration, a DoubleRenderError could be raised
32
+ # if render/redirect_to is called at some point before this callback is executed.
33
+ # To avoid the DoubleRenderError, you could add these two lines at the beginning
34
+ # of this callback: (Reference: https://github.com/rails/rails/issues/25106)
35
+ # self.response_body = nil
36
+ # @_response_body = nil
37
+ select_account_for_resource_owner do |resource_owner, return_to|
38
+ # Example implementation:
39
+ # store_location_for resource_owner, return_to
40
+ # redirect_to account_select_url
41
+ end
42
+
31
43
  subject do |resource_owner, application|
32
44
  # Example implementation:
33
45
  # resource_owner.id
@@ -1,7 +1,7 @@
1
1
  class CreateDoorkeeperOpenidConnectTables < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :oauth_openid_requests do |t|
4
- t.integer :access_grant_id, null: false
4
+ t.references :access_grant, null: false, index: true
5
5
  t.string :nonce, null: false
6
6
  end
7
7
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doorkeeper-openid_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 1.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Dengler
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-05-20 00:00:00.000000000 Z
12
+ date: 2020-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: doorkeeper
@@ -157,6 +157,7 @@ files:
157
157
  - lib/doorkeeper/openid_connect/rails/routes.rb
158
158
  - lib/doorkeeper/openid_connect/rails/routes/mapper.rb
159
159
  - lib/doorkeeper/openid_connect/rails/routes/mapping.rb
160
+ - lib/doorkeeper/openid_connect/response_mode.rb
160
161
  - lib/doorkeeper/openid_connect/response_types_config.rb
161
162
  - lib/doorkeeper/openid_connect/user_info.rb
162
163
  - lib/doorkeeper/openid_connect/version.rb
@@ -185,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
186
  - !ruby/object:Gem::Version
186
187
  version: '0'
187
188
  requirements: []
188
- rubygems_version: 3.0.2
189
+ rubygems_version: 3.0.3
189
190
  signing_key:
190
191
  specification_version: 4
191
192
  summary: OpenID Connect extension for Doorkeeper.