Example #1
0
 /**
  * {@inheritdoc}
  */
 public function search($query, $page, $perPage, $searchById = false)
 {
     list($search, $entityClass, $permission, $entityId, $excludeCurrentUser) = explode(';', $query);
     $entityClass = str_replace('_', '\\', $entityClass);
     if ($entityId) {
         $object = $this->em->getRepository($entityClass)->find((int) $entityId);
     } else {
         $object = 'entity:' . $entityClass;
     }
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $isGranted = $this->getSecurityContext()->isGranted($permission, $object);
     if ($isGranted) {
         $results = [];
         if ($searchById) {
             $results[] = $this->em->getRepository('OroUserBundle:User')->find((int) $query);
         } else {
             $user = $this->getSecurityContext()->getToken()->getUser();
             $organization = $this->getSecurityContext()->getToken()->getOrganizationContext();
             $queryBuilder = $this->getSearchQueryBuilder($search);
             if ((bool) $excludeCurrentUser) {
                 $this->excludeUser($queryBuilder, $user);
             }
             $this->addAcl($queryBuilder, $observer->getAccessLevel(), $user, $organization);
             $results = $queryBuilder->getQuery()->getResult();
         }
         $resultsData = [];
         foreach ($results as $user) {
             $resultsData[] = $this->convertItem($user);
         }
     } else {
         $resultsData = [];
     }
     return ['results' => $resultsData, 'more' => false];
 }
 /**
  * @param BuildBefore $event
  */
 public function onBuildBefore(BuildBefore $event)
 {
     $config = $event->getConfig();
     $object = 'entity:Oro\\Bundle\\OrganizationBundle\\Entity\\BusinessUnit';
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $this->getSecurityContext()->isGranted('VIEW', $object);
     $user = $this->getSecurityContext()->getToken()->getUser();
     $organization = $this->getSecurityContext()->getToken()->getOrganizationContext();
     $accessLevel = $observer->getAccessLevel();
     $where = $config->offsetGetByPath('[source][query][where][and]', []);
     if ($accessLevel == AccessLevel::GLOBAL_LEVEL) {
         $leftJoins = $config->offsetGetByPath('[source][query][join][inner]', []);
         $leftJoins[] = ['join' => 'u.organization', 'alias' => 'org'];
         $config->offsetSetByPath('[source][query][join][inner]', $leftJoins);
         $where = array_merge($where, ['org.id in (' . $organization->getId() . ')']);
     } elseif ($accessLevel !== AccessLevel::SYSTEM_LEVEL) {
         $resultBuIds = [];
         if ($accessLevel == AccessLevel::LOCAL_LEVEL) {
             $resultBuIds = $this->treeProvider->getTree()->getUserBusinessUnitIds($user->getId(), $organization->getId());
         } elseif ($accessLevel == AccessLevel::DEEP_LEVEL) {
             $resultBuIds = $this->treeProvider->getTree()->getUserSubordinateBusinessUnitIds($user->getId(), $organization->getId());
         }
         if (count($resultBuIds)) {
             $where = array_merge($where, ['u.id in (' . implode(', ', $resultBuIds) . ')']);
         } else {
             // There are no records to show, make query to return empty result
             $where = array_merge($where, ['1 = 0']);
         }
     }
     if (count($where)) {
         $config->offsetSetByPath('[source][query][where][and]', $where);
     }
 }
 /**
  * Get data for query acl access level check
  * Return null if entity has full access, empty array if user does't have access to the entity
  *  and array with entity field and field values witch user have access.
  *
  * @param $entityClassName
  * @param $permissions
  * @return null|array
  */
 public function getAclConditionData($entityClassName, $permissions = 'VIEW')
 {
     if ($this->aclVoter === null || !$this->getUserId() || !$this->entityMetadataProvider->isProtectedEntity($entityClassName)) {
         return [];
     }
     $condition = null;
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $isGranted = $this->getSecurityContext()->isGranted($permissions, 'entity:' . $entityClassName);
     if ($isGranted) {
         $condition = $this->buildConstraintIfAccessIsGranted($entityClassName, $observer->getAccessLevel(), $this->metadataProvider->getMetadata($entityClassName));
     }
     return $condition;
 }
Example #4
0
 /**
  * Check is granting user to object in given permission
  *
  * @param string        $permission
  * @param object|string $object
  */
 protected function checkIsGranted($permission, $object)
 {
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $this->isAssignGranted = $this->securityFacade->isGranted($permission, $object);
     $this->accessLevel = $observer->getAccessLevel();
 }
 /**
  * Get ACL sql conditions and join statements to check shared records
  *
  * @param string $entityName
  * @param string $entityAlias
  * @param mixed $permissions
  *
  * @return array
  */
 public function getAclShareData($entityName, $entityAlias, $permissions = BasicPermissionMap::PERMISSION_VIEW)
 {
     if ($permissions !== BasicPermissionMap::PERMISSION_VIEW) {
         return null;
     }
     $aclClass = $this->getObjectManager()->getRepository('OroSecurityBundle:AclClass')->findOneBy(['classType' => $entityName]);
     if (!$aclClass) {
         return null;
     }
     $shareConfig = null;
     if ($this->configProvider->hasConfig($entityName)) {
         $shareConfig = $this->configProvider->getConfig($entityName)->get('share_scopes');
     }
     if (!$shareConfig) {
         return null;
     }
     $aclSIds = $this->getSecurityIdentityIds((array) $shareConfig);
     if (empty($aclSIds)) {
         return null;
     }
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $isGranted = $this->getSecurityContext()->isGranted($permissions, 'entity:' . $entityName);
     if (!$isGranted || !in_array($observer->getAccessLevel(), $this->shareAccessLevels)) {
         return null;
     }
     $shareCondition = ['existsSubselect' => ['select' => 1, 'from' => ['schemaName' => self::ACL_ENTRIES_SCHEMA_NAME, 'alias' => self::ACL_ENTRIES_ALIAS], 'where' => $this->getShareSubselectWhereConditions($entityAlias, $aclSIds, $aclClass)], 'not' => false];
     //Add query components for OutputSqlWalker
     $queryComponents[self::ACL_ENTRIES_ALIAS] = ['metadata' => $this->getObjectManager()->getClassMetadata(self::ACL_ENTRIES_SCHEMA_NAME), 'parent' => null, 'relation' => null, 'map' => null, 'nestingLevel' => null, 'token' => null];
     return [$shareCondition, $queryComponents];
 }
 /**
  * @param BuildBefore $event
  */
 public function onBuildBefore(BuildBefore $event)
 {
     $config = $event->getConfig();
     $parameters = $event->getDatagrid()->getParameters();
     $permission = $parameters->get('permission');
     $entityClass = str_replace('_', '\\', $parameters->get('entity'));
     $entityId = $parameters->get('entity_id');
     if ($entityId) {
         $object = $this->em->getRepository($entityClass)->find((int) $entityId);
     } else {
         $object = 'entity:' . $entityClass;
     }
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $this->getSecurityContext()->isGranted($permission, $object);
     $user = $this->getSecurityContext()->getToken()->getUser();
     $organization = $this->getSecurityContext()->getToken()->getOrganizationContext();
     $accessLevel = $observer->getAccessLevel();
     $where = $config->offsetGetByPath('[source][query][where][and]', []);
     /** todo: refactor this check usages */
     if ($accessLevel == AccessLevel::BASIC_LEVEL) {
         $where = array_merge($where, ['u.id = ' . $user->getId()]);
     } elseif ($accessLevel == AccessLevel::GLOBAL_LEVEL) {
         $leftJoins = $config->offsetGetByPath('[source][query][join][inner]', []);
         $leftJoins[] = ['join' => 'u.organizations', 'alias' => 'org'];
         $config->offsetSetByPath('[source][query][join][inner]', $leftJoins);
         $where = array_merge($where, ['org.id in (' . $organization->getId() . ')']);
     } elseif ($accessLevel !== AccessLevel::SYSTEM_LEVEL) {
         $resultBuIds = [];
         if ($accessLevel == AccessLevel::LOCAL_LEVEL) {
             $resultBuIds = $this->treeProvider->getTree()->getUserBusinessUnitIds($user->getId(), $organization->getId());
         } elseif ($accessLevel == AccessLevel::DEEP_LEVEL) {
             $resultBuIds = $this->treeProvider->getTree()->getUserSubordinateBusinessUnitIds($user->getId(), $organization->getId());
         }
         $leftJoins = $config->offsetGetByPath('[source][query][join][inner]', []);
         $leftJoins[] = ['join' => 'u.businessUnits', 'alias' => 'bu'];
         $config->offsetSetByPath('[source][query][join][inner]', $leftJoins);
         $where = array_merge($where, ['bu.id in (' . implode(', ', $resultBuIds) . ')']);
     }
     if (count($where)) {
         $config->offsetSetByPath('[source][query][where][and]', $where);
     }
 }
Example #7
0
 /**
  * {@inheritdoc}
  *
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 public function search($query, $page, $perPage, $searchById = false)
 {
     list($search, $entityClass, $permission, $entityId, $excludeCurrentUser) = explode(';', $query);
     $entityClass = $this->decodeClassName($entityClass);
     $hasMore = false;
     $object = $entityId ? $this->em->getRepository($entityClass)->find((int) $entityId) : 'entity:' . $entityClass;
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     if ($this->getSecurityContext()->isGranted($permission, $object)) {
         $results = [];
         if ($searchById) {
             $results = $this->searchById($search);
         } else {
             $page = (int) $page > 0 ? (int) $page : 1;
             $perPage = (int) $perPage > 0 ? (int) $perPage : 10;
             $firstResult = ($page - 1) * $perPage;
             $perPage += 1;
             $user = $this->getSecurityContext()->getToken()->getUser();
             $organization = $this->getSecurityContext()->getToken()->getOrganizationContext();
             $queryBuilder = $this->createQueryBuilder();
             $this->addSearchCriteria($queryBuilder, $search);
             if ((bool) $excludeCurrentUser) {
                 $this->excludeUser($queryBuilder, $user);
             }
             $this->addAdditionalFilterCriteria($queryBuilder);
             $queryBuilder->setFirstResult($firstResult)->setMaxResults($perPage);
             $query = $this->applyAcl($queryBuilder, $observer->getAccessLevel(), $user, $organization);
             $results = $query->getResult();
             $hasMore = count($results) == $perPage;
         }
         $resultsData = [];
         foreach ($results as $user) {
             $resultsData[] = $this->convertItem($user);
         }
     } else {
         $resultsData = [];
     }
     return ['results' => $resultsData, 'more' => $hasMore];
 }
 /**
  * Get data for query acl access level check
  * Return empty array if entity has full access, null if user does't have access to the entity
  *  and array with entity field and field values which user have access.
  *
  * @param $entityClassName
  * @param $permissions
  *
  * @return null|array
  */
 public function getAclConditionData($entityClassName, $permissions = 'VIEW')
 {
     if ($this->aclVoter === null || !$this->getUserId() || !$this->entityMetadataProvider->isProtectedEntity($entityClassName)) {
         // return full access to the entity
         return [];
     }
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $groupedEntityClassName = $entityClassName;
     if ($this->aclGroupProvider) {
         $group = $this->aclGroupProvider->getGroup();
         if ($group) {
             $groupedEntityClassName = sprintf('%s@%s', $this->aclGroupProvider->getGroup(), $entityClassName);
         }
     }
     $isGranted = $this->getSecurityContext()->isGranted($permissions, new ObjectIdentity('entity', $groupedEntityClassName));
     if ($isGranted) {
         $condition = $this->buildConstraintIfAccessIsGranted($entityClassName, $observer->getAccessLevel(), $this->metadataProvider->getMetadata($entityClassName));
     } else {
         $condition = $this->getAccessDeniedCondition();
     }
     return $condition;
 }
 /**
  * @param BuildBefore $event
  */
 public function onBuildBefore(BuildBefore $event)
 {
     $parameters = $event->getDatagrid()->getParameters();
     $permission = $parameters->get('permission');
     if ($parameters->get('entity')) {
         $entityClass = str_replace('_', '\\', $parameters->get('entity'));
     } else {
         $entityClass = 'Oro\\Bundle\\UserBundle\\Entity\\User';
     }
     $entityId = $parameters->get('entity_id');
     if ($entityId) {
         $object = $this->em->getRepository($entityClass)->find((int) $entityId);
     } else {
         $object = 'entity:' . $entityClass;
     }
     $observer = new OneShotIsGrantedObserver();
     $this->aclVoter->addOneShotIsGrantedObserver($observer);
     $this->getSecurityContext()->isGranted($permission, $object);
     $accessLevel = $observer->getAccessLevel();
     $config = $event->getConfig();
     $user = $this->getSecurityContext()->getToken()->getUser();
     $organization = $this->getSecurityContext()->getToken()->getOrganizationContext();
     $this->applyACL($config, $accessLevel, $user, $organization);
 }
 public function testVote()
 {
     $selector = $this->getMockBuilder('Oro\\Bundle\\SecurityBundle\\Acl\\Extension\\AclExtensionSelector')->disableOriginalConstructor()->getMock();
     $permissionMap = $this->getMock('Symfony\\Component\\Security\\Acl\\Permission\\PermissionMapInterface');
     $voter = new AclVoter($this->getMock('Symfony\\Component\\Security\\Acl\\Model\\AclProviderInterface'), $this->getMock('Symfony\\Component\\Security\\Acl\\Model\\ObjectIdentityRetrievalStrategyInterface'), $this->getMock('Symfony\\Component\\Security\\Acl\\Model\\SecurityIdentityRetrievalStrategyInterface'), $permissionMap);
     $voter->setAclExtensionSelector($selector);
     $token = $this->getMock('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface');
     $object = new \stdClass();
     $extension = $this->getMock('Oro\\Bundle\\SecurityBundle\\Acl\\Extension\\AclExtensionInterface');
     $extension->expects($this->once())->method('getAccessLevel')->with($this->equalTo(1))->will($this->returnValue(AccessLevel::LOCAL_LEVEL));
     $isGrantedObserver = $this->getMockBuilder('Oro\\Bundle\\SecurityBundle\\Acl\\Domain\\OneShotIsGrantedObserver')->disableOriginalConstructor()->getMock();
     $voter->addOneShotIsGrantedObserver($isGrantedObserver);
     $isGrantedObserver->expects($this->once())->method('setAccessLevel')->with($this->equalTo(AccessLevel::LOCAL_LEVEL));
     $selector->expects($this->exactly(2))->method('select')->with($this->identicalTo($object))->will($this->returnValue($extension));
     $inVoteToken = null;
     $inVoteObject = null;
     $inVoteExtension = null;
     $permissionMap->expects($this->exactly(2))->method('getMasks')->will($this->returnCallback(function () use(&$voter, &$inVoteToken, &$inVoteObject, &$inVoteExtension) {
         $inVoteToken = $voter->getSecurityToken();
         $inVoteObject = $voter->getObject();
         $inVoteExtension = $voter->getAclExtension();
         $voter->setTriggeredMask(1);
         return null;
     }));
     $this->assertNull($voter->getSecurityToken());
     $this->assertNull($voter->getObject());
     $this->assertNull($voter->getAclExtension());
     $voter->vote($token, $object, array('test'));
     $this->assertNull($voter->getSecurityToken());
     $this->assertNull($voter->getObject());
     $this->assertNull($voter->getAclExtension());
     $this->assertTrue($token === $inVoteToken);
     $this->assertTrue($object === $inVoteObject);
     $this->assertTrue($extension === $inVoteExtension);
     // call the vote method one more time to ensure that OneShotIsGrantedObserver was removed from the voter
     $voter->vote($token, $object, array('test'));
 }