MishkaCmsCore.Accounts (Mishka CMS Core v0.0.1)

Copy Markdown View Source

MishkaCms Accounts Domain - Complete user authentication and authorization system.

This Ash domain provides comprehensive user management capabilities including authentication, authorization, permission management, and secure token handling for the MishkaCms platform. Built with security-first principles and modern authentication patterns.

Domain Architecture

Organizes user and security resources into a cohesive system:

  • User Management: User registration, authentication, and profile management
  • Permission System: Role-based access control with granular permissions
  • Token Management: Secure token generation and validation
  • Password Security: Secure password handling with reset capabilities
  • API Integration: RESTful endpoints for authentication workflows

Resource Organization

MishkaCmsCore.Accounts/
├── User - Core user accounts with authentication
├── Token - Secure token management for sessions/API access
├── Permission - System permissions and capabilities
└── UserPermission - User-permission relationship mapping

Key Features

  • Password Authentication: Secure password-based user authentication
  • Token-based API Access: JWT or similar token system for API authentication
  • Permission Management: Granular permission assignment and validation
  • Password Reset: Secure password reset via email tokens
  • User Registration: Streamlined user onboarding process
  • Profile Management: User profile updates and management
  • Admin Controls: Administrative user and permission management

Permission Management

An admin permission is admin:<surface>:<area>, a plain string written where it is used. Accounts are managed with the user area, and what they hold with the permission area:

alias MishkaCmsCore.Accounts.Checks.AccessPermissions

# Grant an account what the granter holds (`admin:<surface>:permission`, within its ceiling)
user
|> Ash.Changeset.for_update(:assign_permissions, %{permission_ids: ids}, actor: granter)
|> Ash.update()

# Ask what a user holds
AccessPermissions.match?(user, %{}, permissions: ["admin:dashboard:runtime:page"])

Security Features

Password Security

  • Secure password hashing (likely Argon2 or bcrypt)
  • Password strength validation
  • Secure password reset workflow
  • Protection against timing attacks

Token Security

  • Secure token generation and validation
  • Token expiration and refresh capabilities
  • API endpoint protection via token authentication
  • Automatic token metadata in authentication responses

Permission System

  • Granular permission assignment
  • Role-based access control (RBAC)
  • Permission validation middleware
  • Administrative permission management

Error Handling

The domain includes comprehensive error handling:

  • Authentication failures with proper HTTP status codes
  • Invalid token handling
  • Permission denied responses
  • User not found scenarios
  • Password reset token validation

Multi-tenant Considerations

  • Users can have different permissions per site/tenant
  • Token validation respects tenant boundaries
  • Permission checks include tenant context
  • Administrative operations scoped to appropriate tenants

Production Considerations

  • Monitor authentication attempt rates and patterns
  • Implement proper session timeout policies
  • Regular audit of user permissions and access
  • Secure token storage and transmission
  • Password policy enforcement
  • Account lockout policies for security
  • Regular cleanup of expired tokens
  • Comprehensive audit logging of authentication events

Summary

Functions

page(page, request) deprecated

Functions

aggregate(query, aggregate_or_aggregates, opts \\ [])

This function is deprecated. Use `Ash.aggregate/3` instead.

aggregate!(query, aggregate_or_aggregates, opts \\ [])

This function is deprecated. Use `Ash.aggregate!/3` instead.

avg(query, field, opts \\ [])

This function is deprecated. Use `Ash.avg/3` instead.

avg!(query, field, opts \\ [])

This function is deprecated. Use `Ash.avg!/3` instead.

bulk_create(inputs, resource, action, opts \\ [])

This function is deprecated. Use `Ash.bulk_create/4` instead.

bulk_create!(inputs, resource, action, opts \\ [])

This function is deprecated. Use `Ash.bulk_create!/4` instead.

bulk_destroy(stream_or_query, action, input, opts \\ [])

This function is deprecated. Use `Ash.bulk_destroy/4` instead.

bulk_destroy!(stream_or_query, action, input, opts \\ [])

This function is deprecated. Use `Ash.bulk_destroy!/4` instead.

bulk_update(stream_or_query, action, input, opts \\ [])

This function is deprecated. Use `Ash.bulk_update/4` instead.

bulk_update!(stream_or_query, action, input, opts \\ [])

This function is deprecated. Use `Ash.bulk_update!/4` instead.

calculate(resource, calculation, opts \\ [])

This function is deprecated. Use `Ash.calculate/3` instead.

calculate!(resource, calculation, opts \\ [])

This function is deprecated. Use `Ash.calculate!/3` instead.

can(action_or_query_or_changeset, actor, opts \\ [])

This function is deprecated. Use `Ash.can/3` instead.
@spec can(
  action_or_query_or_changeset ::
    Ash.Query.t()
    | Ash.Changeset.t()
    | {Ash.Resource.t(), atom() | Ash.Resource.Actions.action()},
  actor :: term(),
  opts :: Keyword.t()
) ::
  {:ok, boolean() | :maybe}
  | {:ok, true, Ash.Changeset.t() | Ash.Query.t()}
  | {:ok, true, Ash.Changeset.t(), Ash.Query.t()}
  | {:ok, false, Exception.t()}
  | {:error, term()}

can?(query_or_changeset_or_action, actor, opts \\ [])

This function is deprecated. Use `Ash.can?/3` instead.
@spec can?(
  query_or_changeset_or_action ::
    Ash.Query.t()
    | Ash.Changeset.t()
    | {Ash.Resource.t(), atom() | Ash.Resource.Actions.action()},
  actor :: term(),
  opts :: Keyword.t()
) :: boolean() | no_return()

count(query, opts \\ [])

This function is deprecated. Use `Ash.count/2` instead.

count!(query, opts \\ [])

This function is deprecated. Use `Ash.count!/2` instead.

create(changeset, opts \\ [])

This function is deprecated. Use `Ash.create/2` instead.

create!(changeset, opts \\ [])

This function is deprecated. Use `Ash.create!/2` instead.

default_short_name()

destroy(record, opts \\ [])

This function is deprecated. Use `Ash.destroy/2` instead.

destroy!(record, opts \\ [])

This function is deprecated. Use `Ash.destroy!/2` instead.

exists(query, opts \\ [])

This function is deprecated. Use `Ash.exists/2` instead.

exists?(query, opts \\ [])

This function is deprecated. Use `Ash.exists?/2` instead.

first(query, field, opts \\ [])

This function is deprecated. Use `Ash.first/3` instead.

first!(query, field, opts \\ [])

This function is deprecated. Use `Ash.first!/3` instead.

get(resource, id_or_filter, opts \\ [])

This function is deprecated. Use `Ash.get/3` instead.

get!(resource, id_or_filter, opts \\ [])

This function is deprecated. Use `Ash.get!/3` instead.

json_api_match_route(arg1, arg2)

list(query, field, opts \\ [])

This function is deprecated. Use `Ash.list/3` instead.

list!(query, field, opts \\ [])

This function is deprecated. Use `Ash.list!/3` instead.

load(data, query, opts \\ [])

This function is deprecated. Use `Ash.load/3` instead.

load!(data, query, opts \\ [])

This function is deprecated. Use `Ash.load!/3` instead.

max(query, field, opts \\ [])

This function is deprecated. Use `Ash.max/3` instead.

max!(query, field, opts \\ [])

This function is deprecated. Use `Ash.max!/3` instead.

min(query, field, opts \\ [])

This function is deprecated. Use `Ash.min/3` instead.

min!(query, field, opts \\ [])

This function is deprecated. Use `Ash.min!/3` instead.

page(page, request)

This function is deprecated. Use `Ash.page/2` instead.

page!(page, request)

This function is deprecated. Use `Ash.page!/2` instead.

read(query, opts \\ [])

This function is deprecated. Use `Ash.read/2` instead.

read!(query, opts \\ [])

This function is deprecated. Use `Ash.read!/2` instead.

read_one(query, opts \\ [])

This function is deprecated. Use `Ash.read_one/2` instead.

read_one!(query, opts \\ [])

This function is deprecated. Use `Ash.read_one!/2` instead.

reload(record, opts \\ [])

This function is deprecated. Use `Ash.reload/2` instead.

reload!(record, opts \\ [])

This function is deprecated. Use `Ash.reload!/2` instead.

run_action(input, opts \\ [])

This function is deprecated. Use `Ash.run_action/2` instead.

run_action!(input, opts \\ [])

This function is deprecated. Use `Ash.run_action/2` instead.

stream!(query, opts \\ [])

This function is deprecated. Use `Ash.stream!/2` instead.

sum(query, field, opts \\ [])

This function is deprecated. Use `Ash.sum/3` instead.

sum!(query, field, opts \\ [])

This function is deprecated. Use `Ash.sum!/3` instead.

update(changeset, opts \\ [])

This function is deprecated. Use `Ash.update/2` instead.

update!(changeset, opts \\ [])

This function is deprecated. Use `Ash.update!/2` instead.