/**
  * Get the parameters needed in the template. This is common for the default link chooser and the cke link chooser.
  *
  * @return array
  */
 private function getTemplateParameters()
 {
     /* @var EntityManager $em */
     $em = $this->getDoctrine()->getManager();
     $locale = $this->getRequest()->getLocale();
     $qb = $em->getConnection()->createQueryBuilder();
     $qb->select('n.id, n.parent_id, t.weight, t.title, t.online, t.url, n.ref_entity_name')->from('kuma_nodes', 'n')->leftJoin('n', 'kuma_node_translations', 't', "(t.node_id = n.id AND t.lang = ?)")->where('n.deleted = 0')->andWhere('t.online IN (0, 1)')->addOrderBy('parent_id', 'ASC')->addOrderBy('weight', 'ASC')->addOrderBy('title', 'ASC');
     $permissionDef = new PermissionDefinition(array(PermissionMap::PERMISSION_VIEW));
     $permissionDef->setEntity('Kunstmaan\\NodeBundle\\Entity\\Node');
     $permissionDef->setAlias('n');
     $qb = $this->get('kunstmaan_admin.acl.native.helper')->apply($qb, $permissionDef);
     $stmt = $em->getConnection()->prepare($qb->getSQL());
     $stmt->bindValue(1, $locale);
     $stmt->execute();
     $result = $stmt->fetchAll();
     $simpleTreeView = new SimpleTreeView();
     foreach ($result as $data) {
         if ($this->isStructureNode($data['ref_entity_name'])) {
             $data['online'] = true;
         }
         $simpleTreeView->addItem($data['parent_id'], $data);
     }
     // When the media bundle is available, we show a link in the header to the media chooser
     $allBundles = $this->container->getParameter('kernel.bundles');
     if (array_key_exists('KunstmaanMediaBundle', $allBundles)) {
         $params = array('linkChooser' => 1);
         $cKEditorFuncNum = $this->getRequest()->get('CKEditorFuncNum');
         if (!empty($cKEditorFuncNum)) {
             $params['CKEditorFuncNum'] = $cKEditorFuncNum;
         }
         $mediaChooserLink = $this->generateUrl('KunstmaanMediaBundle_chooser', $params);
     }
     return array('tree' => $simpleTreeView, 'mediaChooserLink' => $mediaChooserLink);
 }
    /**
     * 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;
    }
Exemplo n.º 3
0
 /**
  * Returns valid IDs for a specific entity with ACL restrictions for current user applied
  *
  * @param PermissionDefinition $permissionDef
  *
  * @throws InvalidArgumentException
  *
  * @return array
  */
 public function getAllowedEntityIds(PermissionDefinition $permissionDef)
 {
     $rootEntity = $permissionDef->getEntity();
     if (empty($rootEntity)) {
         throw new InvalidArgumentException("You have to provide an entity class name!");
     }
     $builder = new MaskBuilder();
     foreach ($permissionDef->getPermissions() as $permission) {
         $mask = constant(get_class($builder) . '::MASK_' . strtoupper($permission));
         $builder->add($mask);
     }
     $query = new Query($this->em);
     $query->setHint('acl.mask', $builder->get());
     $query->setHint('acl.root.entity', $rootEntity);
     $sql = $this->getPermittedAclIdsSQLForUser($query);
     $rsm = new ResultSetMapping();
     $rsm->addScalarResult('id', 'id');
     $nativeQuery = $this->em->createNativeQuery($sql, $rsm);
     $transform = function ($item) {
         return $item['id'];
     };
     $result = array_map($transform, $nativeQuery->getScalarResult());
     return $result;
 }
    /**
     * Get all the information needed to build a menu tree with one query.
     * We only fetch the fields we need, instead of fetching full objects to limit the memory usage.
     *
     * @param string          $lang                 The locale
     * @param string          $permission           The permission (read, write, ...)
     * @param AclNativeHelper $aclNativeHelper      The acl helper
     * @param bool            $includeHiddenFromNav Include nodes hidden from navigation or not
     *
     * @return array
     */
    public function getAllMenuNodes($lang, $permission, AclNativeHelper $aclNativeHelper, $includeHiddenFromNav = false)
    {
        $connection = $this->_em->getConnection();
        $qb = $connection->createQueryBuilder();
        $databasePlatformName = $connection->getDatabasePlatform()->getName();
        $createIfStatement = function ($expression, $trueValue, $falseValue) use($databasePlatformName) {
            switch ($databasePlatformName) {
                case 'sqlite':
                    $statement = 'CASE WHEN %s THEN %s ELSE %s END';
                    break;
                default:
                    $statement = 'IF(%s, %s, %s)';
            }
            return sprintf($statement, $expression, $trueValue, $falseValue);
        };
        $sql = <<<SQL
n.id, n.parent_id AS parent, t.url,
{$createIfStatement('t.weight IS NULL', 'v.weight', 't.weight')} AS weight,
{$createIfStatement('t.title IS NULL', 'v.title', 't.title')} AS title,
{$createIfStatement('t.online IS NULL', '0', 't.online')} AS online,
n.hidden_from_nav AS hidden,
n.ref_entity_name AS ref_entity_name
SQL;
        $qb->select($sql)->from('kuma_nodes', 'n')->leftJoin('n', 'kuma_node_translations', 't', '(t.node_id = n.id AND t.lang = ?)')->leftJoin('n', '(SELECT lang, title, weight, node_id, url FROM kuma_node_translations GROUP BY node_id ORDER BY id ASC)', 'v', '(v.node_id = n.id AND v.lang <> ?)')->where('n.deleted = 0')->addGroupBy('n.id')->addOrderBy('t.weight', 'ASC')->addOrderBy('t.title', 'ASC');
        if (!$includeHiddenFromNav) {
            $qb->andWhere('n.hidden_from_nav <> 0');
        }
        $permissionDef = new PermissionDefinition(array($permission));
        $permissionDef->setEntity('Kunstmaan\\NodeBundle\\Entity\\Node');
        $permissionDef->setAlias('n');
        $qb = $aclNativeHelper->apply($qb, $permissionDef);
        $stmt = $this->_em->getConnection()->prepare($qb->getSQL());
        $stmt->bindValue(1, $lang);
        $stmt->bindValue(2, $lang);
        $stmt->execute();
        return $stmt->fetchAll();
    }
 /**
  * @covers Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionDefinition::setPermissions
  * @expectedException \InvalidArgumentException
  */
 public function testSetPermissionsWithInvalidData()
 {
     $this->object->setPermissions(array());
 }