CoolCMS API

PrivilegeCheckTrait

RBAC access control of the admin.

  • checkAdminAccess() is called in BasePresenter::startup() and guards the entry key :Admin (who may enter the admin at all).
  • loadUserPrivileges() is called right after checkAdminAccess() in startup(); it loads all privileges of the logged-in user into $userPrivileges with one database query per request, so components (e.g. DataGrid) can check them safely.
  • checkPrivilege() and checkCurrentPrivilege() are called explicitly in a presenter action for finer privileges (e.g. :Admin:Blog:Article:edit).
  • isAllowed() serves conditional display (grid actions etc.); it reads the loaded array only, with no database query.

Table of Contents

Constants

LOGIN_BACKLINK  : string = 'backlink'
Login page parameter with the key of the stored request to return to ({@see loginReturnArgs()}).

Properties

$privilegeManager  : PrivilegeManager
$userPrivileges  : array<int, string>

Methods

isAllowed()  : bool
Returns whether the logged-in user has the given privilege.
checkAdminAccess()  : void
Entry gate to the admin: a guest is sent to login; a logged-in user without `:Admin` is sent to login with an error.
checkCurrentPrivilege()  : void
Builds the key from the current request (`:Admin:<Module>:<Presenter>:<action>`) and checks it. `getName()` already contains the `Admin:...` prefix, so only one leading colon is added.
checkPrivilege()  : void
Checks a specific privilege; throws 403 when denied.
loadUserPrivileges()  : void
Loads all privileges of the logged-in user with one database query. Call it right after `checkAdminAccess()` in `startup()` (the user is guaranteed to be logged in by then).
loginReturnArgs()  : array<string, string>
Remembers the request of a logged-out user so the login can return to it ({@see storeRequest()}, `backlink` of the login page, restored by `AuthStorageTrait::redirectAfterLoginAction()`).

Constants

Login page parameter with the key of the stored request to return to ({@see loginReturnArgs()}).

public string LOGIN_BACKLINK = 'backlink'

Properties

$userPrivileges

private array<int, string> $userPrivileges = []

privileges of the current user loaded in startup()

Methods

isAllowed()

Returns whether the logged-in user has the given privilege.

public isAllowed(string $key) : bool

Reads the array loaded in startup(), with no database query. Fail-closed: returns false when loadUserPrivileges() was not called or failed.

Public so templates can call it ($presenter->isAllowed(...)) for conditional display of actions outside DataGrid (e.g. static menu management links).

Parameters
$key : string
Return values
bool

checkAdminAccess()

Entry gate to the admin: a guest is sent to login; a logged-in user without `:Admin` is sent to login with an error.

protected checkAdminAccess() : void

checkCurrentPrivilege()

Builds the key from the current request (`:Admin:<Module>:<Presenter>:<action>`) and checks it. `getName()` already contains the `Admin:...` prefix, so only one leading colon is added.

protected checkCurrentPrivilege() : void

Use it where the key matches the action; use explicit checkPrivilege() where it differs (another presenter, add versus edit).

checkPrivilege()

Checks a specific privilege; throws 403 when denied.

protected checkPrivilege(string $key) : void

IMPORTANT: a hidden button is no protection. A hand-built ?...&do=<signal> URL runs the action, so every non-standard action and every mutating signal needs the gate as its first statement; otherwise anyone who types the URL can run it.

IMPORTANT: form actions need two gates, one in the signal and one in process*() (the submit), because a submit arrives as its own request. With only the signal gate the submit stays open. See the WorkList traits.

Parameters
$key : string

loadUserPrivileges()

Loads all privileges of the logged-in user with one database query. Call it right after `checkAdminAccess()` in `startup()` (the user is guaranteed to be logged in by then).

protected loadUserPrivileges() : void

loginReturnArgs()

Remembers the request of a logged-out user so the login can return to it ({@see storeRequest()}, `backlink` of the login page, restored by `AuthStorageTrait::redirectAfterLoginAction()`).

private loginReturnArgs() : array<string, string>

Without it a save sent after a logout in another tab (or after the idle timeout) ended on the login page with no explanation, the login led to the dashboard and the filled-in form was lost. A restored POST renders the form again with the submitted values, but Nette does not process it (Request::RESTORED, no blind replay): the admin checks the values and saves once more. An AJAX request is not stored (naja would replay it as a page). The user id stored with the request is the previous identity, so a different account logging in is not sent there.

Return values
array<string, string>
On this page

Search results