Пример #1
0
 /**
  *
  * Mode table:
  *
  *  0 all
  *  1 list
  *  2 view
  *  3 add
  *  4 update
  *  5 delete
  *
  * @static
  *
  * @param        $objectKey
  * @param  int $mode
  *
  * @param integer|null $targetType
  * @param integer|null $targetId
  *
  * @return mixed
  */
 public function getRules($objectKey, $mode = 1, $targetType = ACL::TARGET_TYPE_USER, $targetId = null)
 {
     $objectKey = Objects::normalizeObjectKey($objectKey);
     //normalize input. default is user
     $targetType = ACL::TARGET_TYPE_GROUP === $targetType ? ACL::TARGET_TYPE_GROUP : ACL::TARGET_TYPE_USER;
     $user = null;
     if ($targetType === ACL::TARGET_TYPE_USER) {
         if (!$targetId) {
             $user = $this->pageStack->getUser();
         } else {
             $user = UserQuery::create()->findPk($targetId);
         }
     }
     if (ACL::TARGET_TYPE_USER === $targetType) {
         if ($user) {
             $targetId = $user->getId();
             $inGroups = $user->getGroupIdsArray();
         } else {
             //no user found, so we check against guest
             $targetId = 0;
             $inGroups = [0];
         }
     } else {
         $inGroups = [(string) $targetId];
     }
     $cacheKey = '';
     if ($this->getCaching()) {
         $cacheKey = md5($targetType . '.' . $targetId . '.' . implode(',', $inGroups) . '.' . $objectKey . '.' . $mode);
         $cached = $this->cacher->getDistributedCache('core/acl/rules/' . $cacheKey);
         if (null !== $cached) {
             return $cached;
         }
     }
     $mode += 0;
     $data = array($objectKey, $mode);
     $targets = array();
     //group is always checked. If no user found, $inGroups is 0, which means it checks against Guest group.
     $targets[] = "( target_type = 1 AND target_id IN (?))";
     $data[] = implode(', ', $inGroups);
     if (ACL::TARGET_TYPE_USER === $targetType) {
         //if user type, we include additionally all user rules
         $targets[] = "( target_type = 0 AND target_id = ?)";
         if ($user) {
             $data[] = $user->getId();
         } else {
             //no user found, so we check against guest
             $data[] = 0;
         }
     }
     //now it gets dirty. A bit more complicated query, so we do it directly with PDO.
     $con = Propel::getReadConnection('default');
     $targets = implode(' OR ', $targets);
     $query = "\n                SELECT constraint_type, constraint_code, mode, access, sub, fields\n                FROM system_acl\n                WHERE\n                object = ? AND\n                (mode = ? OR mode = 0) AND\n                (\n                    {$targets}\n                )\n                ORDER BY prio DESC\n        ";
     $stmt = $con->prepare($query);
     $stmt->execute($data);
     $rules = array();
     while ($rule = $stmt->fetch(\PDO::FETCH_ASSOC)) {
         $rule['mode'] = (int) $rule['mode'];
         $rule['access'] = (int) $rule['access'];
         $rule['sub'] = (bool) $rule['sub'];
         $rule['constraint_type'] = (int) $rule['constraint_type'];
         if ($rule['fields'] && substr($rule['fields'], 0, 1) === '{') {
             $rule['fields'] = json_decode($rule['fields'], true);
         }
         if ($rule['constraint_type'] === ACL::CONSTRAINT_CONDITION && substr($rule['constraint_code'], 0, 1) === '[') {
             $rule['constraint_code'] = json_decode($rule['constraint_code'], true);
         }
         $rules[] = $rule;
     }
     if ($this->getCaching()) {
         $this->cacher->setDistributedCache('core/acl/rules/' . $cacheKey, $rules);
         return $rules;
     } else {
         return $rules;
     }
 }
Пример #2
0
 public function testNestedSubPermission()
 {
     $this->getACL()->setCaching(false);
     $this->getACL()->removeObjectRules('jarves/node');
     $tokenStorage = $this->getTokenStorage();
     $token = new UsernamePasswordToken(UserQuery::create()->findOneByUsername('test'), null, "main");
     $tokenStorage->setToken($token);
     $user = $this->getPageStack()->getUser();
     $this->assertEquals('test', $user->getUsername());
     $domain = DomainQuery::create()->findOne();
     $root = NodeQuery::create()->findRoot($domain->getId());
     $subNode = new Node();
     $subNode->setTitle('TestNode tree');
     $subNode->insertAsFirstChildOf($root);
     $subNode->save();
     $subNode2 = new Node();
     $subNode2->setTitle('TestNode sub');
     $subNode2->insertAsFirstChildOf($subNode);
     $subNode2->save();
     //make access for all
     $rule = new Acl();
     $rule->setAccess(true);
     $rule->setObject('jarves/node');
     $rule->setTargetType(\Jarves\ACL::TARGET_TYPE_USER);
     $rule->setTargetId($user->getId());
     $rule->setMode(\Jarves\ACL::MODE_ALL);
     $rule->setConstraintType(\Jarves\ACL::CONSTRAINT_ALL);
     $rule->setPrio(2);
     $rule->save();
     //revoke access for all children of `TestNode tree`
     $rule2 = new Acl();
     $rule2->setAccess(false);
     $rule2->setObject('jarves/node');
     $rule2->setTargetType(\Jarves\ACL::TARGET_TYPE_USER);
     $rule2->setTargetId($user->getId());
     $rule2->setMode(\Jarves\ACL::MODE_ALL);
     $rule2->setConstraintType(\Jarves\ACL::CONSTRAINT_CONDITION);
     $rule2->setConstraintCode(json_encode(['title', '=', 'TestNode tree']));
     $rule2->setPrio(3);
     $rule2->setSub(true);
     $rule2->save();
     $this->getCacher()->invalidateCache('core');
     $node1RequestListing = ACLRequest::create('jarves/node', $subNode->getId())->onlyListingMode();
     $node2RequestListing = ACLRequest::create('jarves/node', $subNode2->getId())->onlyListingMode();
     $this->assertFalse($this->getACL()->check($node1RequestListing));
     $this->assertFalse($this->getACL()->check($node2RequestListing));
     $items = $this->getObjects()->getBranch('jarves/node', $subNode->getId(), null, 1, null, ['permissionCheck' => true]);
     $this->assertNull($items, 'rule2 revokes the access to all elements');
     $item = $this->getObjects()->get('jarves/node', $subNode2->getId(), ['permissionCheck' => true]);
     $this->assertNull($item);
     // Deactivate sub
     $rule2->setSub(false);
     $rule2->save();
     $this->assertFalse($this->getACL()->check($node1RequestListing));
     $this->assertTrue($this->getACL()->check($node2RequestListing));
     $items = $this->getObjects()->getBranch('jarves/node', $subNode->getId(), null, 1, null, ['permissionCheck' => true]);
     $this->assertEquals('TestNode sub', $items[0]['title'], 'We got TestNode sub');
     $item = $this->getObjects()->get('jarves/node', $subNode2->getId(), ['permissionCheck' => true]);
     $this->assertEquals('TestNode sub', $item['title'], 'We got TestNode sub');
     // Activate access
     $rule2->setAccess(true);
     $rule2->save();
     $this->assertTrue($this->getACL()->check($node1RequestListing));
     $this->assertTrue($this->getACL()->check($node2RequestListing));
     $items = $this->getObjects()->getBranch('jarves/node', $subNode->getId(), null, 1, null, ['permissionCheck' => true]);
     $this->assertEquals('TestNode sub', $items[0]['title'], 'We got TestNode sub');
     $subNode->delete();
     $subNode2->delete();
     $rule->delete();
     $rule2->delete();
     $this->getACL()->setCaching(true);
 }