Permissions Scripts: functions.inc.php: Difference between revisions

From XMBdocs
mNo edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
All permissions retrieval and password checking logic is located in this file.
All permissions retrieval and password checking logic is located in this portion of the [[Forum Permissions System]]


==Functions==
==Functions==
Line 76: Line 76:
X_PERMS_USERLIST will still indicate whether or not a user is in the userlist or modlist for a forum.  X_PERMS_VIEW, however, doesn't necessarily indicate whether a user has the View permission based on their rank because it could be a View permission based on the user list.  In anticipation of the need to know the exact permissions set, we will be adding the X_PERMS_RAWVIEW index for that purpose.
X_PERMS_USERLIST will still indicate whether or not a user is in the userlist or modlist for a forum.  X_PERMS_VIEW, however, doesn't necessarily indicate whether a user has the View permission based on their rank because it could be a View permission based on the user list.  In anticipation of the need to know the exact permissions set, we will be adding the X_PERMS_RAWVIEW index for that purpose.


Comprehensive examples of checkForumPermissions() usage are published in the [[Best Practices]] section.
Comprehensive examples of checkForumPermissions() usage are published in the [[Permissions: Best Practices|Best Practices]] section.


When custom code is needed to change the behavior of XMB, one can take advantage of these orderly bit fields without using checkForumPermissions().
When custom code is needed to change the behavior of XMB, one can take advantage of these orderly bit fields without using checkForumPermissions().

Latest revision as of 14:13, 20 April 2021

All permissions retrieval and password checking logic is located in this portion of the Forum Permissions System

Functions

function elevateUser()

This function is responsible for creating a single authentication point for XMB credentials. One of the most important tasks it carries out is to define user rank constants that are used throughout XMB.

    if ($xmbuser == '') {
        if (!defined('X_GUEST')) {
            define('X_MEMBER', false);
            define('X_GUEST', true);
        }
    }

    if (!defined('X_STAFF')) {
        define('X_SADMIN', $role['sadmin']);
        define('X_ADMIN', $role['admin']);
        define('X_SMOD', $role['smod']);
        define('X_MOD', $role['mod']);
        define('X_STAFF', $role['staff']);
    }

Because elevateUser() is guaranteed to be called by header.php and define these bool constants, it is convenient and sufficient to use them at any point in the code, for example: if (X_GUEST) { echo "Hello, you are not logged in."; } The one caveat is when editing code in header.php or the functions that are called before authenticating the user, it is likely these constants are not yet defined and will evaluate to an implicit string value that narrows to TRUE.

function modcheck()

This function takes as arguments $username (which is not necessarily $xmbuser if a guest logs in through post.php) and $mods, where $username is the raw database value (html encoded) for the current user and $mods is the raw database value of the forums.moderator column in the current forum.

This function returns 'Moderator' if the user has moderation permissions. In all other cases this function returns '' (empty string).

function modcheckPost()

This function extends function modcheck() with logic required to enforce the AllowRankEdit setting. It uses an extra argument called $origstatus, which is the status of the user who originally posted the item to be moderated. If the original poster is ranked higher than the moderator requesting permissions, then this function returns '' (empty string) even though the forum permissions may exist.

function checkForumPermissions()

The purpose of this function is to take a forum row as an argument and return an array of six bool values representing the effective set of permissions. These six values correspond to the six indexes enumerated in header.php (see above).

    $status = array(
        'Super Administrator' => 1,
        'Administrator'       => 2,
        'Super Moderator'     => 4,
        'Moderator'           => 8,
        'Member'              => 16,
        ''                    => 32,
        'Banned'              => (1 << 30));  //$status['Banned'] == 2^30

This function currently uses the above array to map the meaning of forum postperm bits to user status strings. The bits were chosen in the order of most authority (most restricted) to least authority (most available).

0 always represents no access. If none of the bits are set then nobody has effective permissions.

32 always represents a guest user. This matches the empty string status because guest users are not saved to the members table in XMB.

2^30 always represents a banned user. This number was added in version 1.9.10 because its absence was causing errors every time a banned user tried to access the forum list in version 1.9.9. The number was chosen because it is close to max int, making it unlikely to interfere with other values, and also because the decimal representation is 10 digits long; it is nearly impossible to inject into the postperm column. (Ideally this system would have been designed the other way around, but it is what it is.)

It is important for forward compatibility that these integers and the array they are in not be used in any new code. In version 1.9.11 a proper enumeration will be located in the header.php file. The syntax for this enumeration will be published as soon as possible.

Changes in XMB 1.9.11

One of the most critical changes in the version 1.9.11 permissions system is the re-formulation of X_PERMS_USERLIST. This change was deemed necessary after discovering the original implementation in version 1.9.9 assigned the wrong value, bool(TRUE), for any user ranked Super Moderator or above. This means Super Moderators were always treated as being in the userlist regardless of the permissions settings.

To make the forum userlist feature even more flexible, the version 1.9.11 forum permissions will be additive rather than subtractive. This is an important difference. In version 1.9.10, turning off View permissions for the Members rank meant that any Member in the userlist would not have access to the forum. This was accomplished by checking:

if ($perm[X_PERMS_VIEW] && $perm[X_PERMS_USERLIST]) {

In version 1.9.11 this syntax is no longer allowed and will result in all permissions being denied for any forum that has a blank userlist. Because we are making permissions additive, turning on View permissions for the Members rank will mean that any Member will have access to the forum, regardless of who is in the userlist. This will be accomplished by checking:

if ($perm[X_PERMS_VIEW] || $perm[X_PERMS_USERLIST]) {

This is, admittedly, an area where mods and hacks will not be forward compatible to the next version, however changes should be minimal when using this recommended syntax. In version 1.9.11, the Userlist permissions will be implicitly combined with the View permissions so that they do not have to be checked separately. So, the previous line of code will be exactly equivalent to:

if ($perm[X_PERMS_VIEW]) {

X_PERMS_USERLIST will still indicate whether or not a user is in the userlist or modlist for a forum. X_PERMS_VIEW, however, doesn't necessarily indicate whether a user has the View permission based on their rank because it could be a View permission based on the user list. In anticipation of the need to know the exact permissions set, we will be adding the X_PERMS_RAWVIEW index for that purpose.

Comprehensive examples of checkForumPermissions() usage are published in the Best Practices section.

When custom code is needed to change the behavior of XMB, one can take advantage of these orderly bit fields without using checkForumPermissions().

Example:

  • You want to change the visibility of forums on the front page based on user rank.
  • You do not want the visibility of forums to be tied directly to the VIEW permission.
  • You have the abillity to edit functions.inc.php.

The function checkForumPermissions() would be useless in this case because it only returns TRUE or FALSE based on the VIEW permission. Instead, you want to create front page rules based on the difference between the status value and the postperm value.

Let's say you want to make the members-only forums visible to guests viewing the front page. It is as simple as writing a few lines of code that boil down to: if (postperm >= $status['Member']) {include the forum}. This means anyone visiting the board could see the link to any forum that is assigned the VIEW permission for members or guests, regardless of whether they are permitted to follow the link and see the threads in that forum. You will be able to do this with a comparison operator and no need for checking the status string itself.

function handlePasswordDialog()

This function is intended to be a seamless procedure call when the user needs to provide a forum password. For example: if (!$perms[X_PERMS_PASSWORD]) { handlePasswordDialog($fid); }

The user will be prompted to enter their password without leaving the page. The user submits the password form to the current URL so that handlePasswordDialog() will be triggered again, a cookie is sent, and the browser is instructed to silently repeat the request so that the user is now fully logged in before the script proceeds.

function permittedForums()

This function is new in XMB 1.9.11. It is designed to replace some of the awkward and repetitive code used throughout XMB to apply the effective View permissions to the list of all forums. permittedForums() is capable of returning either an array of associative arrays, which is a very handy table representation, or a Comma-Seperated Values (CSV) list of forum IDs, which is very handy for creating database queries.

The primary benefit of using this function is that you will not have to do any permissions checking. Just set the proper arguments, and the function will provide exactly the set of forums that the user may access. You can then custom filter the forums using a simple foreach() loop, which can be much faster than using a database query.