Created
July 29, 2025 13:45
-
-
Save barnabasJ/187c92098cee68217608114845993c7d to your computer and use it in GitHub Desktop.
ash user for discord bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Steward.Accounts.User do | |
| @moduledoc """ | |
| User resource for account management. | |
| Represents users of the system with authentication capabilities. | |
| """ | |
| use Ash.Resource, | |
| otp_app: :steward, | |
| domain: Steward.Accounts, | |
| data_layer: AshPostgres.DataLayer, | |
| authorizers: [Ash.Policy.Authorizer], | |
| extensions: [AshAuthentication] | |
| authentication do | |
| add_ons do | |
| log_out_everywhere do | |
| apply_on_password_change? true | |
| end | |
| end | |
| tokens do | |
| enabled? true | |
| token_resource Steward.Accounts.Token | |
| signing_secret Steward.Secrets | |
| store_all_tokens? true | |
| require_token_presence_for_authentication? true | |
| end | |
| strategies do | |
| oauth2 :discord do | |
| client_id Steward.Secrets | |
| client_secret Steward.Secrets | |
| redirect_uri Steward.Secrets | |
| base_url "https://discord.com/api/v10" | |
| authorize_url "https://discord.com/oauth2/authorize" | |
| token_url "https://discord.com/api/v10/oauth2/token" | |
| user_url "https://discord.com/api/v10/users/@me" | |
| authorization_params scope: "identify email guilds" | |
| registration_enabled? true | |
| identity_resource Steward.Accounts.UserIdentity | |
| end | |
| end | |
| end | |
| postgres do | |
| table "users" | |
| repo Steward.Repo | |
| end | |
| actions do | |
| defaults [:read] | |
| create :create do | |
| description "Create a user with basic attributes (for testing)" | |
| accept [:email, :discord_id, :discord_username, :discord_avatar] | |
| end | |
| 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 | |
| create :register_with_discord do | |
| description "Register or sign in a user with Discord OAuth" | |
| accept [] | |
| argument :user_info, :map, allow_nil?: false | |
| argument :oauth_tokens, :map, allow_nil?: false | |
| upsert? true | |
| upsert_identity :discord_id | |
| upsert_fields [:email, :discord_username, :discord_avatar] | |
| change AshAuthentication.GenerateTokenChange | |
| change AshAuthentication.Strategy.OAuth2.IdentityChange | |
| change fn changeset, _context -> | |
| user_info = Ash.Changeset.get_argument(changeset, :user_info) | |
| changeset | |
| |> Ash.Changeset.change_attribute(:email, user_info["email"]) | |
| |> Ash.Changeset.change_attribute(:discord_id, user_info["id"]) | |
| |> Ash.Changeset.change_attribute(:discord_username, user_info["username"]) | |
| |> Ash.Changeset.change_attribute(:discord_avatar, user_info["avatar"]) | |
| end | |
| end | |
| create :from_discord do | |
| description "Create or update a user from Discord API data or struct" | |
| primary? true | |
| accept [:discord_id] | |
| argument :discord_struct, :map, description: "Optional Nostrum.Struct.User to use instead of fetching" | |
| upsert? true | |
| upsert_identity :discord_id | |
| upsert_fields [:discord_username, :discord_avatar] | |
| change Steward.Accounts.User.Changes.FromDiscord | |
| end | |
| end | |
| policies do | |
| bypass AshAuthentication.Checks.AshAuthenticationInteraction do | |
| authorize_if always() | |
| end | |
| bypass AshDiscord.Checks.AshDiscordInteraction do | |
| authorize_if always() | |
| end | |
| bypass actor_attribute_equals(:role, :bot) do | |
| authorize_if always() | |
| end | |
| policy always() do | |
| forbid_if always() | |
| end | |
| end | |
| attributes do | |
| uuid_primary_key :id | |
| attribute :email, :ci_string do | |
| allow_nil? false | |
| public? true | |
| end | |
| # Discord OAuth attributes | |
| attribute :discord_id, :integer do | |
| allow_nil? false | |
| public? true | |
| end | |
| attribute :discord_username, :string do | |
| allow_nil? false | |
| public? true | |
| end | |
| attribute :discord_avatar, :string do | |
| public? true | |
| end | |
| end | |
| identities do | |
| identity :email, [:email] | |
| identity :discord_id, [:discord_id] | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment