Rephi.Authorization (Rephi v0.1.0)
View SourceThe Authorization context manages roles, permissions, and user authorization.
This module implements a complete Role-Based Access Control (RBAC) system with hierarchical roles and permissions. It provides functions for:
- Role management (CRUD operations)
- Permission management (CRUD operations)
- User-role assignments
- User-permission assignments (direct)
- Role-permission assignments
- Role hierarchy management
- Authorization checks
Examples
# Check if user has permission
iex> Authorization.can?(user, "users:edit")
true
# Check if user has role
iex> Authorization.has_role?(user, "admin")
false
# Get all user permissions (direct + inherited via roles)
iex> Authorization.get_user_permissions(user)
[%Permission{slug: "users:view"}, %Permission{slug: "users:create"}]
Role Hierarchy
Roles can inherit permissions from parent roles. For example:
admin
role inherits frommanager
rolemanager
role inherits fromuser
role- Users with
admin
role automatically have allmanager
anduser
permissions
Permission Categories
Permissions are organized by domain using colon notation:
users:*
- User management permissionsroles:*
- Role management permissionspermissions:*
- Permission management permissionssystem:*
- System administration permissions
Summary
Functions
Assigns a parent role to a child role.
Assigns a permission to a role.
Assigns a permission directly to a user.
Assigns a role to a user.
Checks if a user has a specific permission.
Flexible authorization check with keyword options.
Creates a new permission.
Creates a new role.
Deletes a permission from the system.
Deletes a role from the system.
Gets a single permission by ID, returning nil if not found.
Gets a single permission by ID, raising an exception if not found.
Gets a permission by its unique slug identifier.
Gets a single role by ID, returning nil if not found.
Gets a single role by ID, raising an exception if not found.
Gets a role by its unique slug identifier.
Gets all permissions for a role (including inherited permissions).
Gets all effective permissions for a user.
Gets all roles directly assigned to a user.
Checks if a user has a specific role assigned.
Returns the list of all permissions in the system.
Returns the list of all roles in the system.
Removes a parent role from a child role.
Removes a permission from a role.
Removes a permission from a user.
Removes a role assignment from a user.
Checks if a role has a specific permission.
Updates an existing permission.
Updates an existing role.
Functions
Assigns a parent role to a child role.
Assigns a permission to a role.
Assigns a permission directly to a user.
Assigns a role to a user.
Creates a relationship between a user and a role, optionally with metadata about who assigned it and why.
Parameters
user
- The user structrole
- The role struct to assignopts
- Optional metadata (assigned_by, notes)
Examples
iex> Authorization.assign_role_to_user(user, admin_role)
{:ok, %UserRole{}}
iex> Authorization.assign_role_to_user(user, role, %{
...> assigned_by: current_user.id,
...> notes: "Promoted to admin"
...> })
{:ok, %UserRole{notes: "Promoted to admin"}}
iex> Authorization.assign_role_to_user(user, role) # Already assigned
{:error, %Ecto.Changeset{}}
Checks if a user has a specific permission.
This function checks both direct permissions assigned to the user and permissions inherited through roles. It supports hierarchical role inheritance.
Parameters
user
- The user struct to check permissions forpermission
- Either a permission slug (string) or Permission struct
Examples
iex> Authorization.can?(user, "users:edit")
true
iex> Authorization.can?(user, permission_struct)
false
iex> Authorization.can?(nil, "users:edit")
false
iex> Authorization.can?(user, nil)
false
Permission Resolution Order
- Check direct user permissions
- Check permissions through assigned roles
- Check permissions through role hierarchy (parent roles)
Flexible authorization check with keyword options.
This function provides a flexible interface for authorization checks using keyword arguments instead of positional parameters.
Parameters
opts
- Keyword list with authorization options
Supported Options
user: user, permission: "permission:slug"
- Check user permissionuser: user, role: "role_slug"
- Check user role
Examples
iex> Authorization.can_by?(user: user, permission: "users:edit")
true
iex> Authorization.can_by?(user: user, role: "admin")
false
iex> Authorization.can_by?(invalid: "option")
false
Creates a new permission.
Parameters
attrs
- A map of permission attributes
Examples
iex> Authorization.create_permission(%{
...> name: "Export Users",
...> slug: "users:export",
...> description: "Export user data"
...> })
{:ok, %Permission{name: "Export Users", slug: "users:export"}}
iex> Authorization.create_permission(%{name: "", slug: ""})
{:error, %Ecto.Changeset{}}
Creates a new role.
Parameters
attrs
- A map of role attributes
Examples
iex> Authorization.create_role(%{name: "Manager", slug: "manager"})
{:ok, %Role{name: "Manager", slug: "manager"}}
iex> Authorization.create_role(%{name: "", slug: ""})
{:error, %Ecto.Changeset{}}
Deletes a permission from the system.
Also removes all associated role-permission and user-permission assignments.
Parameters
permission
- The permission struct to delete
Examples
iex> Authorization.delete_permission(permission)
{:ok, %Permission{}}
iex> Authorization.delete_permission(invalid_permission)
{:error, %Ecto.Changeset{}}
Deletes a role from the system.
Also removes all associated user-role and role-permission assignments.
Parameters
role
- The role struct to delete
Examples
iex> Authorization.delete_role(role)
{:ok, %Role{}}
iex> Authorization.delete_role(invalid_role)
{:error, %Ecto.Changeset{}}
Gets a single permission by ID, returning nil if not found.
Parameters
id
- The permission ID
Examples
iex> Authorization.get_permission(1)
%Permission{id: 1, name: "View Users"}
iex> Authorization.get_permission(999)
nil
Gets a single permission by ID, raising an exception if not found.
Parameters
id
- The permission ID
Examples
iex> Authorization.get_permission!(1)
%Permission{id: 1, name: "View Users", slug: "users:view"}
iex> Authorization.get_permission!(999)
** (Ecto.NoResultsError)
Gets a permission by its unique slug identifier.
Parameters
slug
- The permission slug (e.g., "users:view", "roles:create")
Examples
iex> Authorization.get_permission_by_slug("users:view")
%Permission{slug: "users:view", name: "View Users"}
iex> Authorization.get_permission_by_slug("nonexistent")
nil
Gets a single role by ID, returning nil if not found.
Parameters
id
- The role ID
Examples
iex> Authorization.get_role(1)
%Role{id: 1, name: "Admin"}
iex> Authorization.get_role(999)
nil
Gets a single role by ID, raising an exception if not found.
Parameters
id
- The role ID
Examples
iex> Authorization.get_role!(1)
%Role{id: 1, name: "Admin"}
iex> Authorization.get_role!(999)
** (Ecto.NoResultsError)
Gets a role by its unique slug identifier.
Parameters
slug
- The role slug (e.g., "admin", "user")
Examples
iex> Authorization.get_role_by_slug("admin")
%Role{slug: "admin", name: "Administrator"}
iex> Authorization.get_role_by_slug("nonexistent")
nil
Gets all permissions for a role (including inherited permissions).
Gets all effective permissions for a user.
Returns a deduplicated list of all permissions the user has access to, including both direct permissions and permissions inherited through roles and role hierarchy.
Parameters
user
- The user struct
Examples
iex> Authorization.get_user_permissions(user)
[
%Permission{slug: "users:view", name: "View Users"},
%Permission{slug: "users:create", name: "Create Users"},
%Permission{slug: "roles:view", name: "View Roles"}
]
Permission Sources
- Direct permissions: Permissions assigned directly to the user
- Role permissions: Permissions assigned to user's roles
- Inherited permissions: Permissions from parent roles in hierarchy
Gets all roles directly assigned to a user.
This does not include roles inherited through hierarchy.
Parameters
user
- The user struct
Examples
iex> Authorization.get_user_roles(user)
[%Role{name: "Manager", slug: "manager"}]
Checks if a user has a specific role assigned.
This function only checks for direct role assignments, not role inheritance.
Parameters
user
- The user struct to checkrole
- Either a role slug (string) or Role struct
Examples
iex> Authorization.has_role?(user, "admin")
true
iex> Authorization.has_role?(user, admin_role)
false
iex> Authorization.has_role?(nil, "admin")
false
iex> Authorization.has_role?(user, nil)
false
Returns the list of all permissions in the system.
Examples
iex> Authorization.list_permissions()
[
%Permission{name: "View Users", slug: "users:view"},
%Permission{name: "Create Users", slug: "users:create"}
]
Returns the list of all roles in the system.
Examples
iex> Authorization.list_roles()
[%Role{name: "Admin", slug: "admin"}, %Role{name: "User", slug: "user"}]
Removes a parent role from a child role.
Removes a permission from a role.
Removes a permission from a user.
Removes a role assignment from a user.
Parameters
user
- The user structrole
- The role struct to remove
Examples
iex> Authorization.remove_role_from_user(user, admin_role)
{:ok, %UserRole{}}
iex> Authorization.remove_role_from_user(user, unassigned_role)
{:error, :not_found}
Checks if a role has a specific permission.
This function checks both direct permissions assigned to the role and permissions inherited through role hierarchy.
Parameters
role
- The role struct to checkpermission
- Either a permission slug (string) or Permission struct
Examples
iex> Authorization.role_has_permission?(admin_role, "users:delete")
true
iex> Authorization.role_has_permission?(user_role, delete_permission)
false
iex> Authorization.role_has_permission?(role, "nonexistent:permission")
false
Permission Resolution
- Check permissions directly assigned to the role
- Check permissions inherited from parent roles (recursive)
Updates an existing permission.
Parameters
permission
- The permission struct to updateattrs
- A map of attributes to update
Examples
iex> Authorization.update_permission(permission, %{
...> description: "Updated description"
...> })
{:ok, %Permission{description: "Updated description"}}
iex> Authorization.update_permission(permission, %{slug: ""})
{:error, %Ecto.Changeset{}}
Updates an existing role.
Parameters
role
- The role struct to updateattrs
- A map of attributes to update
Examples
iex> Authorization.update_role(role, %{name: "Senior Manager"})
{:ok, %Role{name: "Senior Manager"}}
iex> Authorization.update_role(role, %{slug: ""})
{:error, %Ecto.Changeset{}}