Files
ubicloud/routes/account.rb
Jeremy Evans b780fb582e Support connecting and disconnecting OIDC authentication support for accounts
This is based on the existing support for connecting social logins
to accounts.  Connecting needs to be handled differently, since
we don't want to show all accounts every OIDC provider that is
supported (OIDC providers should be considered internal).

As OIDC providers are named with the OidcProvider ubid, add
omniauth_provider_name helper method that returns the display name
for the provider, and use that in the flash messages.

This makes a change to the layout so it will use the @page_message
style page if logged in and @use_page_message is set. I'm not sure
whether @page_message is already used on any page shown when logged
in.  If not, we could probably remove @use_page_message and have
the presence of @page_message trigger the alternative layout.
2025-07-08 00:10:06 +09:00

58 lines
2.2 KiB
Ruby

# frozen_string_literal: true
class Clover
hash_branch("account") do |r|
r.web do
r.get true do
no_authorization_needed
r.redirect "/account/multifactor-manage"
end
r.on "login-method" do
r.get true do
no_authorization_needed
@identities = current_account.identities_dataset.select_hash(:provider, :uid)
social_login_providers = omniauth_providers.map { |provider,| provider.to_s }
@oidc_identities = @identities.reject { |provider,| social_login_providers.include?(provider) }
@oidc_identity_names = OidcProvider.where(id: @oidc_identities.keys.map! { UBID.to_uuid(it) }).select_hash(:id, :display_name)
view "account/login_method"
end
r.get "oidc" do
no_authorization_needed
unless (id = typecast_params.ubid_uuid("provider")) && (oidc_provider = OidcProvider[id])
flash[:error] = "No valid OIDC provider with that ID"
r.redirect "/account/login-method"
end
r.redirect "/auth/#{oidc_provider.ubid}?redirect_url=/account/login-method"
end
r.post "disconnect" do
no_authorization_needed
no_audit_log
provider, uid = typecast_params.nonempty_str(["provider", "uid"])
identities = current_account.identities
unless identities.length > (rodauth.has_password? ? 0 : 1)
flash[:error] = "You must have at least one login method"
r.redirect "/account/login-method"
end
if provider == "password"
DB[:account_password_hashes].where(id: current_account.id).delete
DB[:account_previous_password_hashes].where(account_id: current_account.id).delete
flash[:notice] = "Your password has been deleted"
elsif (identity = identities.find { it.provider == provider && it.uid == uid })
identity.destroy
flash[:notice] = "Your account has been disconnected from #{omniauth_provider_name(provider)}"
else
flash[:error] = "Your account already has been disconnected from #{omniauth_provider_name(provider)}"
end
r.redirect "/account/login-method"
end
end
end
end
end