Extract OidcUserConsent.record! upsert for shared consent
The consent record is unique on user+application and shared between the browser authorization flow and device-flow approval. Centralize the upsert in OidcUserConsent.record!(merge:) so a narrower device request unions its scopes into any existing grant (merge: true) rather than overwriting it and wiping stored claims, while the browser consent screen records exactly the approved scopes (merge: false). scopes is now nil-safe for not-yet-saved records. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F7cwhwDJp3MJJDoNPVE6zq
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7eddea8356
commit
e3f0bd4cab
@@ -87,14 +87,14 @@ class DeviceAuthorizationsController < ApplicationController
|
||||
end
|
||||
|
||||
def record_consent(device_code, user)
|
||||
consent = OidcUserConsent.find_or_initialize_by(user: user, application: device_code.application)
|
||||
# Merge into any existing consent instead of overwriting it. The consent
|
||||
# record is shared with the browser flow (unique on user+application) and
|
||||
# scopes_granted is treated as a granted superset, so a narrower device
|
||||
# request must not shrink previously granted scopes or wipe stored claims.
|
||||
consent.scopes = consent.scopes_granted.to_s.split | granted_scopes(device_code)
|
||||
consent.claims_requests = {} if consent.new_record?
|
||||
consent.granted_at = Time.current
|
||||
consent.save!
|
||||
# merge: true — the consent record is shared with the browser flow, so a
|
||||
# narrower device request must not shrink previously granted scopes or wipe
|
||||
# stored claims.
|
||||
OidcUserConsent.record!(
|
||||
user: user,
|
||||
application: device_code.application,
|
||||
scopes: granted_scopes(device_code),
|
||||
merge: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user