Class: StandardId::Oauth::ClientRegistration

Inherits:
Object
  • Object
show all
Defined in:
lib/standard_id/oauth/client_registration.rb

Overview

RFC 7591 Dynamic Client Registration.

Maps a client metadata document (the JSON body of POST /oauth/register) onto a StandardId::ClientApplication, applying the engine’s security defaults (PKCE-forced public clients, S256, consent-by-default) and a conservative whitelist of grant/response types. Keeps the controller thin in the same flow-object style as the other lib/standard_id/oauth/ objects.

On success #call returns a Result carrying the persisted client plus the one-time plaintext secret (confidential clients only); on a metadata or redirect-uri problem it raises the matching RFC 7591 §3.2.2 error (InvalidRedirectUriError / InvalidClientMetadataError), which the controller renders as HTTP 400. A nil owner resolver while the feature is enabled raises ConfigurationError (a host-app bug, not client input).

Defined Under Namespace

Classes: Result

Constant Summary collapse

ALLOWED_GRANT_TYPES =

RFC 7591 grant_types we support. M2M (client_credentials) is deliberately excluded from DCR — self-registered clients are public/interactive.

%w[authorization_code refresh_token].freeze
ALLOWED_RESPONSE_TYPES =

Only the authorization-code response type is supported.

%w[code].freeze
PUBLIC_AUTH_METHOD =

token_endpoint_auth_method -> client_type mapping.

"none".freeze
CONFIDENTIAL_AUTH_METHODS =
%w[client_secret_basic client_secret_post].freeze
DEFAULT_AUTH_METHOD =
PUBLIC_AUTH_METHOD
DEFAULT_SCOPE =
"openid profile email".freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(metadata) ⇒ ClientRegistration

Returns a new instance of ClientRegistration.

Parameters:

  • metadata (Hash)

    RFC 7591 client metadata (symbolized or stringified keys)



40
41
42
# File 'lib/standard_id/oauth/client_registration.rb', line 40

def initialize()
  @metadata = ( || {}).to_h.symbolize_keys
end

Class Method Details

.call(metadata) ⇒ Object



44
45
46
# File 'lib/standard_id/oauth/client_registration.rb', line 44

def self.call()
  new().call
end

Instance Method Details

#callObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/standard_id/oauth/client_registration.rb', line 48

def call
  attrs = mapped_attributes
  client = StandardId::ClientApplication.new(attrs)

  secret_plaintext = nil
  StandardId::ClientApplication.transaction do
    client.save!
    if client.confidential?
      secret_plaintext = SecureRandom.hex(32)
      client.create_client_secret!(
        name: "Dynamic Registration Secret",
        client_secret: secret_plaintext
      )
    end
  end

  Result.new(client: client, client_secret: secret_plaintext, token_endpoint_auth_method: auth_method)
rescue ActiveRecord::RecordInvalid => e
  raise_for(e.record)
end