Class Useraccount

Description

Methods to access properties of the account of the logged in user

This deals mainly with retrieving information about the user that is currently logged in. There is one exception: a user that is NOT logged in can still have a $USER object, but there are no privileges in that case. The special user_id in that case is 0.

The constructor reads the important data from the database. This includes things like the full name of the user and the email address. This information is stored in the object and can be used, e.g. $USER->email. This information is basically copied from the table 'users'.

Furthermore, any properties for this user are retrieved from the table 'users_properties'. All properties are stored in an array. These can be used directly via $USER->properties['foobar'].

Access Control

Finally we deal with access control. This has become quite complex but still managable (I hope). There are six tables dealing with acl's:

  • acls: site-wide permissions for jobs, intranet, modules and nodes
  • acls_areas: permissions for intranet, modules and nodes at the area level
  • acls_nodes: permissions for modules and nodes a the node level
  • acls_modules: permissions for modules at the site level
  • acls_modules_areas: permissions for modules at the area level
  • acls_modules_nodes: permissions for modules at the node level
The user has at least one associated ACL: the acl_id field in the user record. Additional ACLs are associated with the user via group memberships. All ACLs are integer bitmasks where a '1' grants a permission for something and a '0' denies permission.

All bits '0' is a special case: this is the default (nothing allowed) and hence does not have to be stored: the mere non-existence of permissions implies no permissions.

All bits '1' is also a special case, dubbed 'ROLE_GURU'. If an ACL has this value, it means that all current (and future) permissions are granted. A user with ROLE_GURU can do anything.

Of the six tables, only the first one (acls) is read immediately in the constructor. The others are read on demand. This is done by initially setting the corresponding cache variable to NULL. If the table has been read, the variable will always be of type 'array', even though that array may be empty (indicating no permissions).

The permissions from the ACLs are combined between the user's acl and the optional group-acls. Only the combination of user and group permissions is cached in order to save space. This is done by OR'ing the permission bits. Note that the condition all bits '0' is not stored, also to save space.

There are some functions to test for individual permissions:

  • has_site_permissions()
  • has_area_permissions()
  • has_node_parmissions()
  • has_job_permissions()
  • has_intranet_permissions()
  • has_module_site_permissions()
  • has_module_area_permissions()
  • has_module_node_parmissions()
Example: in order to determine wheter a user has access to the intranet in area #2, the following could be used:

    $area_id = 2; if ($USER->has_intranet_permissions(ACL_ROLE_INTRANET_ACCESS,$area_id)) {     .... }

The effect of this call is as follows. First the routine checks the (already cached) intranet-permissions at the site level. If access is granted at the site level, there is no need to look any further because obviously this user has access to this intranet (private area) and all other current and future intranets. If not, the routine looks at intranet permissions at the area level. The first time this will trigger reading and caching the table for area-level permissions. In this case (intranet-access), the area-level permissions provide the definitive go/nogo for this user (there is no point in having intranet-access-permissions at the node level).

Note that the 'lower' ACL is only checked if the 'higher' does not provide answers. This saves unnecessary trips to the database.

Note that this works much the same for the other has_xxx_permissions(): first the site-level is tried, then the area-level and finally the node-level (when applicable).

ACLs for modules

Access to the CMS itself is fairly fine-grained. The permissions are stored in the fields 'permissions_nodes' in the tables 'acls' (site-level), acls_areas (area-level) and acls_nodes (node-level). These permissions basically deal with the page manager (the piece de resistance of the whole system).

However, there are modules that can be linked to nodes, e.g. a chat or a forum or an agenda which also require autorised users and permissions. These permissions are stored in three tables: acls_modules (site-level). acls_modules_areas (area-level) and acls_modules_nodes (node-level). This works pretty much the same as the permissions for the CMS itself, be it that there is an extra parameter, namely the module_id.

Once again, the permissions are only read when necessary. I.e., if the site-level already grants a permission, the area and node level are not read from the database. This saves time and space.

Roles and permissions

Permissions are indivial flags that allow or disallow a certain feature, e.g. 'adding a page to a section'. In order to keep these permissions manageable groups of permissions are combined yielding a limited number of 'roles'. A 'role' is a combination of 1 or more permission bits. Assigning permissions (in the user account manager) is done by assigning these 'roles' to a user, either sitewide, areawide or per node. These roles are dubbed sitemaster, areamaster, sectionmaster, pagemaster and contentmaster. The 'higher' roles incoporate the 'lower' roles: permissions of a sectionmaster include those of a pagemaster and a contentmaster.

Located in /program/lib/useraccount.class.php (line 251)


	
			
Variable Summary
 array $acls
 null|array $acls_areas
 null|array $acls_modules
 null|array $acls_modules_areas
 null|array $acls_modules_nodes
 null|array $acls_nodes
 int $acl_id
 string $editor
 string $email
 string $full_name
 string $language_key
 string $path
 array $properties
 string $username
 int $user_id
Method Summary
 void Useraccount ([int $user_id = 0])
 array fetch_acls_from_table (string $table, string $where)
 bool has_area_permissions (int $mask, int $area_id, [string $field = 'permissions_nodes'])
 bool has_intranet_permissions (int $mask, int $area_id)
 bool has_job_permissions (int $mask)
 bool has_node_permissions (int $mask, int $area_id, int $node_id, [string $field = 'permissions_nodes'])
 bool has_site_permissions (int $mask, [string $field = 'permissions_nodes'])
 bool is_admin ()
 bool is_admin_pagemanager (int $area_id)
 string where_acl_id ([string $field = 'acl_id'])
Variables
array $acls = array('permissions_jobs' => ACL_ROLE_NONE,
'permissions_intranet' => ACL_ROLE_NONE,
'permissions_modules' => ACL_ROLE_NONE,
'permissions_nodes' => ACL_ROLE_NONE)
(line 277)
  • var: $acls contains the highest-level (site level) permissions, cached from table acls
null|array $acls_areas = NULL (line 283)
  • var: $acls_areas holds area-level permissions, cached from acls_areas
null|array $acls_modules = NULL (line 289)
  • var: $acls_modules holds site-level permissions for modules, cached from acls_modules
null|array $acls_modules_areas = NULL (line 292)
  • var: $acls_modules_areas holds area-level permissions for modules, cached from acls_modules_areas
null|array $acls_modules_nodes = NULL (line 295)
  • var: $acls_modules_nodes holds node-level permissions for modules, cached from acls_modules_nodes
null|array $acls_nodes = NULL (line 286)
  • var: $acls_nodes holds node-level permissions, cached from acls_nodes
int $acl_id (line 271)
  • var: $acl_id identifies the main acl for this user
array|null $area_permissions_from_nodes = NULL (line 310)
  • var: cache for admin permissions based on node permissions
string $editor (line 304)
  • var: $editor the preferred editor for this user (empty implies system default from $CFG->editor)
string $email (line 262)
  • var: $email
string $full_name (line 259)
  • var: $full_name
bool $high_visibility = FALSE (line 301)
  • var: $high_visibility
bool $is_logged_in = FALSE (line 307)
  • var: $is_logged_in TRUE if user is logged in, FALSE otherwise
string $language_key (line 265)
  • var: $language_key
string $path (line 268)
  • var: $path directory that holds the personal data files relative to "{$CFG->datadir}/users/"
array $properties = array() (line 298)
  • var: $properties
array $related_acls = array() (line 274)
  • var: $related_acls holds acl_id -> groupname/capacity pairs related to this user
string $username (line 256)
  • var: $username
int $user_id (line 253)
  • var: $user_id
Methods
Constructor Useraccount (line 318)

get pertinent user information in core

void Useraccount ([int $user_id = 0])
  • int $user_id: identifies data from which user to load, 0 means no user/a passerby
fetch_acls_from_table (line 567)

retrieve acl-data from table into a sparse array

  • return: zero or more elements with permissions
array fetch_acls_from_table (string $table, string $where)
  • string $table: name of the table which holds the acls
  • string $where: a ready-to-use whereclause that selects the relevant acls based on acl_id
has_area_permissions (line 407)

determine user's permissions for an area

this looks at the area-level permissions for manipulating nodes and areas. However, we first look at the site-level permissions. If those already satisfy the request, we return immediately. If not, the permissions are fetched from the table acls_areas of from the cached data. We only fetch the data if it is really necessary.

  • return: TRUE if at least one permission in $mask is granted, FALSE otherwise
bool has_area_permissions (int $mask, int $area_id, [string $field = 'permissions_nodes'])
  • int $mask: bitmap of OR'ed permissions to test for
  • int $area_id: which area to test
  • string $field: name of permissions to check (default 'permissions_nodes')
has_intranet_permissions (line 475)

determine user's permissions for an intranet area

this looks at the area-level permissions for intranet areas.

  • return: TRUE if at least one permission in $mask is granted, FALSE otherwise
bool has_intranet_permissions (int $mask, int $area_id)
  • int $mask: bitmap of OR'ed permissions to test for
  • int $area_id: which area to test
has_job_permissions (line 459)

determine user's permissions for a job

  • return: TRUE if at least one permission in $mask is granted, FALSE otherwise
bool has_job_permissions (int $mask)
  • int $mask: bitmap of OR'ed permissions to test for
has_node_permissions (line 435)

determine user's permissions for a node within an area

  • return: TRUE if at least one permission in $mask is granted, FALSE otherwise
bool has_node_permissions (int $mask, int $area_id, int $node_id, [string $field = 'permissions_nodes'])
  • int $mask: bitmap of OR'ed permissions to test for
  • int $area_id: which area to test
  • int $node_id: which node to test
  • string $field: name of permissions to check (default 'permissions_nodes')
has_site_permissions (line 382)

determine user's permissions for the site-level

this looks at the site-level permissions for manipulating nodes and areas etc. The permissions are cached from the table acls.

  • return: TRUE if at least one permission in $mask is granted, FALSE otherwise
bool has_site_permissions (int $mask, [string $field = 'permissions_nodes'])
  • int $mask: bitmap of OR'ed permissions to test for
  • string $field: name of permissions to check (default 'permissions_nodes')
is_admin (line 492)

determine whether the user has administrator privilege

If this user has access to the admin startcenter, she is considered an administrator. Further access depends on the other bits in the job permissions, but at least she is allowed to enter the system via admin.php.

  • return: TRUE if user is considered an admin, FALSE otherwise
bool is_admin ()
is_admin_pagemanager (line 516)

determine whether the user has administrator privilege for pagemanager

This routine determines whether a user has any privileges at all for the page manager. This is true in the following cases:

  • the user has sitewide permissions that belong to one of the roles contentmaster, pagemaster, sectionmaster or areamaster, OR
  • the user has areawide permissions for one of those roles, OR
  • the user has permissions for one of those roles in at least one node in the requested area.
The calculations in the third case are cached for all areas.

  • return: TRUE if user is considered a pagemanager admin, FALSE otherwise
bool is_admin_pagemanager (int $area_id)
  • int $area_id: the area to examine
where_acl_id (line 615)

a convenient routine to construct a selection of acls

this constructs a where clause of the form '(acl_id = 1) OR (acl_id = 2) OR (acl_id = 3)'

  • return: ready-to-use where-clause without the word 'where'
string where_acl_id ([string $field = 'acl_id'])
  • string $field: identifies the fieldname to check

Documentation generated on Wed, 11 May 2011 23:45:42 +0200 by phpDocumentor 1.4.0