$acl->check($request): boolean
예제 #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);
 }
예제 #2
0
 public function onKernelRequest(GetResponseEvent $event)
 {
     /** @var PageStack $pageStack */
     $pageStack = $this->container->get('jarves.page_stack');
     /** @var ACL $acl */
     $acl = $this->container->get('jarves.acl');
     $editorNodeId = $pageStack->getRequest()->get('_jarves_editor_node');
     $editorDomainId = $pageStack->getRequest()->get('_jarves_editor_domain');
     if (null !== $editorNodeId || null !== $editorDomainId) {
         $pk = $editorNodeId ? ['id' => $editorNodeId] : null;
         if (!$acl->isUpdatable('jarves/node', $pk)) {
             throw new AccessDeniedException('Access denied');
         }
     }
     if ($pageStack->isAdmin()) {
         $whiteList = ['', '/admin/backend/css', '/admin/backend/script', '/admin/ui/languages', '/admin/ui/language', '/admin/ui/language-plural', '/admin/login', '/admin/logged-in'];
         $adminPrefix = $pageStack->getAdminPrefix();
         $url = substr($event->getRequest()->getPathInfo(), strlen($adminPrefix));
         if (in_array($url, $whiteList)) {
             return;
         }
         $hasUser = (bool) $pageStack->getUser();
         $aclPath = '/jarves' . $url;
         //acl rules start always with /jarves
         $hasAccess = $acl->check(ACLRequest::create('jarves/entryPoint', ['path' => $aclPath]));
         if (!$hasUser || !$hasAccess) {
             $response = new Response(json_encode(['status' => 403, 'error' => 'AccessDeniedException', 'message' => 'Access denied.' . (!$pageStack->getUser() ? ' Not logged in.' : '')], JSON_PRETTY_PRINT), 403);
             $response->headers->set('Content-Type', 'application/json');
             $event->setResponse($response);
         }
     }
 }
예제 #3
0
파일: ACL.php 프로젝트: jarves/jarves
 /**
  * @param ACLRequest $aclRequest
  *
  * @return bool
  */
 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;
 }
예제 #4
0
 /**
  * @ApiDoc(
  *  section="Backend",
  *  description="Returns all available menu/entryPoint items for the main navigation bar in the administration"
  * )
  *
  * @Rest\View()
  * @Rest\Get("/admin/backend/menus")
  *
  * @return array
  */
 public function getMenusAction()
 {
     $entryPoints = array();
     foreach ($this->jarves->getConfigs() as $bundleName => $bundleConfig) {
         foreach ($bundleConfig->getAllEntryPoints() as $subEntryPoint) {
             $path = $subEntryPoint->getFullPath();
             if (substr_count($path, '/') <= 3) {
                 if ($subEntryPoint->isLink()) {
                     if ($this->acl->check(ACLRequest::create('jarves/entryPoint', ['path' => '/' . $path]))) {
                         $entryPoints[$path] = array('label' => $subEntryPoint->getLabel(), 'icon' => $subEntryPoint->getIcon(), 'fullPath' => $path, 'path' => $subEntryPoint->getPath(), 'type' => $subEntryPoint->getType(), 'system' => $subEntryPoint->getSystem(), 'templateUrl' => $subEntryPoint->getTemplateUrl(), 'level' => substr_count($path, '/'));
                     }
                 }
             }
         }
     }
     return $entryPoints;
 }
예제 #5
0
 public function testObjectGeneral()
 {
     ItemQuery::create()->deleteAll();
     TestQuery::create()->deleteAll();
     $this->getACL()->removeObjectRules('test/item');
     $this->getACL()->setCaching(false);
     $user = new User();
     $user->setUsername('TestUser');
     $user->save();
     $group = new Group();
     $group->setName('ACL Test group');
     $group->addUser($user);
     $group->save();
     $item1 = new Item();
     $item1->setTitle('Item 1');
     $item1->save();
     $item2 = new Item();
     $item2->setTitle('Item 2');
     $item2->save();
     $test1 = new Test();
     $test1->setName('Test 1');
     $test1->save();
     $aclRequestItem1OnlyListing = ACLRequest::create('test/item', $item1->getId())->onlyListingMode();
     $this->assertFalse($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup($group->getId())), 'we have no rules, so everyone except admin user and admin group has no access.');
     $this->assertTrue($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup(1)), 'we have no rules, so only group admin has access.');
     $this->assertTrue($this->getACL()->check($aclRequestItem1OnlyListing->targetUser(1)), 'we have no rules, so only user admin has access.');
     $this->getACL()->removeObjectRules('test/item');
     $this->getACL()->setObjectList('test/item', \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), true);
     $this->assertTrue($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup($group->getId())), 'testGroup got list access to all test/item objects.');
     $this->getACL()->setObjectListExact('test/item', $item1->getId(), \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), false);
     $this->assertFalse($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup($group->getId())), 'testGroup got list access-denied to item 1.');
     $aclRequestItem2OnlyListing = ACLRequest::create('test/item', $item2->getId())->onlyListingMode();
     $this->assertTrue($this->getACL()->check($aclRequestItem2OnlyListing->targetGroup($group->getId())), 'testGroup still have access to item2.');
     $this->getACL()->setObjectListExact('test/item', $item2->getId(), \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), false);
     $this->assertFalse($this->getACL()->check($aclRequestItem2OnlyListing->targetGroup($group->getId())), 'testGroup does not have access to item2 anymore.');
     $acl = $this->getACL()->setObjectListExact('test/item', $item2->getId(), \Jarves\ACL::TARGET_TYPE_USER, $user->getId(), true);
     $this->assertTrue($this->getACL()->check($aclRequestItem2OnlyListing->targetUser($user->getId())), 'testUser got access through a rule for only him.');
     $acl->setAccess(false);
     $acl->save();
     $this->assertFalse($this->getACL()->check($aclRequestItem2OnlyListing->targetUser($user->getId())), 'testUser got no-access through a rule for only him.');
     //access to every item
     $acl = $this->getACL()->setObjectList('test/item', \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), true);
     $this->assertTrue($this->getACL()->check($aclRequestItem2OnlyListing->targetUser($user->getId())), 'testUser has now access to all items through his group.');
     $this->assertTrue($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup($group->getId())), 'testGroup has now access to all items.');
     $this->assertTrue($this->getACL()->check($aclRequestItem2OnlyListing->targetGroup($group->getId())), 'testGroup has now access to all items.');
     //remove the acl item that gives access to anything.
     $acl->delete();
     $this->assertFalse($this->getACL()->check($aclRequestItem2OnlyListing->targetUser($user->getId())), 'testUser has no access anymore, since we deleted the access-for-all rule.');
     $this->assertFalse($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup($group->getId())), 'testGroup has no access anymore to all items (item1).');
     $this->assertFalse($this->getACL()->check($aclRequestItem2OnlyListing->targetGroup($group->getId())), 'testGroup has no access anymore to all items (item2).');
     //check checkListCondition
     $this->getACL()->setObjectListCondition('test/item', array(array('id', '>', $item1->getId())), \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), true);
     $this->assertTrue($this->getACL()->check($aclRequestItem2OnlyListing->targetGroup($group->getId())), 'testGroup has access to all items after item1');
     $this->assertFalse($this->getACL()->check($aclRequestItem1OnlyListing->targetGroup($group->getId())), 'testGroup has access to all items after item1, but only > , so not item1 itself.');
     //revoke anything to object 'test\item'
     $this->getACL()->setObjectList('test/item', \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), false);
     $this->assertFalse($this->getACL()->check($aclRequestItem2OnlyListing->targetGroup($group->getId())), 'testGroup has no access to all items after item1');
     //check against object test
     $aclRequestTest1OnlyListing = ACLRequest::create('test/test', $test1->getId())->onlyListingMode();
     $this->getACL()->setObjectListExact('test/test', $test1->getId(), \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), true);
     $this->assertTrue($this->getACL()->check($aclRequestTest1OnlyListing->targetGroup($group->getId())), 'testGroup has access test1.');
     $this->getACL()->setObjectList('test/test', \Jarves\ACL::TARGET_TYPE_GROUP, $group->getId(), false);
     $this->assertFalse($this->getACL()->check($aclRequestTest1OnlyListing->targetGroup($group->getId())), 'testGroup has no access test1.');
     $this->getACL()->setCaching(true);
     $this->getACL()->removeObjectRules('test/item');
 }
예제 #6
0
 /**
  * @ApiDoc(
  *  section="Administration",
  *  description="Logs in a user to the current session"
  * )
  *
  * Result on success:
  * {
  *    token: "c7405b2be7da96b0db784f2dc8b2b974",
  *    userId: 1,
  *    username: "******",
  *    access: true, #administration access
  *    firstName: "Admini",
  *    lastName: "strator",
  *    emailMd5: <emailAsMd5>, //for gravatar
  *    imagePath: "/path/to/image.jpg"
  *}
  *
  * @Rest\RequestParam(name="username", requirements=".+", strict=true)
  * @Rest\RequestParam(name="password", requirements=".+", strict=true)
  *
  * @Rest\Post("/admin/login")
  *
  * @param ParamFetcher $paramFetcher
  *
  * @return array|bool Returns false on failure or a array if successful.
  */
 public function loginUserAction(ParamFetcher $paramFetcher, Request $request)
 {
     $username = $paramFetcher->get('username');
     $password = $paramFetcher->get('password');
     $user = $this->userProvider->loadUserByUsername($username);
     if (!$user) {
         $this->logger->warning(sprintf('Login failed for "%s". User not found', $username));
         sleep(1);
         return false;
     }
     $encoder = $this->encoderFactory->getEncoder($user);
     if (!$encoder->isPasswordValid($user->getPassword(), $password, null)) {
         $this->logger->warning(sprintf('Login failed for "%s". Password missmatch ', $username));
         sleep(1);
         return false;
     }
     $token = new UsernamePasswordToken($user, null, "main", $user->getGroupRoles());
     $this->tokenStorage->setToken($token);
     //now dispatch the login event
     $event = new InteractiveLoginEvent($request, $token);
     $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
     return array('userId' => $user->getId(), 'username' => $user->getUsername(), 'lastLogin' => $user->getLastLogin(), 'access' => $this->acl->check(ACLRequest::create('jarves/entryPoint', ['path' => '/admin'])), 'firstName' => $user->getFirstName(), 'lastName' => $user->getLastName(), 'imagePath' => $user->getImagePath());
 }
예제 #7
0
 /**
  * Returns file information as array.
  *
  * @param string|integer $path
  * @return array|null
  */
 protected function getFile($path)
 {
     $file = $this->webFilesystem->getFile($path);
     $file = $file->toArray();
     $aclRequest = ACLRequest::create('jarves/file', $file)->onlyListingMode();
     if (!$file || !$this->acl->check($aclRequest)) {
         return null;
     }
     $file['writeAccess'] = $this->acl->check($aclRequest->onlyUpdateMode());
     $this->appendImageInformation($file);
     return $file;
 }
예제 #8
0
 /**
  * Patches a object entry. This means, only defined fields will be saved. Fields which are not defined will
  * not be overwritten.
  *
  * @param  array $pk
  *
  * @param  Request|array $requestOrData
  * @return bool
  *
  * @throws AccessDeniedException
  * @throws ObjectNotFoundException
  * @throws \Exception
  */
 public function patch($pk, $requestOrData)
 {
     $storageController = $this->objects->getStorageController($this->getObject());
     $pk = $storageController->normalizePrimaryKey($pk);
     $this->primaryKey = $pk;
     $values = $this->collectData($requestOrData);
     $args = ['pk' => $pk, 'values' => &$values, 'controller' => $this, 'mode' => 'update'];
     $eventPre = new GenericEvent($this->getObject(), $args);
     $this->eventDispatcher->dispatch('core/object/modify-pre', $eventPre);
     $this->eventDispatcher->dispatch('core/object/patch-pre', $eventPre);
     $item = $this->getItem($pk);
     if ($this->getPermissionCheck()) {
         if (!$item) {
             return null;
         }
         if (!$this->acl->check(ACLRequest::create($this->getObject(), $pk)->onlyUpdateMode())) {
             return null;
         }
         foreach ($values as $fieldName => $value) {
             $aclRequest = ACLRequest::create($this->getObject(), $pk)->setField([$fieldName => $value])->onlyUpdateMode();
             if (!$this->acl->check($aclRequest)) {
                 throw new AccessDeniedException(sprintf('Not allowed to change `%s`', $fieldName));
             }
         }
     }
     if (($condition = $this->getCondition()) && $condition->hasRules()) {
         if (!$this->conditionOperator->satisfy($condition, $item, $this->getObject())) {
             return null;
         }
     }
     $incomingFields = $requestOrData instanceof Request ? array_keys($requestOrData->request->all()) : array_keys($requestOrData);
     if (!$incomingFields) {
         return false;
     }
     $changedData = $this->mapData($values, $incomingFields, $item);
     if ($this->getWithNewsFeed()) {
         $this->utils->newNewsFeed($this->objects, $this->getObject(), array_merge($values, $pk), 'updated');
     }
     $result = $storageController->patch($pk, $changedData);
     $args['result'] = $result;
     $event = new GenericEvent($this->getObject(), $args);
     $this->eventDispatcher->dispatch('core/object/modify', $event);
     $this->eventDispatcher->dispatch('core/object/patch', $event);
     return $result;
 }