API for managing user roles in PhoenixKit.
This module provides functions for assigning, removing, and querying user roles. It works with the role system to provide authorization capabilities.
Role Management
- Assign and remove roles from users
- Query users by role
- Check user permissions
- Bulk role operations
System Roles
PhoenixKit includes three built-in system roles:
- Owner: System owner with full access (assigned automatically to first user)
- Admin: Administrator with elevated privileges
- User: Standard user with basic access (default for new users)
Examples
# Check if user has a role
iex> user_has_role?(user, "Admin")
true
# Get all user roles
iex> get_user_roles(user)
["Admin", "User"]
# Assign a role to user
iex> assign_role(user, "Admin")
{:ok, %RoleAssignment{}}
# Get all users with a specific role
iex> users_with_role("Admin")
[%User{}, %User{}]
Summary
Functions
Assigns a role to a user.
Assigns roles to existing users who don't have any PhoenixKit roles.
Checks if user can be deactivated safely.
Counts active users with Owner role.
Counts users with a specific role.
Creates a new role.
Deletes a role safely.
Safely demotes a user from Admin or Owner role with protection.
Safely assigns Owner role to first user using database transaction.
Gets only custom (non-system) roles.
Gets comprehensive user statistics including activity and confirmation status.
Gets a role by its name.
Gets a single role by its UUID.
Gets role statistics for dashboard display.
Gets all active roles for a user.
Lists all roles.
Promotes a user to admin role.
Removes a role from a user by deleting the assignment.
Safely removes role with Owner protection.
Synchronizes user roles with a given list of role names.
Updates a role.
Checks if a user has a specific role.
Checks if a user has an "Admin" role.
Checks if a user has an "Owner" role.
Gets all users who have a specific role.
Functions
Assigns a role to a user.
Security
The Owner role cannot be assigned through this function to maintain system security. Only one Owner is automatically assigned during initialization.
Parameters
user: The user to assign the role torole_name: The name of the role to assignassigned_by(optional): The user who is assigning the role
Examples
iex> assign_role(user, "Admin")
{:ok, %RoleAssignment{}}
iex> assign_role(user, "Admin", assigned_by_user)
{:ok, %RoleAssignment{}}
iex> assign_role(user, "Owner")
{:error, :owner_role_protected}
iex> assign_role(user, "NonexistentRole")
{:error, :role_not_found}
Assigns roles to existing users who don't have any PhoenixKit roles.
This is useful for migration scenarios where PhoenixKit is installed into an existing application with users.
Parameters
opts: Options for role assignment:make_first_owner(default: true) - Make first user without roles an Owner
Returns
{:ok, stats}with assignment statistics{:error, reason}on failure
Examples
iex> assign_roles_to_existing_users()
{:ok, %{assigned_owner: 1, assigned_users: 5, total_processed: 6}}
Checks if user can be deactivated safely.
Prevents deactivation of last active Owner.
Parameters
user: User to check for deactivation
Examples
iex> can_deactivate_user?(last_owner)
{:error, :cannot_deactivate_last_owner}
iex> can_deactivate_user?(regular_user)
:ok
Counts active users with Owner role.
Critical security function - ensures we never have zero owners.
Examples
iex> count_active_owners()
1
Counts users with a specific role.
Parameters
role_name: The name of the role to count
Examples
iex> count_users_with_role("Admin")
3
Creates a new role.
Parameters
attrs: Attributes for the new role
Examples
iex> create_role(%{name: "Manager", description: "Department manager"})
{:ok, %Role{}}
iex> create_role(%{name: ""})
{:error, %Ecto.Changeset{}}
Deletes a role safely.
Prevents deletion of system roles and roles currently assigned to users.
Parameters
role: The role to delete
Examples
iex> delete_role(custom_role)
{:ok, %Role{}}
iex> delete_role(system_role)
{:error, :system_role_protected}
iex> delete_role(role_with_users)
{:error, :role_in_use}
Safely demotes a user from Admin or Owner role with protection.
Prevents demotion of last Owner to maintain system security.
Parameters
user: The user to demote
Examples
iex> demote_to_user(admin_user)
{:ok, %RoleAssignment{}}
iex> demote_to_user(last_owner)
{:error, :cannot_demote_last_owner}
Safely assigns Owner role to first user using database transaction.
This function prevents race conditions by using FOR UPDATE lock.
Parameters
user: The user to potentially make Owner
Returns
{:ok, :owner}if user became Owner{:ok, :user}if user became regular User{:error, reason}on failure
Examples
iex> ensure_first_user_is_owner(user)
{:ok, :owner}
Gets only custom (non-system) roles.
Examples
iex> get_custom_roles()
[%Role{name: "Manager"}, %Role{name: "Editor"}]
Gets comprehensive user statistics including activity and confirmation status.
Examples
iex> get_extended_stats()
%{
total_users: 10,
owner_count: 1,
admin_count: 2,
user_count: 7,
active_users: 8,
inactive_users: 2,
confirmed_users: 9,
pending_users: 1
}
Gets a role by its name.
Parameters
name: The name of the role
Examples
iex> get_role_by_name("Admin")
%Role{name: "Admin"}
iex> get_role_by_name("NonexistentRole")
nil
Gets a single role by its UUID.
Returns nil if no role is found.
Parameters
uuid: The UUID of the role to find
Examples
iex> get_role_by_uuid("01234567-89ab-cdef-0123-456789abcdef")
%Role{uuid: "01234567-89ab-cdef-0123-456789abcdef", name: "Editor"}
iex> get_role_by_uuid("nonexistent-uuid")
nil
Gets role statistics for dashboard display.
Examples
iex> get_role_stats()
%{
total_users: 10,
owner_count: 1,
admin_count: 2,
user_count: 7
}
Gets all active roles for a user.
Parameters
user: The user to get roles for
Examples
iex> get_user_roles(user)
["Admin", "User"]
iex> get_user_roles(user_with_no_roles)
[]
Lists all roles.
Examples
iex> list_roles()
[%Role{}, %Role{}, %Role{}]
Promotes a user to admin role.
Parameters
user: The user to promoteassigned_by(optional): The user who is doing the promotion
Examples
iex> promote_to_admin(user)
{:ok, %RoleAssignment{}}
Removes a role from a user by deleting the assignment.
Parameters
user: The user to remove the role fromrole_name: The name of the role to remove
Examples
iex> remove_role(user, "Admin")
{:ok, %RoleAssignment{}}
iex> remove_role(user, "NonexistentRole")
{:error, :assignment_not_found}
Safely removes role with Owner protection.
Prevents removal of Owner role if it would leave system without owners.
Parameters
user: User to remove role fromrole_name: Name of role to remove
Examples
iex> safely_remove_role(owner_user, "Owner")
{:error, :cannot_remove_last_owner}
iex> safely_remove_role(admin_user, "Admin")
{:ok, %RoleAssignment{}}
Synchronizes user roles with a given list of role names.
This function ensures the user has exactly the specified roles.
Parameters
user: The user to synchronize roles forrole_names: List of role names the user should have
Examples
iex> sync_user_roles(user, ["Admin", "Manager"])
{:ok, [%RoleAssignment{}, %RoleAssignment{}]}
Updates a role.
Parameters
role: The role to updateattrs: Attributes to update
Examples
iex> update_role(role, %{description: "Updated description"})
{:ok, %Role{}}
iex> update_role(system_role, %{name: "NewName"})
{:error, %Ecto.Changeset{}}
Checks if a user has a specific role.
Parameters
user: The user to checkrole_name: The name of the role to check for
Examples
iex> user_has_role?(user, "Admin")
true
iex> user_has_role?(user, "Owner")
false
Checks if a user has an "Admin" role.
Parameters
user: The user to check
Examples
iex> user_has_role_admin?(user)
true
Checks if a user has an "Owner" role.
Parameters
user: The user to check
Examples
iex> user_has_role_owner?(user)
true
Gets all users who have a specific role.
Parameters
role_name: The name of the role to search for
Examples
iex> users_with_role("Admin")
[%User{}, %User{}]
iex> users_with_role("NonexistentRole")
[]