Core Concepts
Controller (Class) Access
On this page
Controller access lets an administrator allow or deny a role on a whole controller, without code changes. Manage it at Admin → Classes (/systemroles/admin/roles/classes/index).
How controllers get listed#
SystemRoles scans the folder set in controller_directory (default app/Http/Controllers, including sub-folders). For each PHP file it reads the namespace and the first class name and stores them in system_classes.
- A controller is identified by namespace + class name, so
App\Http\Controllers\UsersControllerandApp\Http\Controllers\Admin\UsersControllerare two separate entries. - The scan runs when the Classes screen opens (if
scan_on_requestistrue), when you runphp artisan systemroles:sync --classes, and when you click Add Class Access. - Scanning only adds and updates. Controllers you delete from the code stay in the table until you remove them.
The Classes screen#
| Column | Meaning |
|---|---|
| Name | Class name |
| Filename | File name |
| Namespace | Full namespace |
| Description | Generated description |
| # of Class Access | How many roles have an access row for it |
| Action | Manage Class Access |
Add Class Access#
The Add Class Access button (in a confirmation dialog) rescans the controllers and creates a row in system_classes_in for every role on every controller, set to "revoke" (0). Existing rows are kept. Use it once after installing, so every controller appears with a complete set of roles.
Manage Class Access#
For one controller, the screen lists every role with two choices:
- Grant Access (
in_role = 1) - Revoke Access (
in_role = 0)
Save to store the choices in system_classes_in.
Checking controller access in code#
The check lives on SystemClassesController:
use BabeRuka\SystemRoles\Http\Controllers\SystemRoles\SystemClassesController;
use BabeRuka\SystemRoles\Services\SystemRolesService;
$roleId = SystemRolesService::roleIdForUser(auth()->id());
$classes = new SystemClassesController();
// Returns 1 (allowed) or 0 (denied). Super admin always gets 1.
$classes->checkSystemClassesInit($roleId, \App\Http\Controllers\InvoiceController::class);
// Same check, but aborts with 403 when denied.
$classes->checkAccess($roleId, \App\Http\Controllers\InvoiceController::class);The class name can be:
- fully qualified (
App\Http\Controllers\Admin\UsersController): matched on namespace and name. Recommended. - short (
UsersController): matched on name only. If two controllers share the name, the first match is used, so prefer the full name.
A controller that is not in system_classes, or has no row for the role, is denied.
chechAccess()(misspelt) still works as an alias ofcheckAccess()for older code. UsecheckAccess()in new code.
Enforcing controller access on every request#
A middleware can check the controller behind the current route:
namespace App\Http\Middleware;
use BabeRuka\SystemRoles\Http\Controllers\SystemRoles\SystemClassesController;
use BabeRuka\SystemRoles\Services\SystemRolesService;
use Closure;
use Illuminate\Http\Request;
class ControllerAccess
{
public function handle(Request $request, Closure $next)
{
$controller = $request->route()?->getControllerClass();
// Closures and package routes are not checked here.
if (! $controller || str_starts_with($controller, 'BabeRuka\\SystemRoles\\')) {
return $next($request);
}
$roleId = SystemRolesService::roleIdForUser(optional($request->user())->getKey());
if ((new SystemClassesController())->checkSystemClassesInit($roleId, $controller) !== 1) {
abort(403, 'You do not have access to this area.');
}
return $next($request);
}
}Apply it to a route group, not globally, so public pages such as login keep working:
Route::middleware(['auth', 'controller.access'])->group(function () {
Route::resource('invoices', InvoiceController::class);
});When to use controller access#
Good for:
- locking whole areas (Reports, Billing, Settings) per role;
- letting an administrator open or close an area quickly.
Less suited for:
- different rights inside one controller (view vs delete). Use permissions for that.
You can combine both: controller access as a coarse gate, permissions for actions inside.