123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Component\Security\Acl\Domain;
- use Doctrine\Common\Cache\Cache;
- use Doctrine\Common\Cache\CacheProvider;
- use Symfony\Component\Security\Acl\Model\AclCacheInterface;
- use Symfony\Component\Security\Acl\Model\AclInterface;
- use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
- use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
- /**
- * This class is a wrapper around the actual cache implementation.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
- class DoctrineAclCache implements AclCacheInterface
- {
- const PREFIX = 'sf2_acl_';
- private $cache;
- private $prefix;
- private $permissionGrantingStrategy;
- /**
- * Constructor.
- *
- * @param Cache $cache
- * @param PermissionGrantingStrategyInterface $permissionGrantingStrategy
- * @param string $prefix
- *
- * @throws \InvalidArgumentException
- */
- public function __construct(Cache $cache, PermissionGrantingStrategyInterface $permissionGrantingStrategy, $prefix = self::PREFIX)
- {
- if (0 === strlen($prefix)) {
- throw new \InvalidArgumentException('$prefix cannot be empty.');
- }
- $this->cache = $cache;
- $this->permissionGrantingStrategy = $permissionGrantingStrategy;
- $this->prefix = $prefix;
- }
- /**
- * {@inheritdoc}
- */
- public function clearCache()
- {
- if ($this->cache instanceof CacheProvider) {
- $this->cache->deleteAll();
- }
- }
- /**
- * {@inheritdoc}
- */
- public function evictFromCacheById($aclId)
- {
- $lookupKey = $this->getAliasKeyForIdentity($aclId);
- if (!$this->cache->contains($lookupKey)) {
- return;
- }
- $key = $this->cache->fetch($lookupKey);
- if ($this->cache->contains($key)) {
- $this->cache->delete($key);
- }
- $this->cache->delete($lookupKey);
- }
- /**
- * {@inheritdoc}
- */
- public function evictFromCacheByIdentity(ObjectIdentityInterface $oid)
- {
- $key = $this->getDataKeyByIdentity($oid);
- if (!$this->cache->contains($key)) {
- return;
- }
- $this->cache->delete($key);
- }
- /**
- * {@inheritdoc}
- */
- public function getFromCacheById($aclId)
- {
- $lookupKey = $this->getAliasKeyForIdentity($aclId);
- if (!$this->cache->contains($lookupKey)) {
- return;
- }
- $key = $this->cache->fetch($lookupKey);
- if (!$this->cache->contains($key)) {
- $this->cache->delete($lookupKey);
- return;
- }
- return $this->unserializeAcl($this->cache->fetch($key));
- }
- /**
- * {@inheritdoc}
- */
- public function getFromCacheByIdentity(ObjectIdentityInterface $oid)
- {
- $key = $this->getDataKeyByIdentity($oid);
- if (!$this->cache->contains($key)) {
- return;
- }
- return $this->unserializeAcl($this->cache->fetch($key));
- }
- /**
- * {@inheritdoc}
- */
- public function putInCache(AclInterface $acl)
- {
- if (null === $acl->getId()) {
- throw new \InvalidArgumentException('Transient ACLs cannot be cached.');
- }
- if (null !== $parentAcl = $acl->getParentAcl()) {
- $this->putInCache($parentAcl);
- }
- $key = $this->getDataKeyByIdentity($acl->getObjectIdentity());
- $this->cache->save($key, serialize($acl));
- $this->cache->save($this->getAliasKeyForIdentity($acl->getId()), $key);
- }
- /**
- * Unserializes the ACL.
- *
- * @param string $serialized
- *
- * @return AclInterface
- */
- private function unserializeAcl($serialized)
- {
- $acl = unserialize($serialized);
- if (null !== $parentId = $acl->getParentAcl()) {
- $parentAcl = $this->getFromCacheById($parentId);
- if (null === $parentAcl) {
- return;
- }
- $acl->setParentAcl($parentAcl);
- }
- $reflectionProperty = new \ReflectionProperty($acl, 'permissionGrantingStrategy');
- $reflectionProperty->setAccessible(true);
- $reflectionProperty->setValue($acl, $this->permissionGrantingStrategy);
- $reflectionProperty->setAccessible(false);
- $aceAclProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'acl');
- $aceAclProperty->setAccessible(true);
- foreach ($acl->getObjectAces() as $ace) {
- $aceAclProperty->setValue($ace, $acl);
- }
- foreach ($acl->getClassAces() as $ace) {
- $aceAclProperty->setValue($ace, $acl);
- }
- $aceClassFieldProperty = new \ReflectionProperty($acl, 'classFieldAces');
- $aceClassFieldProperty->setAccessible(true);
- foreach ($aceClassFieldProperty->getValue($acl) as $aces) {
- foreach ($aces as $ace) {
- $aceAclProperty->setValue($ace, $acl);
- }
- }
- $aceClassFieldProperty->setAccessible(false);
- $aceObjectFieldProperty = new \ReflectionProperty($acl, 'objectFieldAces');
- $aceObjectFieldProperty->setAccessible(true);
- foreach ($aceObjectFieldProperty->getValue($acl) as $aces) {
- foreach ($aces as $ace) {
- $aceAclProperty->setValue($ace, $acl);
- }
- }
- $aceObjectFieldProperty->setAccessible(false);
- $aceAclProperty->setAccessible(false);
- return $acl;
- }
- /**
- * Returns the key for the object identity.
- *
- * @param ObjectIdentityInterface $oid
- *
- * @return string
- */
- private function getDataKeyByIdentity(ObjectIdentityInterface $oid)
- {
- return $this->prefix.md5($oid->getType()).sha1($oid->getType())
- .'_'.md5($oid->getIdentifier()).sha1($oid->getIdentifier());
- }
- /**
- * Returns the alias key for the object identity key.
- *
- * @param string $aclId
- *
- * @return string
- */
- private function getAliasKeyForIdentity($aclId)
- {
- return $this->prefix.$aclId;
- }
- }
|