Explorar el Código

Merge remote-tracking branch 'beeldspraak/acl'

Thomas Rabaix hace 13 años
padre
commit
aaf9c512fb

+ 1 - 0
DependencyInjection/SonataDoctrineORMAdminExtension.php

@@ -43,6 +43,7 @@ class SonataDoctrineORMAdminExtension extends Extension
         $loader->load('doctrine_orm.xml');
         $loader->load('doctrine_orm_filter_types.xml');
         $loader->load('audit.xml');
+        $loader->load('security.xml');
 
         $configuration = new Configuration();
         $processor = new Processor();

+ 16 - 0
Resources/config/security.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<container xmlns="http://symfony.com/schema/dic/services"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
+
+    <parameters>
+        <parameter key="sonata.admin.manipulator.acl.object.orm.class">Sonata\DoctrineORMAdminBundle\Util\ObjectAclManipulator</parameter>
+    </parameters>
+
+    <services>
+        <service id="sonata.admin.manipulator.acl.object.orm" class="%sonata.admin.manipulator.acl.object.orm.class%" >
+            <argument type="service" id="sonata.admin.security.handler" />
+        </service>
+    </services>
+</container>

+ 85 - 0
Util/ObjectAclManipulator.php

@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of the Sonata package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\DoctrineORMAdminBundle\Util;
+
+use Sonata\AdminBundle\Exception\ModelManagerException;
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Console\Output\OutputInterface;
+
+use Sonata\AdminBundle\Security\Handler\AclSecurityHandlerInterface;
+use Sonata\AdminBundle\Admin\AdminInterface;
+use Sonata\AdminBundle\Util\ObjectAclManipulator as BaseObjectAclManipulator;
+
+class ObjectAclManipulator extends BaseObjectAclManipulator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function batchConfigureAcls(OutputInterface $output, AdminInterface $admin, UserSecurityIdentity $securityIdentity = null)
+    {
+        $securityHandler = $admin->getSecurityHandler();
+        if (!$securityHandler instanceof AclSecurityHandlerInterface) {
+            $output->writeln('Admin class is not configured to use ACL : <info>ignoring</info>');
+            return;
+        }
+
+        $output->writeln(sprintf(' > generate ACLs for %s', $admin->getCode()));
+        $objectOwnersMsg = is_null($securityIdentity) ? '' : ' and set the object owner';
+
+        $em = $admin->getModelManager()->getEntityManager();
+        $qb = $em->createQueryBuilder();
+        $qb->select('o')->from($admin->getClass(), 'o');
+
+        $count = 0;
+        $countUpdated = 0;
+        $countAdded = 0;
+
+        try {
+            $batchSize = 20;
+            $batchSizeOutput = 200;
+            $i = 0;
+            $oids = array();
+
+            foreach ($qb->getQuery()->iterate() as $row) {
+                $oids[] = ObjectIdentity::fromDomainObject($row[0]);
+
+                // detach from Doctrine, so that it can be Garbage-Collected immediately
+                $em->detach($row[0]);
+
+                if ((++$i % $batchSize) == 0) {
+
+                    list($batchAdded, $batchUpdated) = $this->configureAcls($admin, $oids, $securityIdentity);
+                    $countAdded += $batchAdded;
+                    $countUpdated += $batchUpdated;
+                    $oids = array();
+                }
+
+                if ((++$i % $batchSizeOutput) == 0) {
+                    $output->writeln(sprintf('   - generated class ACEs%s for %s objects (added %s, updated %s)', $objectOwnersMsg, $count, $countAdded, $countUpdated));
+                }
+
+                $count++;
+            }
+
+            if (count($oids) > 0) {
+                list($batchAdded, $batchUpdated) = $this->configureAcls($admin, $oids, $securityIdentity);
+                $countAdded += $batchAdded;
+                $countUpdated += $batchUpdated;
+            }
+        } catch ( \PDOException $e ) {
+            throw new ModelManagerException('', 0, $e);
+        }
+
+        $output->writeln(sprintf('   - [TOTAL] generated class ACEs%s for %s objects (added %s, updated %s)', $objectOwnersMsg, $count, $countAdded, $countUpdated));
+    }
+}