How to determine if a user has access to a context

I’m trying to determine using PHP and MODX API if a given user has any access to a specific context.

In my specific case, I really only need to know if the user have any access to the manager (mgr context). I need to be able to determine it on the back end (i.e., without requiring the user to attempt to log on first).

Maybe someone has a better answer, but here are my 2 cents.

Access control in MODX is quite complex. I did not fin any direct method that can provide the list of contexts a user is authorised to.

One possible way, which might be sufficient for your case, is through the groups to which the user belongs. You could do a follows :

Step 1: If you look at the “mgr” context in the manager, you can find which groups have manager access, with the policy you think is necessary for access to the manager. To find this, go to the system menu (“cog menu”), select the “Contexts” option. Edit the Web context and go to the “Access permissions” tab.

Step 2: From this list, write down which groups have the access policy or policies that provide the manager access you require in your script.

Step 3: Find to which groups the user belongs using the getUsergroups() or getUserGroupNames() method of the $modx->user object. Determine if he belongs to one of the groups you have identified in step 2.

If you need to find also the groups authorised to the manager through the API, it can get more complex, depending on your exact requirement.

But as a starter, you could query modAccessContext (through an XPDO query) to find the list of groups authorised to the “mgr” context, and match this with the list of groups the user belongs to.

My 2 cents.
The code loops through all the users and determines if they have any defined policy for the ‘mgr’ context.

<?php
//load all active users
$users = $modx->getCollection('modUser', array('active' => true));
$ouput = array();
foreach ($users as $user) {
    $user_id = $user->get('id');
    $context = 'mgr';
    //load context access policies for this user
    $attributes = $modx->call('modAccessContext','loadAttributes',array(&$modx, $context, $user_id));
    
    $has_access = 'No Access';
    foreach ($attributes as $acl_context => $acl) {
        if ($acl_context == $context){
            //there are policies for the context 'mgr'
            $has_access = 'Access';
            //loop through the policies in $acl if 'has access' needs to be specified more specifically
        }
    }
    
    $ouput[$user->get('username')] = $has_access;
}
return json_encode($ouput);

Thanks. That got me the missing pieces that I needed. Here’s my function to determine if a specific user has access to a specific context, optionally ignoring sudo access:

<?php
public function hasContextAccess($user, $context, $ignoreSudo = false)
{
        global $modx;

        if (!$ignoreSudo && $user->get('sudo')) return true;

        $attributes = $modx->call('modAccessContext','loadAttributes',array(&$modx, $context, $user->get('id')));

        foreach ($attributes as $aclContext => $acl)
        {
                if ($aclContext == $context) return true;
        }

        return false;
}