Extract OidcScopes::SUPPORTED as the shared scope list
The supported-scope list lived on OidcController, so the device authorization controller (and a test) had to reach across into OidcController::SUPPORTED_SCOPES. Move it to a shared OidcScopes::SUPPORTED module — one source of truth for the OIDC controller, the device flow, and consent handling — and update every reference. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Q4ATZHoMCWqvSpE2yYoie
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f65f8da2e7
commit
6c4be7199c
@@ -80,7 +80,7 @@ class DeviceAuthorizationsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def granted_scopes(device_code)
|
def granted_scopes(device_code)
|
||||||
device_code.scope.to_s.split & OidcController::SUPPORTED_SCOPES
|
device_code.scope.to_s.split & OidcScopes::SUPPORTED
|
||||||
end
|
end
|
||||||
|
|
||||||
def record_consent(device_code, user)
|
def record_consent(device_code, user)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
class OidcController < ApplicationController
|
class OidcController < ApplicationController
|
||||||
SUPPORTED_SCOPES = %w[openid profile email groups offline_access].freeze
|
|
||||||
|
|
||||||
# Grant types this authorization server supports. Single source of truth:
|
# Grant types this authorization server supports. Single source of truth:
|
||||||
# advertised in discovery (grant_types_supported), accepted at dynamic client
|
# advertised in discovery (grant_types_supported), accepted at dynamic client
|
||||||
@@ -69,7 +68,7 @@ class OidcController < ApplicationController
|
|||||||
grant_types_supported: SUPPORTED_GRANT_TYPES,
|
grant_types_supported: SUPPORTED_GRANT_TYPES,
|
||||||
subject_types_supported: ["pairwise"],
|
subject_types_supported: ["pairwise"],
|
||||||
id_token_signing_alg_values_supported: ["RS256"],
|
id_token_signing_alg_values_supported: ["RS256"],
|
||||||
scopes_supported: SUPPORTED_SCOPES,
|
scopes_supported: OidcScopes::SUPPORTED,
|
||||||
token_endpoint_auth_methods_supported: ["client_secret_post", "client_secret_basic"],
|
token_endpoint_auth_methods_supported: ["client_secret_post", "client_secret_basic"],
|
||||||
claims_supported: [
|
claims_supported: [
|
||||||
"sub", # Always included
|
"sub", # Always included
|
||||||
@@ -127,7 +126,7 @@ class OidcController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Only accept scopes we support (mirrors the authorize endpoint).
|
# Only accept scopes we support (mirrors the authorize endpoint).
|
||||||
requested_scope = (params[:scope].to_s.split & SUPPORTED_SCOPES).join(" ")
|
requested_scope = (params[:scope].to_s.split & OidcScopes::SUPPORTED).join(" ")
|
||||||
requested_scope = "openid" if requested_scope.blank?
|
requested_scope = "openid" if requested_scope.blank?
|
||||||
|
|
||||||
# PKCE is optional but recommended for device flow (RFC 8628 §5.5). If the
|
# PKCE is optional but recommended for device flow (RFC 8628 §5.5). If the
|
||||||
@@ -240,7 +239,7 @@ class OidcController < ApplicationController
|
|||||||
# Normalize requested scopes to the set we support. Needed here so claims
|
# Normalize requested scopes to the set we support. Needed here so claims
|
||||||
# validation below can check claim→scope coverage against what will actually
|
# validation below can check claim→scope coverage against what will actually
|
||||||
# be granted.
|
# be granted.
|
||||||
requested_scopes = scope.split(" ") & SUPPORTED_SCOPES
|
requested_scopes = scope.split(" ") & OidcScopes::SUPPORTED
|
||||||
scope = requested_scopes.join(" ")
|
scope = requested_scopes.join(" ")
|
||||||
|
|
||||||
# Parse claims parameter (JSON string) for OIDC claims request
|
# Parse claims parameter (JSON string) for OIDC claims request
|
||||||
@@ -490,7 +489,7 @@ class OidcController < ApplicationController
|
|||||||
|
|
||||||
user = Current.session.user
|
user = Current.session.user
|
||||||
|
|
||||||
requested_scopes = oauth_params["scope"].split(" ") & SUPPORTED_SCOPES
|
requested_scopes = oauth_params["scope"].split(" ") & OidcScopes::SUPPORTED
|
||||||
parsed_claims = begin
|
parsed_claims = begin
|
||||||
JSON.parse(oauth_params["claims_requests"])
|
JSON.parse(oauth_params["claims_requests"])
|
||||||
rescue
|
rescue
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Single source of truth for the OAuth/OIDC scopes this IdP supports. Shared by
|
||||||
|
# the OIDC controller (discovery + authorize/consent), the device authorization
|
||||||
|
# flow, and consent handling, so no controller has to reach into another for the
|
||||||
|
# list.
|
||||||
|
module OidcScopes
|
||||||
|
SUPPORTED = %w[openid profile email groups offline_access].freeze
|
||||||
|
end
|
||||||
@@ -12,7 +12,7 @@ class OidcHelperTest < ActionView::TestCase
|
|||||||
|
|
||||||
test "scope_description covers every SUPPORTED_SCOPE (so the consent screens can't silently drop one)" do
|
test "scope_description covers every SUPPORTED_SCOPE (so the consent screens can't silently drop one)" do
|
||||||
user = User.new(email_address: "person@example.com")
|
user = User.new(email_address: "person@example.com")
|
||||||
OidcController::SUPPORTED_SCOPES.each do |scope|
|
OidcScopes::SUPPORTED.each do |scope|
|
||||||
assert_not_equal scope, scope_description(scope, user: user),
|
assert_not_equal scope, scope_description(scope, user: user),
|
||||||
"#{scope} has no description and would render as its raw name"
|
"#{scope} has no description and would render as its raw name"
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user