127 lines
3.7 KiB
Elixir
127 lines
3.7 KiB
Elixir
defmodule Mv.Accounts.User do
|
|
@moduledoc """
|
|
The ressource for keeping user-specific data related to the login process. It is used by AshAuthentication to handle the Authentication strategies like SSO.
|
|
"""
|
|
use Ash.Resource,
|
|
domain: Mv.Accounts,
|
|
data_layer: AshPostgres.DataLayer,
|
|
extensions: [AshAuthentication]
|
|
|
|
# authorizers: [Ash.Policy.Authorizer]
|
|
|
|
postgres do
|
|
table "users"
|
|
repo Mv.Repo
|
|
end
|
|
|
|
@doc """
|
|
AshAuthentication specific: Defines the strategies we want to use for authentication.
|
|
Currently password and SSO with Rauthy as OIDC provider
|
|
"""
|
|
authentication do
|
|
session_identifier Application.compile_env(:mv, :session_identifier, :jti)
|
|
|
|
tokens do
|
|
enabled? true
|
|
token_resource Mv.Accounts.Token
|
|
|
|
require_token_presence_for_authentication? Application.compile_env(
|
|
:mv,
|
|
:require_token_presence_for_authentication,
|
|
false
|
|
)
|
|
|
|
store_all_tokens? true
|
|
|
|
# signing_algorithm "EdDSA" -> https://git.local-it.org/local-it/mitgliederverwaltung/issues/87
|
|
|
|
signing_secret fn _, _ ->
|
|
{:ok, Application.get_env(:mv, :token_signing_secret)}
|
|
end
|
|
end
|
|
|
|
strategies do
|
|
oidc :rauthy do
|
|
client_id Mv.Secrets
|
|
base_url Mv.Secrets
|
|
redirect_uri Mv.Secrets
|
|
client_secret Mv.Secrets
|
|
auth_method :client_secret_jwt
|
|
code_verifier true
|
|
|
|
# id_token_signed_response_alg "EdDSA" #-> https://git.local-it.org/local-it/mitgliederverwaltung/issues/87
|
|
end
|
|
|
|
password :password do
|
|
identity_field :email
|
|
hash_provider AshAuthentication.BcryptProvider
|
|
confirmation_required? false
|
|
end
|
|
end
|
|
end
|
|
|
|
actions do
|
|
defaults [:read, :create, :destroy, :update]
|
|
|
|
read :get_by_subject do
|
|
description "Get a user by the subject claim in a JWT"
|
|
argument :subject, :string, allow_nil?: false
|
|
get? true
|
|
prepare AshAuthentication.Preparations.FilterBySubject
|
|
end
|
|
|
|
read :sign_in_with_rauthy do
|
|
argument :user_info, :map, allow_nil?: false
|
|
argument :oauth_tokens, :map, allow_nil?: false
|
|
prepare AshAuthentication.Strategy.OAuth2.SignInPreparation
|
|
|
|
filter expr(email == get_path(^arg(:user_info), [:email]))
|
|
end
|
|
|
|
create :register_with_rauthy do
|
|
argument :user_info, :map, allow_nil?: false
|
|
argument :oauth_tokens, :map, allow_nil?: false
|
|
upsert? true
|
|
upsert_identity :unique_email
|
|
|
|
change AshAuthentication.GenerateTokenChange
|
|
|
|
change fn changeset, _ctx ->
|
|
user_info = Ash.Changeset.get_argument(changeset, :user_info)
|
|
|
|
changeset
|
|
|> Ash.Changeset.change_attribute(:email, user_info["preferred_username"])
|
|
|> Ash.Changeset.change_attribute(:oidc_id, user_info["id"])
|
|
end
|
|
end
|
|
end
|
|
|
|
attributes do
|
|
uuid_primary_key :id
|
|
|
|
attribute :email, :ci_string, allow_nil?: false, public?: true
|
|
attribute :hashed_password, :string, sensitive?: true, allow_nil?: true
|
|
attribute :oidc_id, :string, allow_nil?: true
|
|
end
|
|
|
|
relationships do
|
|
belongs_to :member, Mv.Membership.Member
|
|
end
|
|
|
|
identities do
|
|
identity :unique_email, [:email]
|
|
identity :unique_oidc_id, [:oidc_id]
|
|
end
|
|
|
|
# You can customize this if you wish, but this is a safe default that
|
|
# only allows user data to be interacted with via AshAuthentication.
|
|
# policies do
|
|
# bypass AshAuthentication.Checks.AshAuthenticationInteraction do
|
|
# authorize_if(always())
|
|
# end
|
|
|
|
# policy always() do
|
|
# forbid_if(always())
|
|
# end
|
|
# end
|
|
end
|