/**
     * Apply the ACL constraints to the specified query builder, using the permission definition
     *
     * @param QueryBuilder         $queryBuilder  The query builder
     * @param PermissionDefinition $permissionDef The permission definition
     *
     * @return QueryBuilder
     */
    public function apply(QueryBuilder $queryBuilder, PermissionDefinition $permissionDef)
    {
        $aclConnection = $this->em->getConnection();
        $databasePrefix = is_file($aclConnection->getDatabase()) ? '' : $aclConnection->getDatabase() . '.';
        $rootEntity = $permissionDef->getEntity();
        $linkAlias = $permissionDef->getAlias();
        // Only tables with a single ID PK are currently supported
        $linkField = $this->em->getClassMetadata($rootEntity)->getSingleIdentifierColumnName();
        $rootEntity = '"' . str_replace('\\', '\\\\', $rootEntity) . '"';
        $query = $queryBuilder;
        $builder = new MaskBuilder();
        foreach ($permissionDef->getPermissions() as $permission) {
            $mask = constant(get_class($builder) . '::MASK_' . strtoupper($permission));
            $builder->add($mask);
        }
        $mask = $builder->get();
        /* @var $token TokenInterface */
        $token = $this->tokenStorage->getToken();
        $userRoles = array();
        if (!is_null($token)) {
            $user = $token->getUser();
            $userRoles = $this->roleHierarchy->getReachableRoles($token->getRoles());
        }
        // Security context does not provide anonymous role automatically.
        $uR = array('"IS_AUTHENTICATED_ANONYMOUSLY"');
        /* @var $role RoleInterface */
        foreach ($userRoles as $role) {
            // The reason we ignore this is because by default FOSUserBundle adds ROLE_USER for every user
            if ($role->getRole() !== 'ROLE_USER') {
                $uR[] = '"' . $role->getRole() . '"';
            }
        }
        $uR = array_unique($uR);
        $inString = implode(' OR s.identifier = ', (array) $uR);
        if (is_object($user)) {
            $inString .= ' OR s.identifier = "' . str_replace('\\', '\\\\', get_class($user)) . '-' . $user->getUserName() . '"';
        }
        $joinTableQuery = <<<SELECTQUERY
SELECT DISTINCT o.object_identifier as id FROM {$databasePrefix}acl_object_identities as o
INNER JOIN {$databasePrefix}acl_classes c ON c.id = o.class_id
LEFT JOIN {$databasePrefix}acl_entries e ON (
    e.class_id = o.class_id AND (e.object_identity_id = o.id
    OR {$aclConnection->getDatabasePlatform()->getIsNullExpression('e.object_identity_id')})
)
LEFT JOIN {$databasePrefix}acl_security_identities s ON (
s.id = e.security_identity_id
)
WHERE c.class_type = {$rootEntity}
AND (s.identifier = {$inString})
AND e.mask & {$mask} > 0
SELECTQUERY;
        $query->join($linkAlias, '(' . $joinTableQuery . ')', 'perms_', 'perms_.id = ' . $linkAlias . '.' . $linkField);
        return $query;
    }
 /**
  * Returns true if $user is granted $requiredRole
  * @param $requiredRole
  * @param UserInterface $user
  * @return bool
  */
 public function isGranted($requiredRole, UserInterface $user)
 {
     $requiredRole = new Role($requiredRole);
     foreach ($user->getRoles() as $role) {
         $hierarchy = $this->roleHierarchy->getReachableRoles([new Role($role)]);
         if (in_array($requiredRole, $hierarchy)) {
             return true;
         }
     }
     return false;
 }
 /**
  * @param array $arguments
  * @return array
  */
 private function getVariables(array $arguments)
 {
     $token = $this->tokenStorage->getToken();
     if ($this->roleHierarchy !== null) {
         $roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
     } else {
         $roles = $token->getRoles();
     }
     $variables = array('token' => $token, 'user' => $token->getUser(), 'roles' => array_map(function (Role $role) {
         return $role->getRole();
     }, $roles), 'trust_resolver' => $this->trustResolver, 'auth_checker' => $this->authChecker, 'args' => $arguments);
     return $variables;
 }
Example #4
0
 /**
  * @param Connection    $connection
  * @param UserInterface $user
  *
  * @return int[]
  */
 private function findSidIds(Connection $connection, UserInterface $user = null)
 {
     $userSid = $this->aclIdentifier->getUserSecurityIdentity($user);
     $queryBuilder = $connection->createQueryBuilder();
     $queryBuilder->select('acl_s.id')->from($this->aclTables['sid'], 'acl_s')->where('acl_s.username = :username_true AND acl_s.identifier = :identifier')->setParameter('identifier', $userSid->getClass() . '-' . $userSid->getUsername())->setParameter('username_true', true, \PDO::PARAM_BOOL);
     if (null === $user && null !== $this->tokenStorage->getToken()) {
         $user = $this->tokenStorage->getToken()->getUser();
     }
     if ($user instanceof UserInterface) {
         $roles = $this->roleHierarchy->getReachableRoles(array_map(function ($role) {
             if (is_string($role)) {
                 $role = new Role($role);
             }
             return $role;
         }, $user->getRoles()));
         $roles = array_map(function (RoleInterface $role) {
             return $role->getRole();
         }, $roles);
         if (!empty($roles)) {
             $queryBuilder->orWhere('acl_s.username = :username_false AND acl_s.identifier IN (:roles)')->setParameter('roles', $roles, Connection::PARAM_STR_ARRAY)->setParameter('username_false', false, \PDO::PARAM_BOOL);
         }
     }
     return array_map(function (array $row) {
         return (int) $row['id'];
     }, $queryBuilder->execute()->fetchAll());
 }
 /**
  * @param  TokenInterface $token
  * @return array
  */
 protected function getUserRoles(TokenInterface $token)
 {
     $roles = array();
     foreach ($this->roleHierarchy->getReachableRoles($token->getRoles()) as $role) {
         $roles[] = $role->getRole();
     }
     return array_unique($roles);
 }
Example #6
0
 /**
  * @param $roleName
  * @param TokenInterface $token
  * @return bool
  */
 protected function hasRole($roleName, TokenInterface $token)
 {
     foreach ($this->roleHierarchy->getReachableRoles($token->getRoles()) as $role) {
         if ($roleName === $role->getRole()) {
             return true;
         }
     }
     return false;
 }
 /**
  * Evaluate the annotation
  *
  * @param GroupSecurityInterface $annotation
  * @param Request $request 
  */
 protected function evaluate(GroupSecurityInterface $annotation, Request $request)
 {
     $roles = array_map(function ($role) {
         return $role->getRole();
     }, $this->roleHierarchy->getReachableRoles($this->tokenStorage->getToken()->getRoles()));
     if ($annotation->isStrictExpression() || !in_array($this->adminRole, $roles)) {
         if (!$this->language->evaluate($annotation->getExpression(), array("group" => $this->getGroup($annotation, $request), "groupSecurityChecker" => $this->groupSecurityChecker))) {
             throw new AccessDeniedException("GroupSecurity's expression (\"" . $annotation->expression . "\") denied access.");
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function getSecurityIdentities(Token\TokenInterface $token)
 {
     $sids = array();
     // add user security identity
     if (!$token instanceof Token\AnonymousToken) {
         try {
             $sids[] = UserSecurityIdentity::fromToken($token);
         } catch (\InvalidArgumentException $invalid) {
             // ignore, user has no user security identity
         }
     }
     // add all reachable roles
     foreach ($this->roleHierarchy->getReachableRoles($token->getRoles()) as $role) {
         $sids[] = new RoleSecurityIdentity($role);
     }
     // add journal roles
     $user = $token->getUser();
     try {
         $selectedJournal = $this->journalService->getSelectedJournal();
     } catch (\Exception $e) {
         $selectedJournal = false;
     }
     if ($user instanceof User && $selectedJournal instanceof Journal) {
         foreach ($user->getJournalRoles($selectedJournal) as $journalRoles) {
             $sids[] = new JournalRoleSecurityIdentity($journalRoles[0], $journalRoles[1]);
         }
     }
     // add built-in special roles
     if ($this->authenticationTrustResolver->isFullFledged($token)) {
         $sids[] = new RoleSecurityIdentity(AuthenticatedVoter::IS_AUTHENTICATED_FULLY);
         $sids[] = new RoleSecurityIdentity(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED);
         $sids[] = new RoleSecurityIdentity(AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY);
     } elseif ($this->authenticationTrustResolver->isRememberMe($token)) {
         $sids[] = new RoleSecurityIdentity(AuthenticatedVoter::IS_AUTHENTICATED_REMEMBERED);
         $sids[] = new RoleSecurityIdentity(AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY);
     } elseif ($this->authenticationTrustResolver->isAnonymous($token)) {
         $sids[] = new RoleSecurityIdentity(AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY);
     }
     return $sids;
 }
 /**
  * @covers Kunstmaan\AdminBundle\Helper\Security\Acl\AclNativeHelper::apply
  */
 public function testApplyAnonymous()
 {
     $queryBuilder = new QueryBuilder($this->conn);
     $queryBuilder->add('from', array(array('table' => 'myTable', 'alias' => 'n')));
     $roles = array();
     $this->token->expects($this->once())->method('getRoles')->will($this->returnValue($roles));
     $this->rh->expects($this->once())->method('getReachableRoles')->with($roles)->will($this->returnValue($roles));
     $this->token->expects($this->any())->method('getUser')->will($this->returnValue('anon.'));
     $permissionDef = new PermissionDefinition(array('view'), 'Kunstmaan\\NodeBundle\\Entity\\Node', 'n');
     /* @var $qb QueryBuilder */
     $qb = $this->object->apply($queryBuilder, $permissionDef);
     $query = $qb->getSQL();
     $this->assertContains('"IS_AUTHENTICATED_ANONYMOUSLY"', $query);
 }
Example #10
0
 protected function extractRoles(TokenInterface $token)
 {
     // FIXME: this is the definition of a hack
     if (property_exists($token, 'reachableRoles') === true) {
         return $token->reachableRoles;
     }
     if ($token->getUsername() === 'anon.') {
         $roles = [new Role('ROLE_PUBLIC')];
     } else {
         $roles = $token->getRoles();
     }
     $token->reachableRoles = $this->roleHierarchy->getReachableRoles($roles);
     return $token->reachableRoles;
 }
Example #11
0
    /**
     * This query works well with small offset, but if want to use it with large offsets please refer to the link on how to implement
     * http://www.scribd.com/doc/14683263/Efficient-Pagination-Using-MySQL
     * This will only check permissions on the first entity added in the from clause, it will not check permissions
     * By default the number of rows returned are 10 starting from 0
     *
     * @param Query $query
     *
     * @return string
     */
    private function getPermittedAclIdsSQLForUser(Query $query)
    {
        $aclConnection = $this->em->getConnection();
        $databasePrefix = is_file($aclConnection->getDatabase()) ? '' : $aclConnection->getDatabase() . '.';
        $mask = $query->getHint('acl.mask');
        $rootEntity = '"' . str_replace('\\', '\\\\', $query->getHint('acl.root.entity')) . '"';
        /* @var $token TokenInterface */
        $token = $this->securityContext->getToken();
        $userRoles = array();
        $user = null;
        if (!is_null($token)) {
            $user = $token->getUser();
            $userRoles = $this->roleHierarchy->getReachableRoles($token->getRoles());
        }
        // Security context does not provide anonymous role automatically.
        $uR = array('"IS_AUTHENTICATED_ANONYMOUSLY"');
        /* @var $role RoleInterface */
        foreach ($userRoles as $role) {
            // The reason we ignore this is because by default FOSUserBundle adds ROLE_USER for every user
            if ($role->getRole() !== 'ROLE_USER') {
                $uR[] = '"' . $role->getRole() . '"';
            }
        }
        $uR = array_unique($uR);
        $inString = implode(' OR s.identifier = ', $uR);
        if (is_object($user)) {
            $inString .= ' OR s.identifier = "' . str_replace('\\', '\\\\', get_class($user)) . '-' . $user->getUserName() . '"';
        }
        $selectQuery = <<<SELECTQUERY
SELECT DISTINCT o.object_identifier as id FROM {$databasePrefix}acl_object_identities as o
INNER JOIN {$databasePrefix}acl_classes c ON c.id = o.class_id
LEFT JOIN {$databasePrefix}acl_entries e ON (
    e.class_id = o.class_id AND (e.object_identity_id = o.id
    OR {$aclConnection->getDatabasePlatform()->getIsNullExpression('e.object_identity_id')})
)
LEFT JOIN {$databasePrefix}acl_security_identities s ON (
s.id = e.security_identity_id
)
WHERE c.class_type = {$rootEntity}
AND (s.identifier = {$inString})
AND e.mask & {$mask} > 0
SELECTQUERY;
        return $selectQuery;
    }
 /**
  * @covers Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper::getAllowedEntityIds
  * @covers Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper::getPermittedAclIdsSQLForUser
  */
 public function testGetAllowedEntityIds()
 {
     $roles = array(new Role('ROLE_KING'));
     $allRoles = array($roles[0], new Role('ROLE_SUBJECT'));
     $this->token->expects($this->once())->method('getRoles')->will($this->returnValue($roles));
     $this->rh->expects($this->once())->method('getReachableRoles')->with($roles)->will($this->returnValue($allRoles));
     $user = $this->getMockBuilder('FOS\\UserBundle\\Model\\UserInterface')->getMock();
     $user->expects($this->any())->method('getUsername')->will($this->returnValue('MyUser'));
     $this->token->expects($this->any())->method('getUser')->will($this->returnValue($user));
     $hydrator = $this->getMockBuilder('Doctrine\\ORM\\Internal\\Hydration\\ScalarHydrator')->disableOriginalConstructor()->getMock();
     $rows = array(array('id' => 1), array('id' => 9));
     $hydrator->expects($this->once())->method('hydrateAll')->will($this->returnValue($rows));
     $this->em->expects($this->any())->method('newHydrator')->will($this->returnValue($hydrator));
     /* @var $query NativeQuery */
     $query = new NativeQuery($this->em);
     $this->em->expects($this->once())->method('createNativeQuery')->will($this->returnValue($query));
     $permissionDef = new PermissionDefinition(array('view'), 'Kunstmaan\\NodeBundle\\Entity\\Node', 'n');
     /* @var $result array */
     $result = $this->object->getAllowedEntityIds($permissionDef);
     $this->assertEquals(array(1, 9), $result);
 }