Jarves\ACL::check PHP Method

check() public method

public check ( ACLRequest $aclRequest ) : boolean
$aclRequest ACLRequest
return boolean
    public function check(ACLRequest $aclRequest)
    {
        $objectKey = Objects::normalizeObjectKey($aclRequest->getObjectKey());
        $targetType = $aclRequest->getTargetType();
        $targetId = $aclRequest->getTargetId();
        $pk = $aclRequest->getPrimaryKey();
        $field = $aclRequest->getField();
        $pk = $this->objects->normalizePkString($objectKey, $pk);
        if (ACL::TARGET_TYPE_USER === $targetType && null === $targetId) {
            //0 means guest
            $targetId = $this->pageStack->getUser() ? $this->pageStack->getUser()->getId() : 0;
        }
        $user = $this->pageStack->getUser();
        if ($user) {
            $groupIds = $user->getGroupIds();
            if (false !== strpos(',' . $groupIds . ',', ',1,')) {
                //user is in the admin group, so he has always access.
                return true;
            }
        }
        if (ACL::TARGET_TYPE_USER === $targetType && 1 === $targetId) {
            //user admin has always access
            return true;
        }
        if (ACL::TARGET_TYPE_GROUP === $targetType && 1 === $targetId) {
            //group admin has always access
            return true;
        }
        if (0 === $targetId) {
            //guests do always have no access
            return false;
        }
        if (ACL::TARGET_TYPE_GROUP === $targetType && !$targetId) {
            throw new \InvalidArgumentException('For type TARGET_TYPE_GROUP a targetId is required.');
        }
        $cacheKey = null;
        if ($pk && $this->getCaching()) {
            $pkString = $this->objects->getObjectUrlId($objectKey, $pk);
            $cacheKey = md5($targetType . '.' . $targetId . '.' . $objectKey . '/' . $pkString . '/' . json_encode($field));
            $cached = $this->cacher->getDistributedCache('core/acl/' . $cacheKey);
            if (null !== $cached) {
                return $cached;
            }
        }
        $rules = self::getRules($objectKey, $aclRequest->getMode(), $targetType, $targetId);
        if (count($rules) === 0) {
            //no rules found, so we have no access
            return false;
        }
        $access = null;
        $currentObjectPk = $pk;
        $definition = $this->objects->getDefinition($objectKey);
        $not_found = true;
        //starts directly as if we were in the parent checking.
        $parent_acl = $aclRequest->isAsParent();
        $fCount = null;
        $fKey = null;
        $fValue = null;
        $fIsArray = is_array($field);
        if ($fIsArray) {
            $fCount = count($field);
            $fKey = key($field);
            $fValue = current($field);
            if (is_int($fKey)) {
                $fKey = $fValue;
                $fValue = null;
            }
        }
        $depth = 0;
        $match = false;
        $originObjectItemPk = $currentObjectPk;
        while ($not_found) {
            $currentObjectPkString = null;
            if ($currentObjectPk) {
                $currentObjectPkString = $this->objects->getObjectUrlId($objectKey, $currentObjectPk);
            }
            $depth++;
            if ($depth > 50) {
                $not_found = false;
                break;
            }
            foreach ($rules as $aclRule) {
                if ($parent_acl && !$aclRule['sub']) {
                    //as soon we enter the parent_acl mode we only take acl rules into consideration
                    //that are also valid for children (sub=true)
                    continue;
                }
                $match = false;
                /*
                 * CUSTOM CONSTRAINT
                 */
                if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION) {
                    $objectItem = null;
                    if ($originObjectItemPk === $currentObjectPk && null !== $aclRequest->getPrimaryObjectItem()) {
                        $objectItem = $aclRequest->getPrimaryObjectItem();
                    } else {
                        if ($originObjectItemPk) {
                            $objectItem = $this->objects->get($objectKey, $currentObjectPk);
                        }
                    }
                    if ($objectItem && $this->conditionOperator->satisfy($aclRule['constraint_code'], $objectItem, $objectKey)) {
                        $match = true;
                    }
                    /*
                     * EXACT
                     */
                } else {
                    if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT) {
                        if ($currentObjectPk && $aclRule['constraint_code'] === $currentObjectPkString) {
                            $match = true;
                        }
                        /**
                         * ALL
                         */
                    } else {
                        $match = true;
                    }
                }
                if (!$match && $aclRule['sub'] && $currentObjectPk) {
                    // we need to check if a parent matches this $acl as we have sub=true
                    $parentItem = $this->objects->normalizePkString($objectKey, $currentObjectPk);
                    $parentCondition = Condition::create($aclRule['constraint_code']);
                    $parentOptions['fields'] = $this->conditionOperator->extractFields($parentCondition);
                    while ($parentItem = $this->objects->getParent($objectKey, $this->objects->getObjectPk($objectKey, $parentItem), $parentOptions)) {
                        if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION && $this->conditionOperator->satisfy($parentCondition, $parentItem)) {
                            $match = true;
                            break;
                        } else {
                            if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT && $aclRule['constraint_code'] === $this->objects->getObjectUrlId($objectKey, $parentItem)) {
                                $match = true;
                                break;
                            }
                        }
                    }
                }
                if ($match) {
                    //match, check all $field
                    $field2Key = $field;
                    if ($field) {
                        if ($fIsArray && $fCount === 1) {
                            if (is_string($fKey) && is_array($aclRule['fields'][$fKey])) {
                                //this field has limits
                                if (($field2Acl = $aclRule['fields'][$fKey]) !== null) {
                                    if (is_array($field2Acl[0])) {
                                        //complex field rule, $field2Acl = ([{access: no, condition: [['id', '>', 2], ..]}, {}, ..])
                                        foreach ($field2Acl as $fRule) {
                                            $satisfy = false;
                                            if (($f = $definition->getField($fKey)) && $f->getType() === 'object') {
                                                $uri = $f->getObject() . '/' . $fValue;
                                                $uriObject = $this->objects->getFromUrl($uri);
                                                $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $uriObject);
                                            } else {
                                                if (null !== $fValue) {
                                                    $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $field);
                                                }
                                            }
                                            if ($satisfy) {
                                                return $fRule['access'] === 1 ? true : false;
                                            }
                                        }
                                        //if no field rules fits, we consider the whole rule
                                        if ($aclRule['access'] !== 2) {
                                            return $aclRule['access'] === 1 ? true : false;
                                        }
                                    } else {
                                        //simple field rule $field2Acl = ({"value1": yes, "value2": no}
                                        if ($field2Acl[$fKey] !== null) {
                                            return $field2Acl[$fKey] === 1 ? true : false;
                                        } else {
                                            //current($field) is not exactly defined in $field2Acl, so we set $access to $acl['access']
                                            //
                                            //if access = 2 then wo do not know it, cause 2 means 'inherited', so maybe
                                            //a other rule has more detailed rule
                                            if ($aclRule['access'] !== 2) {
                                                $access = $aclRule['access'] === 1 ? true : false;
                                                break;
                                            }
                                        }
                                    }
                                }
                            } else {
                                //this field has only true or false
                                $field2Key = $fKey;
                            }
                        }
                        if (!is_array($field2Key)) {
                            if ($aclRule['fields'] && ($field2Acl = $aclRule['fields'][$field2Key]) !== null && !is_array($aclRule['fields'][$field2Key])) {
                                $access = $field2Acl === 1 ? true : false;
                                break;
                            } else {
                                //$field is not exactly defined, so we set $access to $acl['access']
                                //and maybe a rule with the same code has the field defined
                                // if access = 2 then this rule is only for exactly define fields
                                if ($aclRule['access'] !== 2) {
                                    $access = $aclRule['access'] === 1 ? true : false;
                                    break;
                                }
                            }
                        }
                    } else {
                        $access = $aclRule['access'] === 1 ? true : false;
                        break;
                    }
                }
            }
            //foreach
            if (null === $access && $definition->isNested() && $pk) {
                //$access has not defined yet (no rule matched yet). Check if nested and $pk is given
                //load its root and check again
                if (null === ($currentObjectPk = $this->objects->getParentPk($objectKey, $currentObjectPk))) {
                    $access = $aclRequest->isRootHasAccess() ? true : $access;
                    break;
                }
                $parent_acl = true;
            } else {
                break;
            }
        }
        $access = (bool) $access;
        if ($pk && $this->getCaching()) {
            $this->cacher->setDistributedCache('core/acl/' . $cacheKey, $access);
        }
        return $access;
    }

Usage Example

Example #1
0
 public function addSessionScripts()
 {
     $response = $this->pageStack->getPageResponse();
     $session = array();
     $session['userId'] = null;
     $session['lang'] = 'en';
     if ($this->pageStack->getSession() && $this->pageStack->getSession()->has('admin_language')) {
         $session['lang'] = $this->pageStack->getSession()->get('admin_language');
     }
     $session['access'] = $this->acl->check(ACLRequest::create('jarves/entryPoint', ['path' => '/admin']));
     if ($this->pageStack->isLoggedIn()) {
         $user = $this->pageStack->getUser();
         $session['userId'] = $user->getId();
         $session['username'] = $user->getUsername();
         $session['lastLogin'] = $user->getLastLogin();
         $session['firstName'] = $user->getFirstName();
         $session['lastName'] = $user->getLastName();
         //            $email = $user->getEmail();
         //            $session['emailMd5'] = $email ? md5(strtolower(trim($email))) : null;
         $session['imagePath'] = $user->getImagePath();
     }
     $session['token'] = get_class($this->pageStack->getToken());
     $css = 'window._session = ' . json_encode($session) . ';';
     $response->addJs($css);
 }
All Usage Examples Of Jarves\ACL::check