Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Authorization: roles, policies and limitations

The Exponential permission system for developers used to voters, gates, policies, Django permissions or CanCan abilities - roles made of policies, module functions and limitations, assignments to users and groups…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/web-framework-developers/authorization-roles-and-policies.md

On this page

Authorization: roles, policies and limitations

This page is for developers who write voters, gates, policy classes or permission decorators. Exponential's permissions are data, managed by administrators in Users and roles: a role is a set of policies; a policy grants one function of one module (content/read, expdemo/manage), optionally restricted by limitations (only this class, this section, this subtree, this language, this siteaccess); a role is assigned to users or groups, optionally limited to a subtree or section. Your code declares the functions and checks them; administrators decide who gets them (Policies, roles and limitations).

Contents

  1. The model
  2. Declaring permissions for your module
  3. What the kernel checks for you
  4. Checking in PHP
  5. Checking in templates
  6. Compared with other frameworks
  7. Rules

The model

TermClassExample
RoleeZRoleEditor
PolicyeZPolicycontent/edit
LimitationeZPolicyLimitation, eZPolicyLimitationValueClass: Article, Section: Standard
Assignmentrole to user or group, optionally limitedEditor for the group Editors, limited to the subtree "News"

The guide for administrators: Roles, policies and unactivated users.

Declaring permissions for your module

// extension/expdemo/modules/expdemo/module.php
$ViewList['manage'] = array( 'script' => 'manage.php', 'functions' => array( 'manage' ) );

// a limitation whose values are the sections, as kernel/content/module.php defines $SectionID
$SectionLimitation = array( 'name' => 'Section', 'values' => array(), 'class' => 'eZSection',
                            'function' => 'fetchList', 'parameter' => array( false ) );

$FunctionList = array();
$FunctionList['read'] = array();
$FunctionList['manage'] = array( 'Section' => $SectionLimitation );

$FunctionList names the functions and the limitations each accepts; administrators then see expdemo/read and expdemo/manage in the policy editor (Policy functions and limitations, module.php reference).

What the kernel checks for you

  • A view's 'functions' => array( 'manage' ) is checked before the view runs: without the function the user gets "access denied", an anonymous user the login page.
  • That check does not evaluate limitations for your own data; it only knows the user has the function, possibly limited.
  • Content fetches (subTreeByNodeID(), fetch( 'content', ... )) return only what the user may read, applying every content limitation.

Checking in PHP

$user = eZUser::currentUser();
$access = $user->hasAccessTo( 'expdemo', 'manage' );
switch ( $access['accessWord'] )
{
    case 'yes':     // unlimited
        break;
    case 'limited': // $access['policies'] holds the limitations, for example allowed section ids
        break;
    default:        // 'no'
        return $Params['Module']->handleError( eZError::KERNEL_ACCESS_DENIED, 'kernel' );
}

if ( !$node->canRead() ) { /* deny */ }
if ( !$object->canEdit() ) { /* deny */ }

For content, ask the object or node: they apply class, section, owner, subtree, state and language limitations. For your own tables, apply the limitations from $access['policies'] in your query, and check ownership yourself (Access control in code).

Checking in templates

{if fetch( 'user', 'has_access_to', hash( 'module', 'expdemo', 'function', 'manage' ) )}
  <a href={'expdemo/manage'|ezurl}>{'Manage'|i18n( 'extension/expdemo' )}</a>
{/if}

Hiding a link is convenience, not security: the view must check again (Role and policy template operators).

Compared with other frameworks

FrameworkConceptExponential
SymfonyisGranted(), voters, #[IsGranted]hasAccessTo(), canRead(), the view's functions
Laravelgates, policy classes, can middlewarefunctions in $FunctionList, checks in the view
Djangomodel permissions, @permission_required, object permission packagesfunctions and limitations; object checks built in for content
RailsCanCanCan abilities, Pundit policiesroles as data, edited in the administration
Springmethod security, ACLspolicies with limitations; content ACL-like checks built in

The biggest difference: rules live in the database and are changed by administrators, not in code. Your code names the functions and asks the questions.

Rules

  • Access is decided by policies, never by checking a user or group id in code or templates.
  • One function per kind of action (read, create, manage), not per screen.
  • Never grant a new function to Anonymous by default; document what to grant.
  • Apply the same checks to a list as to one item: filter the query, do not hide rows in the template.
  • Background work runs as the user who queued it, or as a dedicated integration user with a role made for it.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x