defmodule Mv.Secrets do @moduledoc """ Secret provider for AshAuthentication. ## Purpose Provides runtime configuration secrets for Ash Authentication strategies, particularly for OIDC (Rauthy) authentication. ## Configuration Source Secrets are read via `Mv.Config` which prefers environment variables and falls back to Settings from the database: - OIDC_CLIENT_ID / settings.oidc_client_id - OIDC_CLIENT_SECRET / settings.oidc_client_secret - OIDC_BASE_URL / settings.oidc_base_url - OIDC_REDIRECT_URI / settings.oidc_redirect_uri When a value is nil, returns `{:error, MissingSecret}` so that AshAuthentication does not crash (e.g. URI.new(nil)) and can redirect to sign-in with an error. """ use AshAuthentication.Secret alias AshAuthentication.Errors.MissingSecret def secret_for( [:authentication, :strategies, :oidc, :client_id], resource, _opts, _meth ) do secret_or_error(Mv.Config.oidc_client_id(), resource, :client_id) end def secret_for( [:authentication, :strategies, :oidc, :redirect_uri], resource, _opts, _meth ) do secret_or_error(Mv.Config.oidc_redirect_uri(), resource, :redirect_uri) end def secret_for( [:authentication, :strategies, :oidc, :client_secret], resource, _opts, _meth ) do secret_or_error(Mv.Config.oidc_client_secret(), resource, :client_secret) end def secret_for( [:authentication, :strategies, :oidc, :base_url], resource, _opts, _meth ) do secret_or_error(Mv.Config.oidc_base_url(), resource, :base_url) end defp secret_or_error(nil, resource, key) do path = [:authentication, :strategies, :oidc, key] {:error, MissingSecret.exception(path: path, resource: resource)} end defp secret_or_error(value, resource, key) when is_binary(value) do if String.trim(value) == "" do secret_or_error(nil, resource, key) else {:ok, value} end end end