6c58fd9bdd
- Create Identity credentials - Add management UI and registration flow
72 lines
2.0 KiB
Ruby
72 lines
2.0 KiB
Ruby
class Users::CredentialsController < ApplicationController
|
|
before_action :set_user
|
|
before_action :set_webauthn_host
|
|
|
|
def index
|
|
@credentials = identity.credentials.order(created_at: :desc)
|
|
end
|
|
|
|
def new
|
|
@creation_options = creation_options
|
|
session[:webauthn_challenge] = @creation_options.challenge
|
|
end
|
|
|
|
def create
|
|
public_key_credential = ActionPack::WebAuthn::PublicKeyCredential.create(
|
|
client_data_json: decode64(credential_response[:client_data_json]),
|
|
attestation_object: decode64(credential_response[:attestation_object]),
|
|
challenge: session.delete(:webauthn_challenge),
|
|
origin: request.base_url,
|
|
transports: Array(credential_response[:transports])
|
|
)
|
|
|
|
identity.credentials.create!(
|
|
name: params.dig(:credential, :name),
|
|
credential_id: public_key_credential.id,
|
|
public_key: public_key_credential.public_key.to_der,
|
|
sign_count: public_key_credential.sign_count,
|
|
transports: public_key_credential.transports
|
|
)
|
|
|
|
redirect_to user_credentials_path(@user)
|
|
end
|
|
|
|
def destroy
|
|
identity.credentials.find(params[:id]).destroy!
|
|
redirect_to user_credentials_path(@user)
|
|
end
|
|
|
|
private
|
|
def set_user
|
|
@user = Current.identity.users.find(params[:user_id])
|
|
end
|
|
|
|
def set_webauthn_host
|
|
ActionPack::WebAuthn::Current.host = request.host
|
|
end
|
|
|
|
def identity
|
|
@user.identity
|
|
end
|
|
|
|
def creation_options
|
|
ActionPack::WebAuthn::PublicKeyCredential::CreationOptions.new(
|
|
id: identity.id,
|
|
name: identity.email_address,
|
|
display_name: @user.name,
|
|
resident_key: :required,
|
|
exclude_credentials: identity.credentials.map { |c| ExcludeCredential.new(c.credential_id, c.transports) }
|
|
)
|
|
end
|
|
|
|
def credential_response
|
|
params.expect(credential: { response: [ :client_data_json, :attestation_object, transports: [] ] })[:response]
|
|
end
|
|
|
|
def decode64(value)
|
|
Base64.urlsafe_decode64(value)
|
|
end
|
|
|
|
ExcludeCredential = Struct.new(:id, :transports)
|
|
end
|