Skip to main content

Overview

Rest Generic Class provides two traits for permission management that integrate with spatie/laravel-permission:
  1. HasPermissionsController - HTTP endpoints for permission operations
  2. HasPermissionsService - Business logic for permission assignment and retrieval
These traits provide:
  • Assign permissions to roles or users (ADD/SYNC/REVOKE modes)
  • Retrieve permissions by role or user
  • Auto-generate permissions from routes
  • Filter permissions by module, entity, or prefix
  • Aggregate permissions across roles/users
  • Support for pivot attributes on user permissions
Namespace: Ronu\RestGenericClass\Core\Traits Location:
  • /src/Core/Traits/HasPermissionsController.php:11
  • /src/Core/Traits/HasPermissionsService.php:21

HasPermissionsController

Provides HTTP endpoints for permission management.

Usage

use Ronu\RestGenericClass\Core\Controllers\RestController;
use Ronu\RestGenericClass\Core\Traits\HasPermissionsController;

class PermissionController extends RestController
{
    use HasPermissionsController;
}

Methods

modules

Retrieve list of application modules.
public function modules(Request $request): array
Query Parameters:
  • enabled (bool|null) - Filter by enabled status (true/false/null for all)
Example:
GET /api/permissions/modules?enabled=true
Response:
[
  "Users",
  "Products",
  "Orders",
  "--site--"
]
--site-- is a special module representing routes without a specific module.

assign_roles

Assign permissions to roles.
public function assign_roles(BaseFormRequest $request): \Illuminate\Http\JsonResponse
Request Body:
{
  "roles": ["admin", "editor"],
  "guard": "api",
  "mode": "ADD",
  "dry_run": false,
  "no_create": false,
  "perms": ["users.read", "users.create"],
  "prefix": "users.",
  "from": "permissions.json",
  "modules": ["Users"],
  "entities": ["users", "mod_sales.orders"],
  "by": "name"
}
Parameters:
  • roles (array|string) - Role names or IDs (comma-separated or array)
  • guard (string) - Guard name (default: 'api')
  • mode (string) - Operation mode: 'ADD', 'SYNC', or 'REVOKE'
  • dry_run (bool) - Preview changes without persisting (default: false)
  • no_create (bool) - Don’t create missing permissions (default: false)
  • perms (array) - Explicit permission names
  • prefix (string) - Filter permissions by prefix (e.g., 'users.')
  • from (string) - Load permissions from JSON/YAML file
  • modules (array) - Filter by module names
  • entities (array) - Filter by entity names (format: 'entity' or 'module.entity')
  • by (string) - Identify roles by 'name' or 'id' (default: 'name')
Response:
{
  "ok": true,
  "summary": {
    "guard": "api",
    "mode": "ADD",
    "perms_count": 5,
    "created_count": 0,
    "used_default_all": false
  },
  "per_role": [
    {
      "role": "admin",
      "guard": "api",
      "mode": "ADD",
      "rows": [
        {
          "permission": "users.read",
          "module": "Users",
          "guard": "api",
          "action": "ADD"
        }
      ]
    }
  ]
}
Example:
POST /api/permissions/assign_roles
Content-Type: application/json

{
  "roles": ["editor"],
  "guard": "api",
  "mode": "SYNC",
  "modules": ["Products"]
}

assign_users

Assign permissions to users.
public function assign_users(BaseFormRequest $request): \Illuminate\Http\JsonResponse
Request Body:
{
  "users": [10, 12, 15],
  "by": "id",
  "guard": "api",
  "mode": "ADD",
  "dry_run": false,
  "no_create": false,
  "perms": ["users.read", "users.create"],
  "prefix": "users.",
  "from": "permissions.json",
  "modules": ["Users"],
  "entities": ["users"],
  "pivot": {"range": "global", "team_id": 42}
}
Parameters: Same as assign_roles, plus:
  • users (array|string) - User identifiers (IDs, emails, or names)
  • by (string) - Identify users by 'id', 'email', or 'name' (default: 'id')
  • pivot (object) - Additional pivot attributes for model_has_permissions table
Response:
{
  "ok": true,
  "summary": {
    "guard": "api",
    "mode": "ADD",
    "perms_count": 3,
    "created_count": 0,
    "used_default_all": false
  },
  "per_user": [
    {
      "user_label": "10 ([email protected])",
      "guard": "api",
      "mode": "ADD",
      "rows": [
        {
          "permission": "users.read",
          "module": "Users",
          "guard": "api",
          "action": "ADD"
        }
      ]
    }
  ]
}
Example with Pivot:
POST /api/permissions/assign_users
Content-Type: application/json

{
  "users": ["[email protected]"],
  "by": "email",
  "mode": "ADD",
  "perms": ["projects.view"],
  "pivot": {"project_id": 5, "access_level": "read"}
}

HasPermissionsService

Provides business logic for permission operations.

Usage

use Ronu\RestGenericClass\Core\Traits\HasPermissionsService;

class PermissionService
{
    use HasPermissionsService;
}

Methods

assignPermissionToRoles

Assign permissions to roles with ADD/SYNC/REVOKE modes.
public function assignPermissionToRoles(array $roleInputs, array $options): array
Parameters:
  • array $roleInputs - Role names or IDs
  • array $options - Configuration array:
    • guard (string) - Guard name
    • mode (string) - 'ADD', 'SYNC', or 'REVOKE'
    • dry_run (bool) - Preview only
    • perms (array) - Permission names
    • prefix (string) - Permission prefix filter
    • from (string) - JSON/YAML file path
    • modules (array) - Module filter
    • entities (array) - Entity filter
    • by (string) - Identify roles by 'name' or 'id'
Returns:
[
    'summary' => [
        'guard' => 'api',
        'mode' => 'ADD',
        'perms_count' => 10,
        'created_count' => 2,
        'used_default_all' => false
    ],
    'per_role' => [
        [
            'role' => 'admin',
            'guard' => 'api',
            'mode' => 'ADD',
            'rows' => [
                [
                    'permission' => 'users.read',
                    'module' => 'Users',
                    'guard' => 'api',
                    'action' => 'ADD'
                ]
            ]
        ]
    ]
]
Example:
$result = $service->assignPermissionToRoles(
    ['admin', 'editor'],
    [
        'guard' => 'api',
        'mode' => 'ADD',
        'modules' => ['Users', 'Products']
    ]
);

assignPermissionToUsers

Assign permissions to users.
public function assignPermissionToUsers(array $userInputs, array $options): array
Parameters: Same as assignPermissionToRoles, plus:
  • pivot (array) - Pivot attributes for model_has_permissions
Example:
$result = $service->assignPermissionToUsers(
    [[email protected]', '[email protected]'],
    [
        'guard' => 'api',
        'mode' => 'ADD',
        'perms' => ['users.read'],
        'by' => 'email',
        'pivot' => ['team_id' => 5]
    ]
);

getPermissionsByRoles

Retrieve permissions for given roles.
public function getPermissionsByRoles(
    array $roleIdsOrNames, 
    string $by = 'id', 
    ?string $guard = null, 
    ?array $modules = null, 
    ?array $entities = null
): array
Example:
$permissions = $service->getPermissionsByRoles(
    ['admin', 'editor'],
    'name',
    'api',
    ['Users'],
    null
);
Response:
[
    [
        'role' => 'admin',
        'guard' => 'api',
        'count' => 15,
        'permissions' => [
            ['id' => 1, 'name' => 'users.read', 'module' => 'Users', 'guard' => 'api'],
            ['id' => 2, 'name' => 'users.create', 'module' => 'Users', 'guard' => 'api'],
        ]
    ]
]

getPermissionsByUsers

Retrieve permissions for given users.
public function getPermissionsByUsers(
    array $userSearchValues, 
    $userModelClass, 
    string $by = 'id', 
    ?string $guard = null, 
    ?array $modules = null, 
    ?array $entities = null
): array
Example:
$permissions = $service->getPermissionsByUsers(
    [10, 12],
    User::class,
    'id',
    'api',
    null,
    null
);
Response:
[
    [
        'user' => ['id' => 10, 'email' => '[email protected]', 'name' => 'John Doe'],
        'guard' => 'api',
        'count' => 8,
        'permissions' => [
            ['id' => 1, 'name' => 'users.read', 'module' => 'Users', 'guard' => 'api']
        ]
    ]
]

aggregate

Aggregate permissions across roles/users.
public function aggregate(array $lists, string $mode = 'union'): Collection
Parameters:
  • array $lists - Array of permission lists from getPermissionsByRoles or getPermissionsByUsers
  • string $mode - 'union' (all unique permissions) or 'intersection' (common permissions)
Example:
$role1Perms = $service->getPermissionsByRoles(['admin'], 'name');
$role2Perms = $service->getPermissionsByRoles(['editor'], 'name');

// Get all unique permissions
$allPerms = $service->aggregate([$role1Perms[0], $role2Perms[0]], 'union');

// Get common permissions
$commonPerms = $service->aggregate([$role1Perms[0], $role2Perms[0]], 'intersection');

refreshPermissions

Auto-generate permissions from application routes.
public function refreshPermissions($guard, $dry): array
Parameters:
  • string $guard - Guard name
  • bool $dry - Dry run (don’t persist changes)
Returns: Array of detected permissions:
[
    [
        'permission' => 'users.read',
        'model' => 'users',
        'type' => 'read',
        'route' => 'api/users',
        'methods' => 'GET',
        'controller' => 'UserController@index'
    ]
]
Example:
$permissions = $service->refreshPermissions('api', false);

Operation Modes

ADD Mode

Adds permissions without removing existing ones.
{"mode": "ADD", "perms": ["users.read"]}
Behavior:
  • Adds specified permissions
  • Keeps existing permissions intact
  • Equivalent to givePermissionTo()

SYNC Mode

Replaces all permissions with specified set.
{"mode": "SYNC", "perms": ["users.read", "users.update"]}
Behavior:
  • Removes all existing permissions
  • Adds specified permissions
  • Equivalent to syncPermissions()

REVOKE Mode

Removes specified permissions.
{"mode": "REVOKE", "perms": ["users.delete"]}
Behavior:
  • Removes specified permissions
  • Keeps other permissions intact
  • Equivalent to revokePermissionTo()

Permission Filtering

By Module

{
  "modules": ["Users", "Products"]
}
Loads all permissions where module column matches.

By Entity

{
  "entities": ["users", "products"]
}
Loads permissions where model column matches (case-insensitive). With module prefix:
{
  "entities": ["mod_sales.orders"]
}
Filters by both module='mod_sales' AND model='orders'.

By Prefix

{
  "prefix": "users."
}
Loads permissions where name starts with users. (e.g., users.read, users.create).

From File

{
  "from": "permissions.json"
}
Loads permission names from JSON/YAML file:
[
  "users.read",
  "users.create",
  "products.read"
]

Pivot Attributes (User Permissions)

Add custom pivot columns to model_has_permissions:
// Migration
Schema::table('model_has_permissions', function (Blueprint $table) {
    $table->unsignedBigInteger('team_id')->nullable();
    $table->string('access_level')->default('read');
    $table->timestamp('expires_at')->nullable();
});
Assign with pivot data:
POST /api/permissions/assign_users
{
  "users": [10],
  "perms": ["projects.view"],
  "pivot": {
    "team_id": 5,
    "access_level": "admin",
    "expires_at": "2025-12-31 23:59:59"
  }
}

Error Handling

Roles Not Found

// Throws NotFoundResourceException
"No roles found for the given identifiers and guard."

Users Not Found

// Throws RuntimeException
"No users found for the given identifiers."

Invalid Mode

// Throws InvalidArgumentException
"Cannot use both sync and revoke simultaneously."

Invalid Column

// Throws RuntimeException
"Error querying roles by 'invalid_column' (column 'invalid_column' may not exist)."

Configuration

Configure Spatie permission package in config/permission.php:
'models' => [
    'permission' => Spatie\Permission\Models\Permission::class,
    'role' => Spatie\Permission\Models\Role::class,
],

'table_names' => [
    'roles' => 'roles',
    'permissions' => 'permissions',
    'model_has_permissions' => 'model_has_permissions',
    'model_has_roles' => 'model_has_roles',
    'role_has_permissions' => 'role_has_permissions',
],

Build docs developers (and LLMs) love