public function testGetTree() { $userRepo = $this->getMockBuilder('Doctrine\\ORM\\EntityRepository')->disableOriginalConstructor()->getMock(); $buRepo = $this->getMockBuilder('Doctrine\\ORM\\EntityRepository')->disableOriginalConstructor()->getMock(); $this->em->expects($this->any())->method('getRepository')->will($this->returnCallback(function ($repoName) use($userRepo, $buRepo) { if ($repoName == 'Oro\\Bundle\\UserBundle\\Entity\\User') { return $userRepo; } if ($repoName == 'Oro\\Bundle\\OrganizationBundle\\Entity\\BusinessUnit') { return $buRepo; } })); list($users, $bUnits) = $this->getTestData(); $userRepo->expects($this->any())->method('findAll')->will($this->returnValue($users)); $buRepo->expects($this->any())->method('findAll')->will($this->returnValue($bUnits)); $metadata = $this->getMockBuilder('Doctrine\\ORM\\Mapping\\ClassMetadata')->disableOriginalConstructor()->getMock(); $this->em->expects($this->any())->method('getClassMetadata')->will($this->returnValue($metadata)); $metadata->expects($this->any())->method('getTableName')->will($this->returnValue('test')); $connection = $this->getMockBuilder('Doctrine\\DBAL\\Connection')->disableOriginalConstructor()->getMock(); $this->em->expects($this->any())->method('getConnection')->will($this->returnValue($connection)); $connection->expects($this->any())->method('isConnected')->will($this->returnValue(true)); $schemaManager = $this->getMockBuilder('Doctrine\\DBAL\\Schema\\MySqlSchemaManager')->disableOriginalConstructor()->getMock(); $connection->expects($this->any())->method('getSchemaManager')->will($this->returnValue($schemaManager)); $schemaManager->expects($this->any())->method('listTableNames')->will($this->returnValue(array('test'))); $this->treeProvider->warmUpCache(); $tree = $this->treeProvider->getTree(); $this->assertEquals(1, $tree->getBusinessUnitOrganizationId(1)); $this->assertEquals([1], $tree->getUserOrganizationIds(1)); }
/** * @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); } }
/** * Add user limitation * * @param DatagridConfiguration $config * @param string $accessLevel * @param User $user * @param Organization $organization * * @throws \Exception */ protected function applyACL(DatagridConfiguration $config, $accessLevel, User $user, Organization $organization) { $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); } }
/** * @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); } }
/** * Adds all user ids within all organizations the given user is associated * * @param int|string $userId * @param array $result [output] */ protected function fillOrganizationUserIds($userId, array &$result) { foreach ($this->treeProvider->getTree()->getUserOrganizationIds($userId) as $orgId) { foreach ($this->treeProvider->getTree()->getOrganizationBusinessUnitIds($orgId) as $buId) { $userIds = $this->treeProvider->getTree()->getBusinessUnitUserIds($buId); if (!empty($userIds)) { $result = array_merge($result, $userIds); } } } }
/** * Get business units ids for current user for current access level * * @return array * value -> business unit id */ protected function getBusinessUnitIds() { if (AccessLevel::SYSTEM_LEVEL == $this->accessLevel) { return $this->businessUnitManager->getBusinessUnitIds(); } elseif (AccessLevel::LOCAL_LEVEL == $this->accessLevel) { return $this->treeProvider->getTree()->getUserBusinessUnitIds($this->currentUser->getId(), $this->getOrganizationContextId()); } elseif (AccessLevel::DEEP_LEVEL === $this->accessLevel) { return $this->treeProvider->getTree()->getUserSubordinateBusinessUnitIds($this->currentUser->getId(), $this->getOrganizationContextId()); } elseif (AccessLevel::GLOBAL_LEVEL === $this->accessLevel) { return $this->businessUnitManager->getBusinessUnitIds($this->getOrganizationContextId()); } return []; }
/** * Add ACL Check condition to the Query Builder * * @param QueryBuilder $queryBuilder * @param string $accessLevel * @param User $user * @param Organization $organization */ protected function addAcl(QueryBuilder $queryBuilder, $accessLevel, User $user, Organization $organization) { if ($accessLevel == AccessLevel::BASIC_LEVEL) { $queryBuilder->andWhere($queryBuilder->expr()->in('users.id', [$user->getId()])); } elseif ($accessLevel == AccessLevel::GLOBAL_LEVEL) { $queryBuilder->join('users.organizations', 'org')->andWhere($queryBuilder->expr()->in('org.id', [$organization->getId()])); } elseif ($accessLevel !== AccessLevel::SYSTEM_LEVEL) { 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()); } $queryBuilder->join('users.businessUnits', 'bu')->andWhere($queryBuilder->expr()->in('bu.id', $resultBuIds)); } }
/** * Determines whether the given user has a relation to the given business unit * * @param int|string $userId * @param int|string|null $businessUnitId * @param bool $deep Specify whether subordinate business units should be checked. Defaults to false. * @param int|null $organizationId * @return bool */ protected function isUserBusinessUnit($userId, $businessUnitId, $deep = false, $organizationId = null) { if ($businessUnitId === null) { return false; } foreach ($this->treeProvider->getTree()->getUserBusinessUnitIds($userId, $organizationId) as $buId) { if ($businessUnitId === $buId) { return true; } if ($deep && in_array($businessUnitId, $this->treeProvider->getTree()->getSubordinateBusinessUnitIds($buId))) { return true; } } return false; }
/** * Checks if user can be set as owner by given user * * @param User $currentUser * @param User $newUser * @param string $accessLevel * @param OwnerTreeProvider $treeProvider * @param Organization $organization * * @return bool */ public function canUserBeSetAsOwner(User $currentUser, User $newUser, $accessLevel, OwnerTreeProvider $treeProvider, Organization $organization) { $userId = $newUser->getId(); if ($accessLevel == AccessLevel::SYSTEM_LEVEL) { return true; } elseif ($accessLevel == AccessLevel::BASIC_LEVEL && $userId == $currentUser->getId()) { return true; } elseif ($accessLevel == AccessLevel::GLOBAL_LEVEL && $newUser->getOrganizations()->contains($organization)) { return true; } else { $resultBuIds = []; if ($accessLevel == AccessLevel::LOCAL_LEVEL) { $resultBuIds = $treeProvider->getTree()->getUserBusinessUnitIds($currentUser->getId(), $organization->getId()); } elseif ($accessLevel == AccessLevel::DEEP_LEVEL) { $resultBuIds = $treeProvider->getTree()->getUserSubordinateBusinessUnitIds($currentUser->getId(), $organization->getId()); } if (!empty($resultBuIds)) { $newUserBuIds = $treeProvider->getTree()->getUserBusinessUnitIds($userId, $organization->getId()); $intersectBUIds = array_intersect($resultBuIds, $newUserBuIds); return !empty($intersectBUIds); } } return false; }
/** * {inheritdoc} */ public function clear($cacheDir) { $this->treeProvider->clear(); }
/** * @param object $user * @param bool $expected * * @dataProvider supportsDataProvider */ public function testSupports($user, $expected) { $this->securityFacade->expects($this->once())->method('getLoggedUser')->willReturn($user); $this->assertEquals($expected, $this->treeProvider->supports()); }
/** * {inheritdoc} */ public function warmUp($cacheDir) { $this->treeProvider->warmUpCache(); }