Permalink
Browse files

Added ACL support inside the fixtures

  • Loading branch information...
jaytaph committed Jul 2, 2012
1 parent fcfc6e6 commit 3a382bbca0f279a59ac2f4453168317880a0e293
View
@@ -0,0 +1,6 @@
+#!/bin/sh
+php app/console doctrine:database:drop --force
+php app/console doctrine:database:create
+php app/console doctrine:schema:create
+php app/console init:acl
+php app/console doctrine:fixtures:load
@@ -72,21 +72,7 @@ public function createAction()
$em->persist($entity);
$em->flush();
- // create the ACL
- $aclProvider = $this->get('security.acl.provider');
- $objectIdentity = ObjectIdentity::fromDomainObject($entity);
- $acl = $aclProvider->createAcl($objectIdentity);
-
- // retrieving the security identity of the currently logged-in user
- $securityContext = $this->get('security.context');
- $user = $securityContext->getToken()->getUser();
- $securityIdentity = UserSecurityIdentity::fromAccount($user);
- $roleSecurityIdentity = new RoleSecurityIdentity('ROLE_ADMIN');
-
- // grant owner access
- $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OPERATOR);
- $acl->insertObjectAce($roleSecurityIdentity, MaskBuilder::MASK_MASTER);
- $aclProvider->updateAcl($acl);
+ $this->assignAcl($entity);
$this->get('session')->setFlash('success',"A new machine has been created!");
return $this->redirect($this->generateUrl('machine'));
@@ -209,4 +195,22 @@ private function createDeleteForm($id)
->getForm()
;
}
+
+ private function assignAcl($entity) {
+ // create the ACL
+ $aclProvider = $this->get('security.acl.provider');
+ $objectIdentity = ObjectIdentity::fromDomainObject($entity);
+ $acl = $aclProvider->createAcl($objectIdentity);
+
+ // retrieving the security identity of the currently logged-in user
+ $securityContext = $this->get('security.context');
+ $user = $securityContext->getToken()->getUser();
+ $securityIdentity = UserSecurityIdentity::fromAccount($user);
+ $roleSecurityIdentity = new RoleSecurityIdentity('ROLE_ADMIN');
+
+ // grant owner access
+ $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OPERATOR);
+ $acl->insertObjectAce($roleSecurityIdentity, MaskBuilder::MASK_MASTER);
+ $aclProvider->updateAcl($acl);
+ }
}
@@ -7,8 +7,23 @@
use Doctrine\Common\DataFixtures\AbstractFixture;
use boxconfig\BoxBundle\Entity\Environment;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
-class EnvironmentFixtureLoader extends AbstractFixture implements OrderedFixtureInterface {
+use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+use Symfony\Component\Security\Acl\Permission\MaskBuilder;
+
+class EnvironmentFixtureLoader extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface {
+
+ private $container;
+
+ public function setContainer(ContainerInterface $container = null)
+ {
+ $this->container = $container;
+ }
public function load(ObjectManager $manager)
{
@@ -31,11 +46,37 @@ public function load(ObjectManager $manager)
$manager->persist($env3);
$manager->flush();
+
+ // Make sure you add ACL's AFTER you have flushed. Otherwise getID() is empty and will fail.
+ $this->assignAcl($env1, $env1->getMachine()->getUser());
+ $this->assignAcl($env2, $env2->getMachine()->getUser());
+ $this->assignAcl($env3, $env3->getMachine()->getUser());
}
public function getOrder()
{
return 60;
}
+ private function assignAcl($entity, $user) {
+ $em = $this->container->get('doctrine')->getEntityManager();
+ $user = $em->getRepository("BoxConfigAccountBundle:User")->findOneById($user->getId());
+
+ // create the ACL
+ $aclProvider = $this->container->get('security.acl.provider');
+ $objectIdentity = ObjectIdentity::fromDomainObject($entity);
+ $acl = $aclProvider->createAcl($objectIdentity);
+
+ // Add operator (owner)
+
+ // Make sure you add the actual class, otherwise it will use the proxy class!
+ $securityIdentity = new UserSecurityIdentity($user, 'BoxConfig\AccountBundle\Entity\User');
+ $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OPERATOR);
+
+ // Add role admin
+ $roleSecurityIdentity = new RoleSecurityIdentity('ROLE_ADMIN');
+ $acl->insertObjectAce($roleSecurityIdentity, MaskBuilder::MASK_MASTER);
+ $aclProvider->updateAcl($acl);
+ }
+
}
@@ -5,10 +5,30 @@
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\DataFixtures\AbstractFixture;
-use boxconfig\BoxBundle\Entity\Machine;
+use Boxconfig\BoxBundle\Entity\Machine;
+use BoxConfig\AccountBundle\Entity\User;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
-class MachineFixtureLoader extends AbstractFixture implements OrderedFixtureInterface {
+use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
+use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
+use Symfony\Component\Security\Acl\Permission\MaskBuilder;
+
+
+class MachineFixtureLoader extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface {
+
+ /**
+ * @var ContainerInterface
+ */
+ private $container;
+
+ public function setContainer(ContainerInterface $container = null)
+ {
+ $this->container = $container;
+ }
public function load(ObjectManager $manager)
{
@@ -19,7 +39,6 @@ public function load(ObjectManager $manager)
$m1->setActive(true);
$m1->setHardware($this->getReference("hw-1"));
$manager->persist($m1);
- // @TODO: Add software
$m2 = new Machine();
$m2->setName("Vader");
@@ -28,7 +47,6 @@ public function load(ObjectManager $manager)
$m2->setActive(true);
$m2->setHardware($this->getReference("hw-1"));
$manager->persist($m2);
- // @TODO: Add software
$m3 = new Machine();
$m3->setName("Kenobi");
@@ -37,10 +55,14 @@ public function load(ObjectManager $manager)
$m3->setActive(false);
$m3->setHardware($this->getReference("hw-3"));
$manager->persist($m3);
- // @TODO: Add software
$manager->flush();
+ // Make sure you add ACL's AFTER you have flushed. Otherwise getID() is empty and will fail.
+ $this->assignAcl($m1, $m1->getUser());
+ $this->assignAcl($m2, $m2->getUser());
+ $this->assignAcl($m3, $m3->getUser());
+
$this->addReference('m-1', $m1);
$this->addReference('m-2', $m2);
$this->addReference('m-3', $m3);
@@ -51,4 +73,25 @@ public function getOrder()
return 50;
}
+
+ private function assignAcl($entity, User $user) {
+ $em = $this->container->get('doctrine')->getEntityManager();
+ $user = $em->getRepository("BoxConfigAccountBundle:User")->findOneById($user->getId());
+
+ // create the ACL
+ $aclProvider = $this->container->get('security.acl.provider');
+ $objectIdentity = ObjectIdentity::fromDomainObject($entity);
+ $acl = $aclProvider->createAcl($objectIdentity);
+
+ // Add operator (owner)
+ // Make sure you add the actual class, otherwise it will use the proxy class!
+ $securityIdentity = new UserSecurityIdentity($user, 'BoxConfig\AccountBundle\Entity\User');
+ $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OPERATOR);
+
+ // Add role admin
+ $roleSecurityIdentity = new RoleSecurityIdentity('ROLE_ADMIN');
+ $acl->insertObjectAce($roleSecurityIdentity, MaskBuilder::MASK_MASTER);
+ $aclProvider->updateAcl($acl);
+ }
+
}
@@ -1,7 +1,7 @@
parameters:
-# box_config_default.example.class: BoxConfig\DefaultBundle\Example
services:
-# box_config_default.example:
-# class: %box_config_default.example.class%
-# arguments: [@service_id, "plain_value", %parameter%]
+ security.acl.object_identity_retrieval_strategy:
+ class: BoxConfig\DefaultBundle\Security\Acl\Domain\ObjectIdentityRetrievalStrategy
+ public: false
+ arguments: [@doctrine.orm.entity_manager]
@@ -0,0 +1,63 @@
+<?php
+/*
+ * Taken from http://jonathaningram.com.au/2012/01/13/overriding-the-objectidentityretrievalstrategy-to-check-if-a-domain-object-is-a-doctrine-proxy/
+ */
+namespace BoxConfig\DefaultBundle\Security\Acl\Domain;
+
+use Symfony\Component\Security\Acl\Exception\InvalidDomainObjectException;
+use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
+use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
+
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Strategy to be used for retrieving object identities from domain objects
+ * where the domain object may be a Doctrine proxy.
+ */
+class ObjectIdentityRetrievalStrategy implements ObjectIdentityRetrievalStrategyInterface
+{
+ /**
+ * @var \Doctrine\ORM\EntityManager $em
+ */
+ private $em;
+
+ public function __construct(EntityManager $em)
+ {
+ $this->em = $em;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getObjectIdentity($domainObject)
+ {
+ try {
+ if ($domainObject instanceof \Doctrine\ORM\Proxy\Proxy) {
+ return $this->fromDomainObject($domainObject);
+ }
+
+ return ObjectIdentity::fromDomainObject($domainObject);
+ } catch (InvalidDomainObjectException $failed) {
+ return null;
+ }
+ }
+
+ private function fromDomainObject($domainObject)
+ {
+ if (!is_object($domainObject)) {
+ throw new InvalidDomainObjectException('$domainObject must be an object.');
+ }
+
+ try {
+ if ($domainObject instanceof DomainObjectInterface) {
+ return new ObjectIdentity($domainObject->getObjectIdentifier(), $this->em->getClassMetadata(get_class($domainObject))->getName());
+ } elseif (method_exists($domainObject, 'getId')) {
+ return new ObjectIdentity($domainObject->getId(), $this->em->getClassMetadata(get_class($domainObject))->getName());
+ }
+ } catch (\InvalidArgumentException $invalid) {
+ throw new InvalidDomainObjectException($invalid->getMessage(), 0, $invalid);
+ }
+
+ throw new InvalidDomainObjectException('$domainObject must either implement the DomainObjectInterface, or have a method named "getId".');
+ }
+}

0 comments on commit 3a382bb

Please sign in to comment.