summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Acl/Dbal/AclProvider.php695
-rw-r--r--Acl/Dbal/MutableAclProvider.php1034
-rw-r--r--Acl/Dbal/Schema.php154
-rw-r--r--Acl/Domain/Acl.php667
-rw-r--r--Acl/Domain/AclCollectionCache.php65
-rw-r--r--Acl/Domain/AuditLogger.php51
-rw-r--r--Acl/Domain/DoctrineAclCache.php229
-rw-r--r--Acl/Domain/Entry.php208
-rw-r--r--Acl/Domain/FieldEntry.php74
-rw-r--r--Acl/Domain/ObjectIdentity.php114
-rw-r--r--Acl/Domain/ObjectIdentityRetrievalStrategy.php35
-rw-r--r--Acl/Domain/PermissionGrantingStrategy.php211
-rw-r--r--Acl/Domain/RoleSecurityIdentity.php73
-rw-r--r--Acl/Domain/SecurityIdentityRetrievalStrategy.php78
-rw-r--r--Acl/Domain/UserSecurityIdentity.php124
-rw-r--r--Acl/Exception/AclAlreadyExistsException.php22
-rw-r--r--Acl/Exception/AclNotFoundException.php22
-rw-r--r--Acl/Exception/ConcurrentModificationException.php22
-rw-r--r--Acl/Exception/Exception.php21
-rw-r--r--Acl/Exception/InvalidDomainObjectException.php22
-rw-r--r--Acl/Exception/NoAceFoundException.php26
-rw-r--r--Acl/Exception/NotAllAclsFoundException.php46
-rw-r--r--Acl/Exception/SidNotLoadedException.php22
-rw-r--r--Acl/Model/AclCacheInterface.php66
-rw-r--r--Acl/Model/AclInterface.php114
-rw-r--r--Acl/Model/AclProviderInterface.php56
-rw-r--r--Acl/Model/AuditLoggerInterface.php29
-rw-r--r--Acl/Model/AuditableAclInterface.php58
-rw-r--r--Acl/Model/AuditableEntryInterface.php34
-rw-r--r--Acl/Model/DomainObjectInterface.php29
-rw-r--r--Acl/Model/EntryInterface.php65
-rw-r--r--Acl/Model/FieldEntryInterface.php27
-rw-r--r--Acl/Model/MutableAclInterface.php158
-rw-r--r--Acl/Model/MutableAclProviderInterface.php54
-rw-r--r--Acl/Model/ObjectIdentityInterface.php50
-rw-r--r--Acl/Model/ObjectIdentityRetrievalStrategyInterface.php29
-rw-r--r--Acl/Model/PermissionGrantingStrategyInterface.php45
-rw-r--r--Acl/Model/SecurityIdentityInterface.php30
-rw-r--r--Acl/Model/SecurityIdentityRetrievalStrategyInterface.php35
-rw-r--r--Acl/Permission/AbstractMaskBuilder.php85
-rw-r--r--Acl/Permission/BasicPermissionMap.php116
-rw-r--r--Acl/Permission/MaskBuilder.php151
-rw-r--r--Acl/Permission/MaskBuilderInterface.php76
-rw-r--r--Acl/Permission/MaskBuilderRetrievalInterface.php25
-rw-r--r--Acl/Permission/PermissionMapInterface.php42
-rw-r--r--Acl/Resources/bin/generateSql.php51
-rw-r--r--Acl/Resources/schema/db2.sql43
-rw-r--r--Acl/Resources/schema/drizzle.sql21
-rw-r--r--Acl/Resources/schema/mssql.sql43
-rw-r--r--Acl/Resources/schema/mysql.sql21
-rw-r--r--Acl/Resources/schema/oracle.sql175
-rw-r--r--Acl/Resources/schema/postgresql.sql43
-rw-r--r--Acl/Resources/schema/sqlanywhere.sql43
-rw-r--r--Acl/Resources/schema/sqlite.sql31
-rw-r--r--Acl/Tests/Dbal/AclProviderBenchmarkTest.php267
-rw-r--r--Acl/Tests/Dbal/AclProviderTest.php280
-rw-r--r--Acl/Tests/Dbal/MutableAclProviderTest.php572
-rw-r--r--Acl/Tests/Domain/AclTest.php513
-rw-r--r--Acl/Tests/Domain/AuditLoggerTest.php83
-rw-r--r--Acl/Tests/Domain/DoctrineAclCacheTest.php101
-rw-r--r--Acl/Tests/Domain/EntryTest.php119
-rw-r--r--Acl/Tests/Domain/FieldEntryTest.php74
-rw-r--r--Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php41
-rw-r--r--Acl/Tests/Domain/ObjectIdentityTest.php135
-rw-r--r--Acl/Tests/Domain/PermissionGrantingStrategyTest.php186
-rw-r--r--Acl/Tests/Domain/RoleSecurityIdentityTest.php55
-rw-r--r--Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php196
-rw-r--r--Acl/Tests/Domain/UserSecurityIdentityTest.php73
-rw-r--r--Acl/Tests/Permission/BasicPermissionMapTest.php23
-rw-r--r--Acl/Tests/Permission/MaskBuilderTest.php103
-rw-r--r--Acl/Tests/Voter/AclVoterTest.php432
-rw-r--r--Acl/Voter/AclVoter.php147
-rw-r--r--Acl/Voter/FieldVote.php40
-rw-r--r--CHANGELOG.md20
-rw-r--r--Core/Authentication/Provider/AnonymousAuthenticationProvider.php16
-rw-r--r--Core/Authentication/Provider/LdapBindAuthenticationProvider.php89
-rw-r--r--Core/Authentication/Provider/RememberMeAuthenticationProvider.php16
-rw-r--r--Core/Authentication/SimpleFormAuthenticatorInterface.php2
-rw-r--r--Core/Authentication/SimplePreAuthenticatorInterface.php2
-rw-r--r--Core/Authentication/Token/AnonymousToken.php34
-rw-r--r--Core/Authentication/Token/RememberMeToken.php38
-rw-r--r--Core/Authorization/AccessDecisionManager.php28
-rw-r--r--Core/Authorization/AccessDecisionManagerInterface.php4
-rw-r--r--Core/Authorization/Voter/AbstractVoter.php4
-rw-r--r--Core/Authorization/Voter/ExpressionVoter.php1
-rw-r--r--Core/Authorization/Voter/Voter.php86
-rw-r--r--Core/Authorization/Voter/VoterInterface.php4
-rw-r--r--Core/Encoder/BCryptPasswordEncoder.php6
-rw-r--r--Core/Encoder/BasePasswordEncoder.php4
-rw-r--r--Core/Encoder/Pbkdf2PasswordEncoder.php26
-rw-r--r--Core/Exception/AuthenticationExpiredException.php31
-rw-r--r--Core/Exception/CustomUserMessageAuthenticationException.php79
-rw-r--r--Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php16
-rw-r--r--Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php81
-rw-r--r--Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php10
-rw-r--r--Core/Tests/Authentication/Token/AnonymousTokenTest.php2
-rw-r--r--Core/Tests/Authentication/Token/RememberMeTokenTest.php6
-rw-r--r--Core/Tests/Authorization/AccessDecisionManagerTest.php14
-rw-r--r--Core/Tests/Authorization/Voter/AbstractVoterTest.php24
-rw-r--r--Core/Tests/Authorization/Voter/Fixtures/MyVoter.php27
-rw-r--r--Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php15
-rw-r--r--Core/Tests/Authorization/Voter/VoterTest.php70
-rw-r--r--Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php26
-rw-r--r--Core/Tests/LegacySecurityContextInterfaceTest.php31
-rw-r--r--Core/Tests/LegacySecurityContextTest.php12
-rw-r--r--Core/Tests/User/LdapUserProviderTest.php105
-rw-r--r--Core/Tests/Util/ClassUtilsTest.php3
-rw-r--r--Core/Tests/Util/StringUtilsTest.php2
-rw-r--r--Core/User/LdapUserProvider.php108
-rw-r--r--Core/User/UserCheckerInterface.php11
-rw-r--r--Core/User/UserProviderInterface.php2
-rw-r--r--Core/Util/ClassUtils.php11
-rw-r--r--Core/Util/SecureRandom.php4
-rw-r--r--Core/Util/SecureRandomInterface.php2
-rw-r--r--Core/Util/StringUtils.php39
-rw-r--r--Core/composer.json21
-rw-r--r--Csrf/CsrfTokenManager.php3
-rw-r--r--Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php8
-rw-r--r--Csrf/TokenGenerator/UriSafeTokenGenerator.php26
-rw-r--r--Csrf/composer.json8
-rw-r--r--Guard/.gitignore (renamed from Acl/.gitignore)0
-rw-r--r--Guard/AbstractGuardAuthenticator.php41
-rw-r--r--Guard/Authenticator/AbstractFormLoginAuthenticator.php111
-rw-r--r--Guard/Firewall/GuardAuthenticationListener.php201
-rw-r--r--Guard/GuardAuthenticatorHandler.php139
-rw-r--r--Guard/GuardAuthenticatorInterface.php160
-rw-r--r--Guard/LICENSE (renamed from Acl/LICENSE)0
-rw-r--r--Guard/Provider/GuardAuthenticationProvider.php148
-rw-r--r--Guard/README.md (renamed from Acl/README.md)11
-rw-r--r--Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php212
-rw-r--r--Guard/Tests/Firewall/GuardAuthenticationListenerTest.php256
-rw-r--r--Guard/Tests/GuardAuthenticatorHandlerTest.php141
-rw-r--r--Guard/Tests/Provider/GuardAuthenticationProviderTest.php150
-rw-r--r--Guard/Token/GuardTokenInterface.php27
-rw-r--r--Guard/Token/PostAuthenticationGuardToken.php90
-rw-r--r--Guard/Token/PreAuthenticationGuardToken.php65
-rw-r--r--Guard/composer.json (renamed from Acl/composer.json)18
-rw-r--r--Guard/phpunit.xml.dist (renamed from Acl/phpunit.xml.dist)2
-rw-r--r--Http/Authentication/DefaultAuthenticationFailureHandler.php3
-rw-r--r--Http/Authentication/DefaultAuthenticationSuccessHandler.php3
-rw-r--r--Http/Authentication/SimpleFormAuthenticatorInterface.php21
-rw-r--r--Http/Authentication/SimplePreAuthenticatorInterface.php21
-rw-r--r--Http/EntryPoint/AuthenticationEntryPointInterface.php4
-rw-r--r--Http/EntryPoint/DigestAuthenticationEntryPoint.php22
-rw-r--r--Http/Firewall/AnonymousAuthenticationListener.php8
-rw-r--r--Http/Firewall/DigestAuthenticationListener.php5
-rw-r--r--Http/Firewall/LogoutListener.php17
-rw-r--r--Http/Firewall/SimpleFormAuthenticationListener.php25
-rw-r--r--Http/Firewall/UsernamePasswordFormAuthenticationListener.php25
-rw-r--r--Http/Logout/LogoutUrlGenerator.php2
-rw-r--r--Http/ParameterBagUtils.php96
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php31
-rw-r--r--Http/RememberMe/PersistentTokenBasedRememberMeServices.php22
-rw-r--r--Http/RememberMe/TokenBasedRememberMeServices.php5
-rw-r--r--Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php34
-rw-r--r--Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php14
-rw-r--r--Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php6
-rw-r--r--Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php10
-rw-r--r--Http/Tests/Firewall/DigestAuthenticationListenerTest.php79
-rw-r--r--Http/Tests/Firewall/LogoutListenerTest.php2
-rw-r--r--Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php4
-rw-r--r--Http/Tests/RememberMe/AbstractRememberMeServicesTest.php8
-rw-r--r--Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php5
-rw-r--r--Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php4
-rw-r--r--Http/composer.json17
-rw-r--r--composer.json36
166 files changed, 3110 insertions, 9668 deletions
diff --git a/Acl/Dbal/AclProvider.php b/Acl/Dbal/AclProvider.php
deleted file mode 100644
index 6709023..0000000
--- a/Acl/Dbal/AclProvider.php
+++ /dev/null
@@ -1,695 +0,0 @@
-<?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\Dbal;
-
-use Doctrine\DBAL\Connection;
-use Doctrine\DBAL\Driver\Statement;
-use Symfony\Component\Security\Acl\Model\AclInterface;
-use Symfony\Component\Security\Acl\Domain\Acl;
-use Symfony\Component\Security\Acl\Domain\Entry;
-use Symfony\Component\Security\Acl\Domain\FieldEntry;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
-use Symfony\Component\Security\Acl\Exception\NotAllAclsFoundException;
-use Symfony\Component\Security\Acl\Model\AclCacheInterface;
-use Symfony\Component\Security\Acl\Model\AclProviderInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
-use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
-
-/**
- * An ACL provider implementation.
- *
- * This provider assumes that all ACLs share the same PermissionGrantingStrategy.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class AclProvider implements AclProviderInterface
-{
- const MAX_BATCH_SIZE = 30;
-
- /**
- * @var AclCacheInterface|null
- */
- protected $cache;
-
- /**
- * @var Connection
- */
- protected $connection;
- protected $loadedAces = array();
- protected $loadedAcls = array();
- protected $options;
-
- /**
- * @var PermissionGrantingStrategyInterface
- */
- private $permissionGrantingStrategy;
-
- /**
- * Constructor.
- *
- * @param Connection $connection
- * @param PermissionGrantingStrategyInterface $permissionGrantingStrategy
- * @param array $options
- * @param AclCacheInterface $cache
- */
- public function __construct(Connection $connection, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $options, AclCacheInterface $cache = null)
- {
- $this->cache = $cache;
- $this->connection = $connection;
- $this->options = $options;
- $this->permissionGrantingStrategy = $permissionGrantingStrategy;
- }
-
- /**
- * {@inheritdoc}
- */
- public function findChildren(ObjectIdentityInterface $parentOid, $directChildrenOnly = false)
- {
- $sql = $this->getFindChildrenSql($parentOid, $directChildrenOnly);
-
- $children = array();
- foreach ($this->connection->executeQuery($sql)->fetchAll() as $data) {
- $children[] = new ObjectIdentity($data['object_identifier'], $data['class_type']);
- }
-
- return $children;
- }
-
- /**
- * {@inheritdoc}
- */
- public function findAcl(ObjectIdentityInterface $oid, array $sids = array())
- {
- return $this->findAcls(array($oid), $sids)->offsetGet($oid);
- }
-
- /**
- * {@inheritdoc}
- */
- public function findAcls(array $oids, array $sids = array())
- {
- $result = new \SplObjectStorage();
- $currentBatch = array();
- $oidLookup = array();
-
- for ($i = 0, $c = count($oids); $i < $c; ++$i) {
- $oid = $oids[$i];
- $oidLookupKey = $oid->getIdentifier().$oid->getType();
- $oidLookup[$oidLookupKey] = $oid;
- $aclFound = false;
-
- // check if result already contains an ACL
- if ($result->contains($oid)) {
- $aclFound = true;
- }
-
- // check if this ACL has already been hydrated
- if (!$aclFound && isset($this->loadedAcls[$oid->getType()][$oid->getIdentifier()])) {
- $acl = $this->loadedAcls[$oid->getType()][$oid->getIdentifier()];
-
- if (!$acl->isSidLoaded($sids)) {
- // FIXME: we need to load ACEs for the missing SIDs. This is never
- // reached by the default implementation, since we do not
- // filter by SID
- throw new \RuntimeException('This is not supported by the default implementation.');
- } else {
- $result->attach($oid, $acl);
- $aclFound = true;
- }
- }
-
- // check if we can locate the ACL in the cache
- if (!$aclFound && null !== $this->cache) {
- $acl = $this->cache->getFromCacheByIdentity($oid);
-
- if (null !== $acl) {
- if ($acl->isSidLoaded($sids)) {
- // check if any of the parents has been loaded since we need to
- // ensure that there is only ever one ACL per object identity
- $parentAcl = $acl->getParentAcl();
- while (null !== $parentAcl) {
- $parentOid = $parentAcl->getObjectIdentity();
-
- if (isset($this->loadedAcls[$parentOid->getType()][$parentOid->getIdentifier()])) {
- $acl->setParentAcl($this->loadedAcls[$parentOid->getType()][$parentOid->getIdentifier()]);
- break;
- } else {
- $this->loadedAcls[$parentOid->getType()][$parentOid->getIdentifier()] = $parentAcl;
- $this->updateAceIdentityMap($parentAcl);
- }
-
- $parentAcl = $parentAcl->getParentAcl();
- }
-
- $this->loadedAcls[$oid->getType()][$oid->getIdentifier()] = $acl;
- $this->updateAceIdentityMap($acl);
- $result->attach($oid, $acl);
- $aclFound = true;
- } else {
- $this->cache->evictFromCacheByIdentity($oid);
-
- foreach ($this->findChildren($oid) as $childOid) {
- $this->cache->evictFromCacheByIdentity($childOid);
- }
- }
- }
- }
-
- // looks like we have to load the ACL from the database
- if (!$aclFound) {
- $currentBatch[] = $oid;
- }
-
- // Is it time to load the current batch?
- $currentBatchesCount = count($currentBatch);
- if ($currentBatchesCount > 0 && (self::MAX_BATCH_SIZE === $currentBatchesCount || ($i + 1) === $c)) {
- try {
- $loadedBatch = $this->lookupObjectIdentities($currentBatch, $sids, $oidLookup);
- } catch (AclNotFoundException $e) {
- if ($result->count()) {
- $partialResultException = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
- $partialResultException->setPartialResult($result);
- throw $partialResultException;
- } else {
- throw $e;
- }
- }
- foreach ($loadedBatch as $loadedOid) {
- $loadedAcl = $loadedBatch->offsetGet($loadedOid);
-
- if (null !== $this->cache) {
- $this->cache->putInCache($loadedAcl);
- }
-
- if (isset($oidLookup[$loadedOid->getIdentifier().$loadedOid->getType()])) {
- $result->attach($loadedOid, $loadedAcl);
- }
- }
-
- $currentBatch = array();
- }
- }
-
- // check that we got ACLs for all the identities
- foreach ($oids as $oid) {
- if (!$result->contains($oid)) {
- if (1 === count($oids)) {
- $objectName = method_exists($oid, '__toString') ? $oid : get_class($oid);
- throw new AclNotFoundException(sprintf('No ACL found for %s.', $objectName));
- }
-
- $partialResultException = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
- $partialResultException->setPartialResult($result);
-
- throw $partialResultException;
- }
- }
-
- return $result;
- }
-
- /**
- * Constructs the query used for looking up object identities and associated
- * ACEs, and security identities.
- *
- * @param array $ancestorIds
- *
- * @return string
- */
- protected function getLookupSql(array $ancestorIds)
- {
- // FIXME: add support for filtering by sids (right now we select all sids)
-
- $sql = <<<SELECTCLAUSE
- SELECT
- o.id as acl_id,
- o.object_identifier,
- o.parent_object_identity_id,
- o.entries_inheriting,
- c.class_type,
- e.id as ace_id,
- e.object_identity_id,
- e.field_name,
- e.ace_order,
- e.mask,
- e.granting,
- e.granting_strategy,
- e.audit_success,
- e.audit_failure,
- s.username,
- s.identifier as security_identifier
- FROM
- {$this->options['oid_table_name']} o
- INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
- LEFT JOIN {$this->options['entry_table_name']} e ON (
- e.class_id = o.class_id AND (e.object_identity_id = o.id OR {$this->connection->getDatabasePlatform()->getIsNullExpression('e.object_identity_id')})
- )
- LEFT JOIN {$this->options['sid_table_name']} s ON (
- s.id = e.security_identity_id
- )
-
- WHERE (o.id =
-SELECTCLAUSE;
-
- $sql .= implode(' OR o.id = ', $ancestorIds).')';
-
- return $sql;
- }
-
- protected function getAncestorLookupSql(array $batch)
- {
- $sql = <<<SELECTCLAUSE
- SELECT a.ancestor_id
- FROM
- {$this->options['oid_table_name']} o
- INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
- INNER JOIN {$this->options['oid_ancestors_table_name']} a ON a.object_identity_id = o.id
- WHERE (
-SELECTCLAUSE;
-
- $types = array();
- $count = count($batch);
- for ($i = 0; $i < $count; ++$i) {
- if (!isset($types[$batch[$i]->getType()])) {
- $types[$batch[$i]->getType()] = true;
-
- // if there is more than one type we can safely break out of the
- // loop, because it is the differentiator factor on whether to
- // query for only one or more class types
- if (count($types) > 1) {
- break;
- }
- }
- }
-
- if (1 === count($types)) {
- $ids = array();
- for ($i = 0; $i < $count; ++$i) {
- $identifier = (string) $batch[$i]->getIdentifier();
- $ids[] = $this->connection->quote($identifier);
- }
-
- $sql .= sprintf(
- '(o.object_identifier IN (%s) AND c.class_type = %s)',
- implode(',', $ids),
- $this->connection->quote($batch[0]->getType())
- );
- } else {
- $where = '(o.object_identifier = %s AND c.class_type = %s)';
- for ($i = 0; $i < $count; ++$i) {
- $sql .= sprintf(
- $where,
- $this->connection->quote($batch[$i]->getIdentifier()),
- $this->connection->quote($batch[$i]->getType())
- );
-
- if ($i + 1 < $count) {
- $sql .= ' OR ';
- }
- }
- }
-
- $sql .= ')';
-
- return $sql;
- }
-
- /**
- * Constructs the SQL for retrieving child object identities for the given
- * object identities.
- *
- * @param ObjectIdentityInterface $oid
- * @param bool $directChildrenOnly
- *
- * @return string
- */
- protected function getFindChildrenSql(ObjectIdentityInterface $oid, $directChildrenOnly)
- {
- if (false === $directChildrenOnly) {
- $query = <<<FINDCHILDREN
- SELECT o.object_identifier, c.class_type
- FROM
- {$this->options['oid_table_name']} o
- INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
- INNER JOIN {$this->options['oid_ancestors_table_name']} a ON a.object_identity_id = o.id
- WHERE
- a.ancestor_id = %d AND a.object_identity_id != a.ancestor_id
-FINDCHILDREN;
- } else {
- $query = <<<FINDCHILDREN
- SELECT o.object_identifier, c.class_type
- FROM {$this->options['oid_table_name']} o
- INNER JOIN {$this->options['class_table_name']} c ON c.id = o.class_id
- WHERE o.parent_object_identity_id = %d
-FINDCHILDREN;
- }
-
- return sprintf($query, $this->retrieveObjectIdentityPrimaryKey($oid));
- }
-
- /**
- * Constructs the SQL for retrieving the primary key of the given object
- * identity.
- *
- * @param ObjectIdentityInterface $oid
- *
- * @return string
- */
- protected function getSelectObjectIdentityIdSql(ObjectIdentityInterface $oid)
- {
- $query = <<<'QUERY'
- SELECT o.id
- FROM %s o
- INNER JOIN %s c ON c.id = o.class_id
- WHERE o.object_identifier = %s AND c.class_type = %s
-QUERY;
-
- return sprintf(
- $query,
- $this->options['oid_table_name'],
- $this->options['class_table_name'],
- $this->connection->quote((string) $oid->getIdentifier()),
- $this->connection->quote((string) $oid->getType())
- );
- }
-
- /**
- * Returns the primary key of the passed object identity.
- *
- * @param ObjectIdentityInterface $oid
- *
- * @return int
- */
- final protected function retrieveObjectIdentityPrimaryKey(ObjectIdentityInterface $oid)
- {
- return $this->connection->executeQuery($this->getSelectObjectIdentityIdSql($oid))->fetchColumn();
- }
-
- /**
- * This method is called when an ACL instance is retrieved from the cache.
- *
- * @param AclInterface $acl
- */
- private function updateAceIdentityMap(AclInterface $acl)
- {
- foreach (array('classAces', 'classFieldAces', 'objectAces', 'objectFieldAces') as $property) {
- $reflection = new \ReflectionProperty($acl, $property);
- $reflection->setAccessible(true);
- $value = $reflection->getValue($acl);
-
- if ('classAces' === $property || 'objectAces' === $property) {
- $this->doUpdateAceIdentityMap($value);
- } else {
- foreach ($value as $field => $aces) {
- $this->doUpdateAceIdentityMap($value[$field]);
- }
- }
-
- $reflection->setValue($acl, $value);
- $reflection->setAccessible(false);
- }
- }
-
- /**
- * Retrieves all the ids which need to be queried from the database
- * including the ids of parent ACLs.
- *
- * @param array $batch
- *
- * @return array
- */
- private function getAncestorIds(array $batch)
- {
- $sql = $this->getAncestorLookupSql($batch);
-
- $ancestorIds = array();
- foreach ($this->connection->executeQuery($sql)->fetchAll() as $data) {
- // FIXME: skip ancestors which are cached
- // Fix: Oracle returns keys in uppercase
- $ancestorIds[] = reset($data);
- }
-
- return $ancestorIds;
- }
-
- /**
- * Does either overwrite the passed ACE, or saves it in the global identity
- * map to ensure every ACE only gets instantiated once.
- *
- * @param array &$aces
- */
- private function doUpdateAceIdentityMap(array &$aces)
- {
- foreach ($aces as $index => $ace) {
- if (isset($this->loadedAces[$ace->getId()])) {
- $aces[$index] = $this->loadedAces[$ace->getId()];
- } else {
- $this->loadedAces[$ace->getId()] = $ace;
- }
- }
- }
-
- /**
- * This method is called for object identities which could not be retrieved
- * from the cache, and for which thus a database query is required.
- *
- * @param array $batch
- * @param array $sids
- * @param array $oidLookup
- *
- * @return \SplObjectStorage mapping object identities to ACL instances
- *
- * @throws AclNotFoundException
- */
- private function lookupObjectIdentities(array $batch, array $sids, array $oidLookup)
- {
- $ancestorIds = $this->getAncestorIds($batch);
- if (!$ancestorIds) {
- throw new AclNotFoundException('There is no ACL for the given object identity.');
- }
-
- $sql = $this->getLookupSql($ancestorIds);
- $stmt = $this->connection->executeQuery($sql);
-
- return $this->hydrateObjectIdentities($stmt, $oidLookup, $sids);
- }
-
- /**
- * This method is called to hydrate ACLs and ACEs.
- *
- * This method was designed for performance; thus, a lot of code has been
- * inlined at the cost of readability, and maintainability.
- *
- * Keep in mind that changes to this method might severely reduce the
- * performance of the entire ACL system.
- *
- * @param Statement $stmt
- * @param array $oidLookup
- * @param array $sids
- *
- * @return \SplObjectStorage
- *
- * @throws \RuntimeException
- */
- private function hydrateObjectIdentities(Statement $stmt, array $oidLookup, array $sids)
- {
- $parentIdToFill = new \SplObjectStorage();
- $acls = $aces = $emptyArray = array();
- $oidCache = $oidLookup;
- $result = new \SplObjectStorage();
- $loadedAces = &$this->loadedAces;
- $loadedAcls = &$this->loadedAcls;
- $permissionGrantingStrategy = $this->permissionGrantingStrategy;
-
- // we need these to set protected properties on hydrated objects
- $aclReflection = new \ReflectionClass('Symfony\Component\Security\Acl\Domain\Acl');
- $aclClassAcesProperty = $aclReflection->getProperty('classAces');
- $aclClassAcesProperty->setAccessible(true);
- $aclClassFieldAcesProperty = $aclReflection->getProperty('classFieldAces');
- $aclClassFieldAcesProperty->setAccessible(true);
- $aclObjectAcesProperty = $aclReflection->getProperty('objectAces');
- $aclObjectAcesProperty->setAccessible(true);
- $aclObjectFieldAcesProperty = $aclReflection->getProperty('objectFieldAces');
- $aclObjectFieldAcesProperty->setAccessible(true);
- $aclParentAclProperty = $aclReflection->getProperty('parentAcl');
- $aclParentAclProperty->setAccessible(true);
-
- // fetchAll() consumes more memory than consecutive calls to fetch(),
- // but it is faster
- foreach ($stmt->fetchAll(\PDO::FETCH_NUM) as $data) {
- list($aclId,
- $objectIdentifier,
- $parentObjectIdentityId,
- $entriesInheriting,
- $classType,
- $aceId,
- $objectIdentityId,
- $fieldName,
- $aceOrder,
- $mask,
- $granting,
- $grantingStrategy,
- $auditSuccess,
- $auditFailure,
- $username,
- $securityIdentifier) = array_values($data);
-
- // has the ACL been hydrated during this hydration cycle?
- if (isset($acls[$aclId])) {
- $acl = $acls[$aclId];
- // has the ACL been hydrated during any previous cycle, or was possibly loaded
- // from cache?
- } elseif (isset($loadedAcls[$classType][$objectIdentifier])) {
- $acl = $loadedAcls[$classType][$objectIdentifier];
-
- // keep reference in local array (saves us some hash calculations)
- $acls[$aclId] = $acl;
-
- // attach ACL to the result set; even though we do not enforce that every
- // object identity has only one instance, we must make sure to maintain
- // referential equality with the oids passed to findAcls()
- $oidCacheKey = $objectIdentifier.$classType;
- if (!isset($oidCache[$oidCacheKey])) {
- $oidCache[$oidCacheKey] = $acl->getObjectIdentity();
- }
- $result->attach($oidCache[$oidCacheKey], $acl);
- // so, this hasn't been hydrated yet
- } else {
- // create object identity if we haven't done so yet
- $oidLookupKey = $objectIdentifier.$classType;
- if (!isset($oidCache[$oidLookupKey])) {
- $oidCache[$oidLookupKey] = new ObjectIdentity($objectIdentifier, $classType);
- }
-
- $acl = new Acl((int) $aclId, $oidCache[$oidLookupKey], $permissionGrantingStrategy, $emptyArray, (bool) $entriesInheriting);
-
- // keep a local, and global reference to this ACL
- $loadedAcls[$classType][$objectIdentifier] = $acl;
- $acls[$aclId] = $acl;
-
- // try to fill in parent ACL, or defer until all ACLs have been hydrated
- if (null !== $parentObjectIdentityId) {
- if (isset($acls[$parentObjectIdentityId])) {
- $aclParentAclProperty->setValue($acl, $acls[$parentObjectIdentityId]);
- } else {
- $parentIdToFill->attach($acl, $parentObjectIdentityId);
- }
- }
-
- $result->attach($oidCache[$oidLookupKey], $acl);
- }
-
- // check if this row contains an ACE record
- if (null !== $aceId) {
- // have we already hydrated ACEs for this ACL?
- if (!isset($aces[$aclId])) {
- $aces[$aclId] = array($emptyArray, $emptyArray, $emptyArray, $emptyArray);
- }
-
- // has this ACE already been hydrated during a previous cycle, or
- // possible been loaded from cache?
- // It is important to only ever have one ACE instance per actual row since
- // some ACEs are shared between ACL instances
- if (!isset($loadedAces[$aceId])) {
- if (!isset($sids[$key = ($username ? '1' : '0').$securityIdentifier])) {
- if ($username) {
- $sids[$key] = new UserSecurityIdentity(
- substr($securityIdentifier, 1 + $pos = strpos($securityIdentifier, '-')),
- substr($securityIdentifier, 0, $pos)
- );
- } else {
- $sids[$key] = new RoleSecurityIdentity($securityIdentifier);
- }
- }
-
- if (null === $fieldName) {
- $loadedAces[$aceId] = new Entry((int) $aceId, $acl, $sids[$key], $grantingStrategy, (int) $mask, (bool) $granting, (bool) $auditFailure, (bool) $auditSuccess);
- } else {
- $loadedAces[$aceId] = new FieldEntry((int) $aceId, $acl, $fieldName, $sids[$key], $grantingStrategy, (int) $mask, (bool) $granting, (bool) $auditFailure, (bool) $auditSuccess);
- }
- }
- $ace = $loadedAces[$aceId];
-
- // assign ACE to the correct property
- if (null === $objectIdentityId) {
- if (null === $fieldName) {
- $aces[$aclId][0][$aceOrder] = $ace;
- } else {
- $aces[$aclId][1][$fieldName][$aceOrder] = $ace;
- }
- } else {
- if (null === $fieldName) {
- $aces[$aclId][2][$aceOrder] = $ace;
- } else {
- $aces[$aclId][3][$fieldName][$aceOrder] = $ace;
- }
- }
- }
- }
-
- // We do not sort on database level since we only want certain subsets to be sorted,
- // and we are going to read the entire result set anyway.
- // Sorting on DB level increases query time by an order of magnitude while it is
- // almost negligible when we use PHPs array sort functions.
- foreach ($aces as $aclId => $aceData) {
- $acl = $acls[$aclId];
-
- ksort($aceData[0]);
- $aclClassAcesProperty->setValue($acl, $aceData[0]);
-
- foreach (array_keys($aceData[1]) as $fieldName) {
- ksort($aceData[1][$fieldName]);
- }
- $aclClassFieldAcesProperty->setValue($acl, $aceData[1]);
-
- ksort($aceData[2]);
- $aclObjectAcesProperty->setValue($acl, $aceData[2]);
-
- foreach (array_keys($aceData[3]) as $fieldName) {
- ksort($aceData[3][$fieldName]);
- }
- $aclObjectFieldAcesProperty->setValue($acl, $aceData[3]);
- }
-
- // fill-in parent ACLs where this hasn't been done yet cause the parent ACL was not
- // yet available
- $processed = 0;
- foreach ($parentIdToFill as $acl) {
- $parentId = $parentIdToFill->offsetGet($acl);
-
- // let's see if we have already hydrated this
- if (isset($acls[$parentId])) {
- $aclParentAclProperty->setValue($acl, $acls[$parentId]);
- ++$processed;
-
- continue;
- }
- }
-
- // reset reflection changes
- $aclClassAcesProperty->setAccessible(false);
- $aclClassFieldAcesProperty->setAccessible(false);
- $aclObjectAcesProperty->setAccessible(false);
- $aclObjectFieldAcesProperty->setAccessible(false);
- $aclParentAclProperty->setAccessible(false);
-
- // this should never be true if the database integrity hasn't been compromised
- if ($processed < count($parentIdToFill)) {
- throw new \RuntimeException('Not all parent ids were populated. This implies an integrity problem.');
- }
-
- return $result;
- }
-}
diff --git a/Acl/Dbal/MutableAclProvider.php b/Acl/Dbal/MutableAclProvider.php
deleted file mode 100644
index bd1976f..0000000
--- a/Acl/Dbal/MutableAclProvider.php
+++ /dev/null
@@ -1,1034 +0,0 @@
-<?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\Dbal;
-
-use Doctrine\Common\PropertyChangedListener;
-use Doctrine\DBAL\Connection;
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException;
-use Symfony\Component\Security\Acl\Exception\ConcurrentModificationException;
-use Symfony\Component\Security\Acl\Model\AclCacheInterface;
-use Symfony\Component\Security\Acl\Model\AclInterface;
-use Symfony\Component\Security\Acl\Model\EntryInterface;
-use Symfony\Component\Security\Acl\Model\MutableAclInterface;
-use Symfony\Component\Security\Acl\Model\MutableAclProviderInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
-use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
-/**
- * An implementation of the MutableAclProviderInterface using Doctrine DBAL.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class MutableAclProvider extends AclProvider implements MutableAclProviderInterface, PropertyChangedListener
-{
- private $propertyChanges;
-
- /**
- * {@inheritdoc}
- */
- public function __construct(Connection $connection, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $options, AclCacheInterface $cache = null)
- {
- parent::__construct($connection, $permissionGrantingStrategy, $options, $cache);
-
- $this->propertyChanges = new \SplObjectStorage();
- }
-
- /**
- * {@inheritdoc}
- */
- public function createAcl(ObjectIdentityInterface $oid)
- {
- if (false !== $this->retrieveObjectIdentityPrimaryKey($oid)) {
- $objectName = method_exists($oid, '__toString') ? $oid : get_class($oid);
- throw new AclAlreadyExistsException(sprintf('%s is already associated with an ACL.', $objectName));
- }
-
- $this->connection->beginTransaction();
- try {
- $this->createObjectIdentity($oid);
-
- $pk = $this->retrieveObjectIdentityPrimaryKey($oid);
- $this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $pk));
-
- $this->connection->commit();
- } catch (\Exception $e) {
- $this->connection->rollBack();
-
- throw $e;
- }
-
- // re-read the ACL from the database to ensure proper caching, etc.
- return $this->findAcl($oid);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteAcl(ObjectIdentityInterface $oid)
- {
- $this->connection->beginTransaction();
- try {
- foreach ($this->findChildren($oid, true) as $childOid) {
- $this->deleteAcl($childOid);
- }
-
- $oidPK = $this->retrieveObjectIdentityPrimaryKey($oid);
-
- $this->deleteAccessControlEntries($oidPK);
- $this->deleteObjectIdentityRelations($oidPK);
- $this->deleteObjectIdentity($oidPK);
-
- $this->connection->commit();
- } catch (\Exception $e) {
- $this->connection->rollBack();
-
- throw $e;
- }
-
- // evict the ACL from the in-memory identity map
- if (isset($this->loadedAcls[$oid->getType()][$oid->getIdentifier()])) {
- $this->propertyChanges->offsetUnset($this->loadedAcls[$oid->getType()][$oid->getIdentifier()]);
- unset($this->loadedAcls[$oid->getType()][$oid->getIdentifier()]);
- }
-
- // evict the ACL from any caches
- if (null !== $this->cache) {
- $this->cache->evictFromCacheByIdentity($oid);
- }
- }
-
- /**
- * Deletes the security identity from the database.
- * ACL entries have the CASCADE option on their foreign key so they will also get deleted.
- *
- * @param SecurityIdentityInterface $sid
- *
- * @throws \InvalidArgumentException
- */
- public function deleteSecurityIdentity(SecurityIdentityInterface $sid)
- {
- $this->connection->executeQuery($this->getDeleteSecurityIdentityIdSql($sid));
- }
-
- /**
- * {@inheritdoc}
- */
- public function findAcls(array $oids, array $sids = array())
- {
- $result = parent::findAcls($oids, $sids);
-
- foreach ($result as $oid) {
- $acl = $result->offsetGet($oid);
-
- if (false === $this->propertyChanges->contains($acl) && $acl instanceof MutableAclInterface) {
- $acl->addPropertyChangedListener($this);
- $this->propertyChanges->attach($acl, array());
- }
-
- $parentAcl = $acl->getParentAcl();
- while (null !== $parentAcl) {
- if (false === $this->propertyChanges->contains($parentAcl) && $acl instanceof MutableAclInterface) {
- $parentAcl->addPropertyChangedListener($this);
- $this->propertyChanges->attach($parentAcl, array());
- }
-
- $parentAcl = $parentAcl->getParentAcl();
- }
- }
-
- return $result;
- }
-
- /**
- * Implementation of PropertyChangedListener.
- *
- * This allows us to keep track of which values have been changed, so we don't
- * have to do a full introspection when ->updateAcl() is called.
- *
- * @param mixed $sender
- * @param string $propertyName
- * @param mixed $oldValue
- * @param mixed $newValue
- *
- * @throws \InvalidArgumentException
- */
- public function propertyChanged($sender, $propertyName, $oldValue, $newValue)
- {
- if (!$sender instanceof MutableAclInterface && !$sender instanceof EntryInterface) {
- throw new \InvalidArgumentException('$sender must be an instance of MutableAclInterface, or EntryInterface.');
- }
-
- if ($sender instanceof EntryInterface) {
- if (null === $sender->getId()) {
- return;
- }
-
- $ace = $sender;
- $sender = $ace->getAcl();
- } else {
- $ace = null;
- }
-
- if (false === $this->propertyChanges->contains($sender)) {
- throw new \InvalidArgumentException('$sender is not being tracked by this provider.');
- }
-
- $propertyChanges = $this->propertyChanges->offsetGet($sender);
- if (null === $ace) {
- if (isset($propertyChanges[$propertyName])) {
- $oldValue = $propertyChanges[$propertyName][0];
- if ($oldValue === $newValue) {
- unset($propertyChanges[$propertyName]);
- } else {
- $propertyChanges[$propertyName] = array($oldValue, $newValue);
- }
- } else {
- $propertyChanges[$propertyName] = array($oldValue, $newValue);
- }
- } else {
- if (!isset($propertyChanges['aces'])) {
- $propertyChanges['aces'] = new \SplObjectStorage();
- }
-
- $acePropertyChanges = $propertyChanges['aces']->contains($ace) ? $propertyChanges['aces']->offsetGet($ace) : array();
-
- if (isset($acePropertyChanges[$propertyName])) {
- $oldValue = $acePropertyChanges[$propertyName][0];
- if ($oldValue === $newValue) {
- unset($acePropertyChanges[$propertyName]);
- } else {
- $acePropertyChanges[$propertyName] = array($oldValue, $newValue);
- }
- } else {
- $acePropertyChanges[$propertyName] = array($oldValue, $newValue);
- }
-
- if (count($acePropertyChanges) > 0) {
- $propertyChanges['aces']->offsetSet($ace, $acePropertyChanges);
- } else {
- $propertyChanges['aces']->offsetUnset($ace);
-
- if (0 === count($propertyChanges['aces'])) {
- unset($propertyChanges['aces']);
- }
- }
- }
-
- $this->propertyChanges->offsetSet($sender, $propertyChanges);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateAcl(MutableAclInterface $acl)
- {
- if (!$this->propertyChanges->contains($acl)) {
- throw new \InvalidArgumentException('$acl is not tracked by this provider.');
- }
-
- $propertyChanges = $this->propertyChanges->offsetGet($acl);
- // check if any changes were made to this ACL
- if (0 === count($propertyChanges)) {
- return;
- }
-
- $sets = $sharedPropertyChanges = array();
-
- $this->connection->beginTransaction();
- try {
- if (isset($propertyChanges['entriesInheriting'])) {
- $sets[] = 'entries_inheriting = '.$this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['entriesInheriting'][1]);
- }
-
- if (isset($propertyChanges['parentAcl'])) {
- if (null === $propertyChanges['parentAcl'][1]) {
- $sets[] = 'parent_object_identity_id = NULL';
- } else {
- $sets[] = 'parent_object_identity_id = '.(int) $propertyChanges['parentAcl'][1]->getId();
- }
-
- $this->regenerateAncestorRelations($acl);
- $childAcls = $this->findAcls($this->findChildren($acl->getObjectIdentity(), false));
- foreach ($childAcls as $childOid) {
- $this->regenerateAncestorRelations($childAcls[$childOid]);
- }
- }
-
- // check properties for deleted, and created ACEs, and perform deletions
- // we need to perform deletions before updating existing ACEs, in order to
- // preserve uniqueness of the order field
- if (isset($propertyChanges['classAces'])) {
- $this->updateOldAceProperty('classAces', $propertyChanges['classAces']);
- }
- if (isset($propertyChanges['classFieldAces'])) {
- $this->updateOldFieldAceProperty('classFieldAces', $propertyChanges['classFieldAces']);
- }
- if (isset($propertyChanges['objectAces'])) {
- $this->updateOldAceProperty('objectAces', $propertyChanges['objectAces']);
- }
- if (isset($propertyChanges['objectFieldAces'])) {
- $this->updateOldFieldAceProperty('objectFieldAces', $propertyChanges['objectFieldAces']);
- }
-
- // this includes only updates of existing ACEs, but neither the creation, nor
- // the deletion of ACEs; these are tracked by changes to the ACL's respective
- // properties (classAces, classFieldAces, objectAces, objectFieldAces)
- if (isset($propertyChanges['aces'])) {
- $this->updateAces($propertyChanges['aces']);
- }
-
- // check properties for deleted, and created ACEs, and perform creations
- if (isset($propertyChanges['classAces'])) {
- $this->updateNewAceProperty('classAces', $propertyChanges['classAces']);
- $sharedPropertyChanges['classAces'] = $propertyChanges['classAces'];
- }
- if (isset($propertyChanges['classFieldAces'])) {
- $this->updateNewFieldAceProperty('classFieldAces', $propertyChanges['classFieldAces']);
- $sharedPropertyChanges['classFieldAces'] = $propertyChanges['classFieldAces'];
- }
- if (isset($propertyChanges['objectAces'])) {
- $this->updateNewAceProperty('objectAces', $propertyChanges['objectAces']);
- }
- if (isset($propertyChanges['objectFieldAces'])) {
- $this->updateNewFieldAceProperty('objectFieldAces', $propertyChanges['objectFieldAces']);
- }
-
- // if there have been changes to shared properties, we need to synchronize other
- // ACL instances for object identities of the same type that are already in-memory
- if (count($sharedPropertyChanges) > 0) {
- $classAcesProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Acl', 'classAces');
- $classAcesProperty->setAccessible(true);
- $classFieldAcesProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Acl', 'classFieldAces');
- $classFieldAcesProperty->setAccessible(true);
-
- foreach ($this->loadedAcls[$acl->getObjectIdentity()->getType()] as $sameTypeAcl) {
- if (isset($sharedPropertyChanges['classAces'])) {
- if ($acl !== $sameTypeAcl && $classAcesProperty->getValue($sameTypeAcl) !== $sharedPropertyChanges['classAces'][0]) {
- throw new ConcurrentModificationException('The "classAces" property has been modified concurrently.');
- }
-
- $classAcesProperty->setValue($sameTypeAcl, $sharedPropertyChanges['classAces'][1]);
- }
-
- if (isset($sharedPropertyChanges['classFieldAces'])) {
- if ($acl !== $sameTypeAcl && $classFieldAcesProperty->getValue($sameTypeAcl) !== $sharedPropertyChanges['classFieldAces'][0]) {
- throw new ConcurrentModificationException('The "classFieldAces" property has been modified concurrently.');
- }
-
- $classFieldAcesProperty->setValue($sameTypeAcl, $sharedPropertyChanges['classFieldAces'][1]);
- }
- }
- }
-
- // persist any changes to the acl_object_identities table
- if (count($sets) > 0) {
- $this->connection->executeQuery($this->getUpdateObjectIdentitySql($acl->getId(), $sets));
- }
-
- $this->connection->commit();
- } catch (\Exception $e) {
- $this->connection->rollBack();
-
- throw $e;
- }
-
- $this->propertyChanges->offsetSet($acl, array());
-
- if (null !== $this->cache) {
- if (count($sharedPropertyChanges) > 0) {
- // FIXME: Currently, there is no easy way to clear the cache for ACLs
- // of a certain type. The problem here is that we need to make
- // sure to clear the cache of all child ACLs as well, and these
- // child ACLs might be of a different class type.
- $this->cache->clearCache();
- } else {
- // if there are no shared property changes, it's sufficient to just delete
- // the cache for this ACL
- $this->cache->evictFromCacheByIdentity($acl->getObjectIdentity());
-
- foreach ($this->findChildren($acl->getObjectIdentity()) as $childOid) {
- $this->cache->evictFromCacheByIdentity($childOid);
- }
- }
- }
- }
-
- /**
- * Updates a user security identity when the user's username changes.
- *
- * @param UserSecurityIdentity $usid
- * @param string $oldUsername
- */
- public function updateUserSecurityIdentity(UserSecurityIdentity $usid, $oldUsername)
- {
- $this->connection->executeQuery($this->getUpdateUserSecurityIdentitySql($usid, $oldUsername));
- }
-
- /**
- * Constructs the SQL for deleting access control entries.
- *
- * @param int $oidPK
- *
- * @return string
- */
- protected function getDeleteAccessControlEntriesSql($oidPK)
- {
- return sprintf(
- 'DELETE FROM %s WHERE object_identity_id = %d',
- $this->options['entry_table_name'],
- $oidPK
- );
- }
-
- /**
- * Constructs the SQL for deleting a specific ACE.
- *
- * @param int $acePK
- *
- * @return string
- */
- protected function getDeleteAccessControlEntrySql($acePK)
- {
- return sprintf(
- 'DELETE FROM %s WHERE id = %d',
- $this->options['entry_table_name'],
- $acePK
- );
- }
-
- /**
- * Constructs the SQL for deleting an object identity.
- *
- * @param int $pk
- *
- * @return string
- */
- protected function getDeleteObjectIdentitySql($pk)
- {
- return sprintf(
- 'DELETE FROM %s WHERE id = %d',
- $this->options['oid_table_name'],
- $pk
- );
- }
-
- /**
- * Constructs the SQL for deleting relation entries.
- *
- * @param int $pk
- *
- * @return string
- */
- protected function getDeleteObjectIdentityRelationsSql($pk)
- {
- return sprintf(
- 'DELETE FROM %s WHERE object_identity_id = %d',
- $this->options['oid_ancestors_table_name'],
- $pk
- );
- }
-
- /**
- * Constructs the SQL for inserting an ACE.
- *
- * @param int $classId
- * @param int|null $objectIdentityId
- * @param string|null $field
- * @param int $aceOrder
- * @param int $securityIdentityId
- * @param string $strategy
- * @param int $mask
- * @param bool $granting
- * @param bool $auditSuccess
- * @param bool $auditFailure
- *
- * @return string
- */
- protected function getInsertAccessControlEntrySql($classId, $objectIdentityId, $field, $aceOrder, $securityIdentityId, $strategy, $mask, $granting, $auditSuccess, $auditFailure)
- {
- $query = <<<'QUERY'
- INSERT INTO %s (
- class_id,
- object_identity_id,
- field_name,
- ace_order,
- security_identity_id,
- mask,
- granting,
- granting_strategy,
- audit_success,
- audit_failure
- )
- VALUES (%d, %s, %s, %d, %d, %d, %s, %s, %s, %s)
-QUERY;
-
- return sprintf(
- $query,
- $this->options['entry_table_name'],
- $classId,
- null === $objectIdentityId ? 'NULL' : (int) $objectIdentityId,
- null === $field ? 'NULL' : $this->connection->quote($field),
- $aceOrder,
- $securityIdentityId,
- $mask,
- $this->connection->getDatabasePlatform()->convertBooleans($granting),
- $this->connection->quote($strategy),
- $this->connection->getDatabasePlatform()->convertBooleans($auditSuccess),
- $this->connection->getDatabasePlatform()->convertBooleans($auditFailure)
- );
- }
-
- /**
- * Constructs the SQL for inserting a new class type.
- *
- * @param string $classType
- *
- * @return string
- */
- protected function getInsertClassSql($classType)
- {
- return sprintf(
- 'INSERT INTO %s (class_type) VALUES (%s)',
- $this->options['class_table_name'],
- $this->connection->quote($classType)
- );
- }
-
- /**
- * Constructs the SQL for inserting a relation entry.
- *
- * @param int $objectIdentityId
- * @param int $ancestorId
- *
- * @return string
- */
- protected function getInsertObjectIdentityRelationSql($objectIdentityId, $ancestorId)
- {
- return sprintf(
- 'INSERT INTO %s (object_identity_id, ancestor_id) VALUES (%d, %d)',
- $this->options['oid_ancestors_table_name'],
- $objectIdentityId,
- $ancestorId
- );
- }
-
- /**
- * Constructs the SQL for inserting an object identity.
- *
- * @param string $identifier
- * @param int $classId
- * @param bool $entriesInheriting
- *
- * @return string
- */
- protected function getInsertObjectIdentitySql($identifier, $classId, $entriesInheriting)
- {
- $query = <<<'QUERY'
- INSERT INTO %s (class_id, object_identifier, entries_inheriting)
- VALUES (%d, %s, %s)
-QUERY;
-
- return sprintf(
- $query,
- $this->options['oid_table_name'],
- $classId,
- $this->connection->quote($identifier),
- $this->connection->getDatabasePlatform()->convertBooleans($entriesInheriting)
- );
- }
-
- /**
- * Constructs the SQL for inserting a security identity.
- *
- * @param SecurityIdentityInterface $sid
- *
- * @return string
- *
- * @throws \InvalidArgumentException
- */
- protected function getInsertSecurityIdentitySql(SecurityIdentityInterface $sid)
- {
- if ($sid instanceof UserSecurityIdentity) {
- $identifier = $sid->getClass().'-'.$sid->getUsername();
- $username = true;
- } elseif ($sid instanceof RoleSecurityIdentity) {
- $identifier = $sid->getRole();
- $username = false;
- } else {
- throw new \InvalidArgumentException('$sid must either be an instance of UserSecurityIdentity, or RoleSecurityIdentity.');
- }
-
- return sprintf(
- 'INSERT INTO %s (identifier, username) VALUES (%s, %s)',
- $this->options['sid_table_name'],
- $this->connection->quote($identifier),
- $this->connection->getDatabasePlatform()->convertBooleans($username)
- );
- }
-
- /**
- * Constructs the SQL for selecting an ACE.
- *
- * @param int $classId
- * @param int $oid
- * @param string $field
- * @param int $order
- *
- * @return string
- */
- protected function getSelectAccessControlEntryIdSql($classId, $oid, $field, $order)
- {
- return sprintf(
- 'SELECT id FROM %s WHERE class_id = %d AND %s AND %s AND ace_order = %d',
- $this->options['entry_table_name'],
- $classId,
- null === $oid ?
- $this->connection->getDatabasePlatform()->getIsNullExpression('object_identity_id')
- : 'object_identity_id = '.(int) $oid,
- null === $field ?
- $this->connection->getDatabasePlatform()->getIsNullExpression('field_name')
- : 'field_name = '.$this->connection->quote($field),
- $order
- );
- }
-
- /**
- * Constructs the SQL for selecting the primary key associated with
- * the passed class type.
- *
- * @param string $classType
- *
- * @return string
- */
- protected function getSelectClassIdSql($classType)
- {
- return sprintf(
- 'SELECT id FROM %s WHERE class_type = %s',
- $this->options['class_table_name'],
- $this->connection->quote($classType)
- );
- }
-
- /**
- * Constructs the SQL for selecting the primary key of a security identity.
- *
- * @param SecurityIdentityInterface $sid
- *
- * @return string
- *
- * @throws \InvalidArgumentException
- */
- protected function getSelectSecurityIdentityIdSql(SecurityIdentityInterface $sid)
- {
- if ($sid instanceof UserSecurityIdentity) {
- $identifier = $sid->getClass().'-'.$sid->getUsername();
- $username = true;
- } elseif ($sid instanceof RoleSecurityIdentity) {
- $identifier = $sid->getRole();
- $username = false;
- } else {
- throw new \InvalidArgumentException('$sid must either be an instance of UserSecurityIdentity, or RoleSecurityIdentity.');
- }
-
- return sprintf(
- 'SELECT id FROM %s WHERE identifier = %s AND username = %s',
- $this->options['sid_table_name'],
- $this->connection->quote($identifier),
- $this->connection->getDatabasePlatform()->convertBooleans($username)
- );
- }
-
- /**
- * Constructs the SQL to delete a security identity.
- *
- * @param SecurityIdentityInterface $sid
- *
- * @return string
- *
- * @throws \InvalidArgumentException
- */
- protected function getDeleteSecurityIdentityIdSql(SecurityIdentityInterface $sid)
- {
- $select = $this->getSelectSecurityIdentityIdSql($sid);
- $delete = preg_replace('/^SELECT id FROM/', 'DELETE FROM', $select);
-
- return $delete;
- }
-
- /**
- * Constructs the SQL for updating an object identity.
- *
- * @param int $pk
- * @param array $changes
- *
- * @return string
- *
- * @throws \InvalidArgumentException
- */
- protected function getUpdateObjectIdentitySql($pk, array $changes)
- {
- if (0 === count($changes)) {
- throw new \InvalidArgumentException('There are no changes.');
- }
-
- return sprintf(
- 'UPDATE %s SET %s WHERE id = %d',
- $this->options['oid_table_name'],
- implode(', ', $changes),
- $pk
- );
- }
-
- /**
- * Constructs the SQL for updating a user security identity.
- *
- * @param UserSecurityIdentity $usid
- * @param string $oldUsername
- *
- * @return string
- */
- protected function getUpdateUserSecurityIdentitySql(UserSecurityIdentity $usid, $oldUsername)
- {
- if ($usid->getUsername() == $oldUsername) {
- throw new \InvalidArgumentException('There are no changes.');
- }
-
- $oldIdentifier = $usid->getClass().'-'.$oldUsername;
- $newIdentifier = $usid->getClass().'-'.$usid->getUsername();
-
- return sprintf(
- 'UPDATE %s SET identifier = %s WHERE identifier = %s AND username = %s',
- $this->options['sid_table_name'],
- $this->connection->quote($newIdentifier),
- $this->connection->quote($oldIdentifier),
- $this->connection->getDatabasePlatform()->convertBooleans(true)
- );
- }
-
- /**
- * Constructs the SQL for updating an ACE.
- *
- * @param int $pk
- * @param array $sets
- *
- * @return string
- *
- * @throws \InvalidArgumentException
- */
- protected function getUpdateAccessControlEntrySql($pk, array $sets)
- {
- if (0 === count($sets)) {
- throw new \InvalidArgumentException('There are no changes.');
- }
-
- return sprintf(
- 'UPDATE %s SET %s WHERE id = %d',
- $this->options['entry_table_name'],
- implode(', ', $sets),
- $pk
- );
- }
-
- /**
- * Creates the ACL for the passed object identity.
- *
- * @param ObjectIdentityInterface $oid
- */
- private function createObjectIdentity(ObjectIdentityInterface $oid)
- {
- $classId = $this->createOrRetrieveClassId($oid->getType());
-
- $this->connection->executeQuery($this->getInsertObjectIdentitySql($oid->getIdentifier(), $classId, true));
- }
-
- /**
- * Returns the primary key for the passed class type.
- *
- * If the type does not yet exist in the database, it will be created.
- *
- * @param string $classType
- *
- * @return int
- */
- private function createOrRetrieveClassId($classType)
- {
- if (false !== $id = $this->connection->executeQuery($this->getSelectClassIdSql($classType))->fetchColumn()) {
- return $id;
- }
-
- $this->connection->executeQuery($this->getInsertClassSql($classType));
-
- return $this->connection->executeQuery($this->getSelectClassIdSql($classType))->fetchColumn();
- }
-
- /**
- * Returns the primary key for the passed security identity.
- *
- * If the security identity does not yet exist in the database, it will be
- * created.
- *
- * @param SecurityIdentityInterface $sid
- *
- * @return int
- */
- private function createOrRetrieveSecurityIdentityId(SecurityIdentityInterface $sid)
- {
- if (false !== $id = $this->connection->executeQuery($this->getSelectSecurityIdentityIdSql($sid))->fetchColumn()) {
- return $id;
- }
-
- $this->connection->executeQuery($this->getInsertSecurityIdentitySql($sid));
-
- return $this->connection->executeQuery($this->getSelectSecurityIdentityIdSql($sid))->fetchColumn();
- }
-
- /**
- * Deletes all ACEs for the given object identity primary key.
- *
- * @param int $oidPK
- */
- private function deleteAccessControlEntries($oidPK)
- {
- $this->connection->executeQuery($this->getDeleteAccessControlEntriesSql($oidPK));
- }
-
- /**
- * Deletes the object identity from the database.
- *
- * @param int $pk
- */
- private function deleteObjectIdentity($pk)
- {
- $this->connection->executeQuery($this->getDeleteObjectIdentitySql($pk));
- }
-
- /**
- * Deletes all entries from the relations table from the database.
- *
- * @param int $pk
- */
- private function deleteObjectIdentityRelations($pk)
- {
- $this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk));
- }
-
- /**
- * This regenerates the ancestor table which is used for fast read access.
- *
- * @param AclInterface $acl
- */
- private function regenerateAncestorRelations(AclInterface $acl)
- {
- $pk = $acl->getId();
- $this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk));
- $this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $pk));
-
- $parentAcl = $acl->getParentAcl();
- while (null !== $parentAcl) {
- $this->connection->executeQuery($this->getInsertObjectIdentityRelationSql($pk, $parentAcl->getId()));
-
- $parentAcl = $parentAcl->getParentAcl();
- }
- }
-
- /**
- * This processes new entries changes on an ACE related property (classFieldAces, or objectFieldAces).
- *
- * @param string $name
- * @param array $changes
- */
- private function updateNewFieldAceProperty($name, array $changes)
- {
- $sids = new \SplObjectStorage();
- $classIds = new \SplObjectStorage();
- foreach ($changes[1] as $field => $new) {
- for ($i = 0, $c = count($new); $i < $c; ++$i) {
- $ace = $new[$i];
-
- if (null === $ace->getId()) {
- if ($sids->contains($ace->getSecurityIdentity())) {
- $sid = $sids->offsetGet($ace->getSecurityIdentity());
- } else {
- $sid = $this->createOrRetrieveSecurityIdentityId($ace->getSecurityIdentity());
- }
-
- $oid = $ace->getAcl()->getObjectIdentity();
- if ($classIds->contains($oid)) {
- $classId = $classIds->offsetGet($oid);
- } else {
- $classId = $this->createOrRetrieveClassId($oid->getType());
- }
-
- $objectIdentityId = $name === 'classFieldAces' ? null : $ace->getAcl()->getId();
-
- $this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, $field, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure()));
- $aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, $field, $i))->fetchColumn();
- $this->loadedAces[$aceId] = $ace;
-
- $aceIdProperty = new \ReflectionProperty('Symfony\Component\Security\Acl\Domain\Entry', 'id');
- $aceIdProperty->setAccessible(true);
- $aceIdProperty->setValue($ace, (int) $aceId);
- }
- }
- }
- }
-
- /**
- * This processes old entries changes on an ACE related property (classFieldAces, or objectFieldAces).
- *
- * @param string $name
- * @param array $changes
- */
- private function updateOldFieldAceProperty($name, array $changes)
- {
- $currentIds = array();
- foreach ($changes[1] as $field => $new) {
- for ($i = 0, $c = count($new); $i < $c; ++$i) {
- $ace = $new[$i];
-
- if (null !== $ace->getId()) {
- $currentIds[$ace->getId()] = true;
- }
- }
- }
-
- foreach ($changes[0] as $old) {
- for ($i = 0, $c = count($old); $i < $c; ++$i) {
- $ace = $old[$i];
-
- if (!isset($currentIds[$ace->getId()])) {
- $this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId()));
- unset($this->loadedAces[$ace->getId()]);
- }
- }
- }
- }
-
- /**
- * This processes new entries changes on an ACE related property (classAces, or objectAces).
- *
- * @param string $name
- * @param array $changes
- */
- private function updateNewAceProperty($name, array $changes)
- {
- list(, $new) = $changes;
-
- $sids = new \SplObjectStorage();
- $classIds = new \SplObjectStorage();
- for ($i = 0, $c = count($new); $i < $c; ++$i) {
- $ace = $new[$i];
-
- if (null === $ace->getId()) {
- if ($sids->contains($ace->getSecurityIdentity())) {
- $sid = $sids->offsetGet($ace->getSecurityIdentity());
- } else {
- $sid = $this->createOrRetrieveSecurityIdentityId($ace->getSecurityIdentity());
- }
-
- $oid = $ace->getAcl()->getObjectIdentity();
- if ($classIds->contains($oid)) {
- $classId = $classIds->offsetGet($oid);
- } else {
- $classId = $this->createOrRetrieveClassId($oid->getType());
- }
-
- $objectIdentityId = $name === 'classAces' ? null : $ace->getAcl()->getId();
-
- $this->connection->executeQuery($this->getInsertAccessControlEntrySql($classId, $objectIdentityId, null, $i, $sid, $ace->getStrategy(), $ace->getMask(), $ace->isGranting(), $ace->isAuditSuccess(), $ace->isAuditFailure()));
- $aceId = $this->connection->executeQuery($this->getSelectAccessControlEntryIdSql($classId, $objectIdentityId, null, $i))->fetchColumn();
- $this->loadedAces[$aceId] = $ace;
-
- $aceIdProperty = new \ReflectionProperty($ace, 'id');
- $aceIdProperty->setAccessible(true);
- $aceIdProperty->setValue($ace, (int) $aceId);
- }
- }
- }
-
- /**
- * This processes old entries changes on an ACE related property (classAces, or objectAces).
- *
- * @param string $name
- * @param array $changes
- */
- private function updateOldAceProperty($name, array $changes)
- {
- list($old, $new) = $changes;
- $currentIds = array();
-
- for ($i = 0, $c = count($new); $i < $c; ++$i) {
- $ace = $new[$i];
-
- if (null !== $ace->getId()) {
- $currentIds[$ace->getId()] = true;
- }
- }
-
- for ($i = 0, $c = count($old); $i < $c; ++$i) {
- $ace = $old[$i];
-
- if (!isset($currentIds[$ace->getId()])) {
- $this->connection->executeQuery($this->getDeleteAccessControlEntrySql($ace->getId()));
- unset($this->loadedAces[$ace->getId()]);
- }
- }
- }
-
- /**
- * Persists the changes which were made to ACEs to the database.
- *
- * @param \SplObjectStorage $aces
- */
- private function updateAces(\SplObjectStorage $aces)
- {
- foreach ($aces as $ace) {
- $this->updateAce($aces, $ace);
- }
- }
-
- private function updateAce(\SplObjectStorage $aces, $ace)
- {
- $propertyChanges = $aces->offsetGet($ace);
- $sets = array();
-
- if (isset($propertyChanges['aceOrder'])
- && $propertyChanges['aceOrder'][1] > $propertyChanges['aceOrder'][0]
- && $propertyChanges == $aces->offsetGet($ace)) {
- $aces->next();
- if ($aces->valid()) {
- $this->updateAce($aces, $aces->current());
- }
- }
-
- if (isset($propertyChanges['mask'])) {
- $sets[] = sprintf('mask = %d', $propertyChanges['mask'][1]);
- }
- if (isset($propertyChanges['strategy'])) {
- $sets[] = sprintf('granting_strategy = %s', $this->connection->quote($propertyChanges['strategy']));
- }
- if (isset($propertyChanges['aceOrder'])) {
- $sets[] = sprintf('ace_order = %d', $propertyChanges['aceOrder'][1]);
- }
- if (isset($propertyChanges['auditSuccess'])) {
- $sets[] = sprintf('audit_success = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditSuccess'][1]));
- }
- if (isset($propertyChanges['auditFailure'])) {
- $sets[] = sprintf('audit_failure = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditFailure'][1]));
- }
-
- $this->connection->executeQuery($this->getUpdateAccessControlEntrySql($ace->getId(), $sets));
- }
-}
diff --git a/Acl/Dbal/Schema.php b/Acl/Dbal/Schema.php
deleted file mode 100644
index ed9327c..0000000
--- a/Acl/Dbal/Schema.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?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\Dbal;
-
-use Doctrine\DBAL\Schema\Schema as BaseSchema;
-use Doctrine\DBAL\Connection;
-
-/**
- * The schema used for the ACL system.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-final class Schema extends BaseSchema
-{
- protected $options;
-
- /**
- * Constructor.
- *
- * @param array $options the names for tables
- * @param Connection $connection
- */
- public function __construct(array $options, Connection $connection = null)
- {
- $schemaConfig = null === $connection ? null : $connection->getSchemaManager()->createSchemaConfig();
-
- parent::__construct(array(), array(), $schemaConfig);
-
- $this->options = $options;
-
- $this->addClassTable();
- $this->addSecurityIdentitiesTable();
- $this->addObjectIdentitiesTable();
- $this->addObjectIdentityAncestorsTable();
- $this->addEntryTable();
- }
-
- /**
- * Merges ACL schema with the given schema.
- *
- * @param BaseSchema $schema
- */
- public function addToSchema(BaseSchema $schema)
- {
- foreach ($this->getTables() as $table) {
- $schema->_addTable($table);
- }
-
- foreach ($this->getSequences() as $sequence) {
- $schema->_addSequence($sequence);
- }
- }
-
- /**
- * Adds the class table to the schema.
- */
- protected function addClassTable()
- {
- $table = $this->createTable($this->options['class_table_name']);
- $table->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => 'auto'));
- $table->addColumn('class_type', 'string', array('length' => 200));
- $table->setPrimaryKey(array('id'));
- $table->addUniqueIndex(array('class_type'));
- }
-
- /**
- * Adds the entry table to the schema.
- */
- protected function addEntryTable()
- {
- $table = $this->createTable($this->options['entry_table_name']);
-
- $table->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => 'auto'));
- $table->addColumn('class_id', 'integer', array('unsigned' => true));
- $table->addColumn('object_identity_id', 'integer', array('unsigned' => true, 'notnull' => false));
- $table->addColumn('field_name', 'string', array('length' => 50, 'notnull' => false));
- $table->addColumn('ace_order', 'smallint', array('unsigned' => true));
- $table->addColumn('security_identity_id', 'integer', array('unsigned' => true));
- $table->addColumn('mask', 'integer');
- $table->addColumn('granting', 'boolean');
- $table->addColumn('granting_strategy', 'string', array('length' => 30));
- $table->addColumn('audit_success', 'boolean');
- $table->addColumn('audit_failure', 'boolean');
-
- $table->setPrimaryKey(array('id'));
- $table->addUniqueIndex(array('class_id', 'object_identity_id', 'field_name', 'ace_order'));
- $table->addIndex(array('class_id', 'object_identity_id', 'security_identity_id'));
-
- $table->addForeignKeyConstraint($this->getTable($this->options['class_table_name']), array('class_id'), array('id'), array('onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE'));
- $table->addForeignKeyConstraint($this->getTable($this->options['oid_table_name']), array('object_identity_id'), array('id'), array('onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE'));
- $table->addForeignKeyConstraint($this->getTable($this->options['sid_table_name']), array('security_identity_id'), array('id'), array('onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE'));
- }
-
- /**
- * Adds the object identity table to the schema.
- */
- protected function addObjectIdentitiesTable()
- {
- $table = $this->createTable($this->options['oid_table_name']);
-
- $table->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => 'auto'));
- $table->addColumn('class_id', 'integer', array('unsigned' => true));
- $table->addColumn('object_identifier', 'string', array('length' => 100));
- $table->addColumn('parent_object_identity_id', 'integer', array('unsigned' => true, 'notnull' => false));
- $table->addColumn('entries_inheriting', 'boolean');
-
- $table->setPrimaryKey(array('id'));
- $table->addUniqueIndex(array('object_identifier', 'class_id'));
- $table->addIndex(array('parent_object_identity_id'));
-
- $table->addForeignKeyConstraint($table, array('parent_object_identity_id'), array('id'));
- }
-
- /**
- * Adds the object identity relation table to the schema.
- */
- protected function addObjectIdentityAncestorsTable()
- {
- $table = $this->createTable($this->options['oid_ancestors_table_name']);
-
- $table->addColumn('object_identity_id', 'integer', array('unsigned' => true));
- $table->addColumn('ancestor_id', 'integer', array('unsigned' => true));
-
- $table->setPrimaryKey(array('object_identity_id', 'ancestor_id'));
-
- $oidTable = $this->getTable($this->options['oid_table_name']);
- $table->addForeignKeyConstraint($oidTable, array('object_identity_id'), array('id'), array('onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE'));
- $table->addForeignKeyConstraint($oidTable, array('ancestor_id'), array('id'), array('onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE'));
- }
-
- /**
- * Adds the security identity table to the schema.
- */
- protected function addSecurityIdentitiesTable()
- {
- $table = $this->createTable($this->options['sid_table_name']);
-
- $table->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => 'auto'));
- $table->addColumn('identifier', 'string', array('length' => 200));
- $table->addColumn('username', 'boolean');
-
- $table->setPrimaryKey(array('id'));
- $table->addUniqueIndex(array('identifier', 'username'));
- }
-}
diff --git a/Acl/Domain/Acl.php b/Acl/Domain/Acl.php
deleted file mode 100644
index fb70738..0000000
--- a/Acl/Domain/Acl.php
+++ /dev/null
@@ -1,667 +0,0 @@
-<?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\NotifyPropertyChanged;
-use Doctrine\Common\PropertyChangedListener;
-use Symfony\Component\Security\Acl\Model\AclInterface;
-use Symfony\Component\Security\Acl\Model\AuditableAclInterface;
-use Symfony\Component\Security\Acl\Model\EntryInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
-use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
-/**
- * An ACL implementation.
- *
- * Each object identity has exactly one associated ACL. Each ACL can have four
- * different types of ACEs (class ACEs, object ACEs, class field ACEs, object field
- * ACEs).
- *
- * You should not iterate over the ACEs yourself, but instead use isGranted(),
- * or isFieldGranted(). These will utilize an implementation of PermissionGrantingStrategy
- * internally.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class Acl implements AuditableAclInterface, NotifyPropertyChanged
-{
- private $parentAcl;
- private $permissionGrantingStrategy;
- private $objectIdentity;
- private $classAces = array();
- private $classFieldAces = array();
- private $objectAces = array();
- private $objectFieldAces = array();
- private $id;
- private $loadedSids;
- private $entriesInheriting;
- private $listeners = array();
-
- /**
- * Constructor.
- *
- * @param int $id
- * @param ObjectIdentityInterface $objectIdentity
- * @param PermissionGrantingStrategyInterface $permissionGrantingStrategy
- * @param array $loadedSids
- * @param bool $entriesInheriting
- */
- public function __construct($id, ObjectIdentityInterface $objectIdentity, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $loadedSids, $entriesInheriting)
- {
- $this->id = $id;
- $this->objectIdentity = $objectIdentity;
- $this->permissionGrantingStrategy = $permissionGrantingStrategy;
- $this->loadedSids = $loadedSids;
- $this->entriesInheriting = $entriesInheriting;
- }
-
- /**
- * Adds a property changed listener.
- *
- * @param PropertyChangedListener $listener
- */
- public function addPropertyChangedListener(PropertyChangedListener $listener)
- {
- $this->listeners[] = $listener;
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteClassAce($index)
- {
- $this->deleteAce('classAces', $index);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteClassFieldAce($index, $field)
- {
- $this->deleteFieldAce('classFieldAces', $index, $field);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteObjectAce($index)
- {
- $this->deleteAce('objectAces', $index);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteObjectFieldAce($index, $field)
- {
- $this->deleteFieldAce('objectFieldAces', $index, $field);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getClassAces()
- {
- return $this->classAces;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getClassFieldAces($field)
- {
- return isset($this->classFieldAces[$field]) ? $this->classFieldAces[$field] : array();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getObjectAces()
- {
- return $this->objectAces;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getObjectFieldAces($field)
- {
- return isset($this->objectFieldAces[$field]) ? $this->objectFieldAces[$field] : array();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getObjectIdentity()
- {
- return $this->objectIdentity;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getParentAcl()
- {
- return $this->parentAcl;
- }
-
- /**
- * {@inheritdoc}
- */
- public function insertClassAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null)
- {
- $this->insertAce('classAces', $index, $mask, $sid, $granting, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function insertClassFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null)
- {
- $this->insertFieldAce('classFieldAces', $index, $field, $mask, $sid, $granting, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function insertObjectAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null)
- {
- $this->insertAce('objectAces', $index, $mask, $sid, $granting, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function insertObjectFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null)
- {
- $this->insertFieldAce('objectFieldAces', $index, $field, $mask, $sid, $granting, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function isEntriesInheriting()
- {
- return $this->entriesInheriting;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isFieldGranted($field, array $masks, array $securityIdentities, $administrativeMode = false)
- {
- return $this->permissionGrantingStrategy->isFieldGranted($this, $field, $masks, $securityIdentities, $administrativeMode);
- }
-
- /**
- * {@inheritdoc}
- */
- public function isGranted(array $masks, array $securityIdentities, $administrativeMode = false)
- {
- return $this->permissionGrantingStrategy->isGranted($this, $masks, $securityIdentities, $administrativeMode);
- }
-
- /**
- * {@inheritdoc}
- */
- public function isSidLoaded($sids)
- {
- if (!$this->loadedSids) {
- return true;
- }
-
- if (!is_array($sids)) {
- $sids = array($sids);
- }
-
- foreach ($sids as $sid) {
- if (!$sid instanceof SecurityIdentityInterface) {
- throw new \InvalidArgumentException(
- '$sid must be an instance of SecurityIdentityInterface.');
- }
-
- foreach ($this->loadedSids as $loadedSid) {
- if ($loadedSid->equals($sid)) {
- continue 2;
- }
- }
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Implementation for the \Serializable interface.
- *
- * @return string
- */
- public function serialize()
- {
- return serialize(array(
- null === $this->parentAcl ? null : $this->parentAcl->getId(),
- $this->objectIdentity,
- $this->classAces,
- $this->classFieldAces,
- $this->objectAces,
- $this->objectFieldAces,
- $this->id,
- $this->loadedSids,
- $this->entriesInheriting,
- ));
- }
-
- /**
- * Implementation for the \Serializable interface.
- *
- * @param string $serialized
- */
- public function unserialize($serialized)
- {
- list($this->parentAcl,
- $this->objectIdentity,
- $this->classAces,
- $this->classFieldAces,
- $this->objectAces,
- $this->objectFieldAces,
- $this->id,
- $this->loadedSids,
- $this->entriesInheriting
- ) = unserialize($serialized);
-
- $this->listeners = array();
- }
-
- /**
- * {@inheritdoc}
- */
- public function setEntriesInheriting($boolean)
- {
- if ($this->entriesInheriting !== $boolean) {
- $this->onPropertyChanged('entriesInheriting', $this->entriesInheriting, $boolean);
- $this->entriesInheriting = $boolean;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function setParentAcl(AclInterface $acl = null)
- {
- if (null !== $acl && null === $acl->getId()) {
- throw new \InvalidArgumentException('$acl must have an ID.');
- }
-
- if ($this->parentAcl !== $acl) {
- $this->onPropertyChanged('parentAcl', $this->parentAcl, $acl);
- $this->parentAcl = $acl;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateClassAce($index, $mask, $strategy = null)
- {
- $this->updateAce('classAces', $index, $mask, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateClassFieldAce($index, $field, $mask, $strategy = null)
- {
- $this->updateFieldAce('classFieldAces', $index, $field, $mask, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateObjectAce($index, $mask, $strategy = null)
- {
- $this->updateAce('objectAces', $index, $mask, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateObjectFieldAce($index, $field, $mask, $strategy = null)
- {
- $this->updateFieldAce('objectFieldAces', $index, $field, $mask, $strategy);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateClassAuditing($index, $auditSuccess, $auditFailure)
- {
- $this->updateAuditing($this->classAces, $index, $auditSuccess, $auditFailure);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateClassFieldAuditing($index, $field, $auditSuccess, $auditFailure)
- {
- if (!isset($this->classFieldAces[$field])) {
- throw new \InvalidArgumentException(sprintf('There are no ACEs for field "%s".', $field));
- }
-
- $this->updateAuditing($this->classFieldAces[$field], $index, $auditSuccess, $auditFailure);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateObjectAuditing($index, $auditSuccess, $auditFailure)
- {
- $this->updateAuditing($this->objectAces, $index, $auditSuccess, $auditFailure);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateObjectFieldAuditing($index, $field, $auditSuccess, $auditFailure)
- {
- if (!isset($this->objectFieldAces[$field])) {
- throw new \InvalidArgumentException(sprintf('There are no ACEs for field "%s".', $field));
- }
-
- $this->updateAuditing($this->objectFieldAces[$field], $index, $auditSuccess, $auditFailure);
- }
-
- /**
- * Deletes an ACE.
- *
- * @param string $property
- * @param int $index
- *
- * @throws \OutOfBoundsException
- */
- private function deleteAce($property, $index)
- {
- $aces = &$this->$property;
- if (!isset($aces[$index])) {
- throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index));
- }
-
- $oldValue = $this->$property;
- unset($aces[$index]);
- $this->$property = array_values($this->$property);
- $this->onPropertyChanged($property, $oldValue, $this->$property);
-
- for ($i = $index, $c = count($this->$property); $i < $c; ++$i) {
- $this->onEntryPropertyChanged($aces[$i], 'aceOrder', $i + 1, $i);
- }
- }
-
- /**
- * Deletes a field-based ACE.
- *
- * @param string $property
- * @param int $index
- * @param string $field
- *
- * @throws \OutOfBoundsException
- */
- private function deleteFieldAce($property, $index, $field)
- {
- $aces = &$this->$property;
- if (!isset($aces[$field][$index])) {
- throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index));
- }
-
- $oldValue = $this->$property;
- unset($aces[$field][$index]);
- $aces[$field] = array_values($aces[$field]);
- $this->onPropertyChanged($property, $oldValue, $this->$property);
-
- for ($i = $index, $c = count($aces[$field]); $i < $c; ++$i) {
- $this->onEntryPropertyChanged($aces[$field][$i], 'aceOrder', $i + 1, $i);
- }
- }
-
- /**
- * Inserts an ACE.
- *
- * @param string $property
- * @param int $index
- * @param int $mask
- * @param SecurityIdentityInterface $sid
- * @param bool $granting
- * @param string $strategy
- *
- * @throws \OutOfBoundsException
- * @throws \InvalidArgumentException
- */
- private function insertAce($property, $index, $mask, SecurityIdentityInterface $sid, $granting, $strategy = null)
- {
- if ($index < 0 || $index > count($this->$property)) {
- throw new \OutOfBoundsException(sprintf('The index must be in the interval [0, %d].', count($this->$property)));
- }
-
- if (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- if (null === $strategy) {
- if (true === $granting) {
- $strategy = PermissionGrantingStrategy::ALL;
- } else {
- $strategy = PermissionGrantingStrategy::ANY;
- }
- }
-
- $aces = &$this->$property;
- $oldValue = $this->$property;
- if (isset($aces[$index])) {
- $this->$property = array_merge(
- array_slice($this->$property, 0, $index),
- array(true),
- array_slice($this->$property, $index)
- );
-
- for ($i = $index, $c = count($this->$property) - 1; $i < $c; ++$i) {
- $this->onEntryPropertyChanged($aces[$i + 1], 'aceOrder', $i, $i + 1);
- }
- }
-
- $aces[$index] = new Entry(null, $this, $sid, $strategy, $mask, $granting, false, false);
- $this->onPropertyChanged($property, $oldValue, $this->$property);
- }
-
- /**
- * Inserts a field-based ACE.
- *
- * @param string $property
- * @param int $index
- * @param string $field
- * @param int $mask
- * @param SecurityIdentityInterface $sid
- * @param bool $granting
- * @param string $strategy
- *
- * @throws \InvalidArgumentException
- * @throws \OutOfBoundsException
- */
- private function insertFieldAce($property, $index, $field, $mask, SecurityIdentityInterface $sid, $granting, $strategy = null)
- {
- if (0 === strlen($field)) {
- throw new \InvalidArgumentException('$field cannot be empty.');
- }
-
- if (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- if (null === $strategy) {
- if (true === $granting) {
- $strategy = PermissionGrantingStrategy::ALL;
- } else {
- $strategy = PermissionGrantingStrategy::ANY;
- }
- }
-
- $aces = &$this->$property;
- if (!isset($aces[$field])) {
- $aces[$field] = array();
- }
-
- if ($index < 0 || $index > count($aces[$field])) {
- throw new \OutOfBoundsException(sprintf('The index must be in the interval [0, %d].', count($this->$property)));
- }
-
- $oldValue = $aces;
- if (isset($aces[$field][$index])) {
- $aces[$field] = array_merge(
- array_slice($aces[$field], 0, $index),
- array(true),
- array_slice($aces[$field], $index)
- );
-
- for ($i = $index, $c = count($aces[$field]) - 1; $i < $c; ++$i) {
- $this->onEntryPropertyChanged($aces[$field][$i + 1], 'aceOrder', $i, $i + 1);
- }
- }
-
- $aces[$field][$index] = new FieldEntry(null, $this, $field, $sid, $strategy, $mask, $granting, false, false);
- $this->onPropertyChanged($property, $oldValue, $this->$property);
- }
-
- /**
- * Updates an ACE.
- *
- * @param string $property
- * @param int $index
- * @param int $mask
- * @param string $strategy
- *
- * @throws \OutOfBoundsException
- */
- private function updateAce($property, $index, $mask, $strategy = null)
- {
- $aces = &$this->$property;
- if (!isset($aces[$index])) {
- throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index));
- }
-
- $ace = $aces[$index];
- if ($mask !== $oldMask = $ace->getMask()) {
- $this->onEntryPropertyChanged($ace, 'mask', $oldMask, $mask);
- $ace->setMask($mask);
- }
- if (null !== $strategy && $strategy !== $oldStrategy = $ace->getStrategy()) {
- $this->onEntryPropertyChanged($ace, 'strategy', $oldStrategy, $strategy);
- $ace->setStrategy($strategy);
- }
- }
-
- /**
- * Updates auditing for an ACE.
- *
- * @param array &$aces
- * @param int $index
- * @param bool $auditSuccess
- * @param bool $auditFailure
- *
- * @throws \OutOfBoundsException
- */
- private function updateAuditing(array &$aces, $index, $auditSuccess, $auditFailure)
- {
- if (!isset($aces[$index])) {
- throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index));
- }
-
- if ($auditSuccess !== $aces[$index]->isAuditSuccess()) {
- $this->onEntryPropertyChanged($aces[$index], 'auditSuccess', !$auditSuccess, $auditSuccess);
- $aces[$index]->setAuditSuccess($auditSuccess);
- }
-
- if ($auditFailure !== $aces[$index]->isAuditFailure()) {
- $this->onEntryPropertyChanged($aces[$index], 'auditFailure', !$auditFailure, $auditFailure);
- $aces[$index]->setAuditFailure($auditFailure);
- }
- }
-
- /**
- * Updates a field-based ACE.
- *
- * @param string $property
- * @param int $index
- * @param string $field
- * @param int $mask
- * @param string $strategy
- *
- * @throws \InvalidArgumentException
- * @throws \OutOfBoundsException
- */
- private function updateFieldAce($property, $index, $field, $mask, $strategy = null)
- {
- if (0 === strlen($field)) {
- throw new \InvalidArgumentException('$field cannot be empty.');
- }
-
- $aces = &$this->$property;
- if (!isset($aces[$field][$index])) {
- throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index));
- }
-
- $ace = $aces[$field][$index];
- if ($mask !== $oldMask = $ace->getMask()) {
- $this->onEntryPropertyChanged($ace, 'mask', $oldMask, $mask);
- $ace->setMask($mask);
- }
- if (null !== $strategy && $strategy !== $oldStrategy = $ace->getStrategy()) {
- $this->onEntryPropertyChanged($ace, 'strategy', $oldStrategy, $strategy);
- $ace->setStrategy($strategy);
- }
- }
-
- /**
- * Called when a property of the ACL changes.
- *
- * @param string $name
- * @param mixed $oldValue
- * @param mixed $newValue
- */
- private function onPropertyChanged($name, $oldValue, $newValue)
- {
- foreach ($this->listeners as $listener) {
- $listener->propertyChanged($this, $name, $oldValue, $newValue);
- }
- }
-
- /**
- * Called when a property of an ACE associated with this ACL changes.
- *
- * @param EntryInterface $entry
- * @param string $name
- * @param mixed $oldValue
- * @param mixed $newValue
- */
- private function onEntryPropertyChanged(EntryInterface $entry, $name, $oldValue, $newValue)
- {
- foreach ($this->listeners as $listener) {
- $listener->propertyChanged($entry, $name, $oldValue, $newValue);
- }
- }
-}
diff --git a/Acl/Domain/AclCollectionCache.php b/Acl/Domain/AclCollectionCache.php
deleted file mode 100644
index 5dfef08..0000000
--- a/Acl/Domain/AclCollectionCache.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Model\AclProviderInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-
-/**
- * This service caches ACLs for an entire collection of objects.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class AclCollectionCache
-{
- private $aclProvider;
- private $objectIdentityRetrievalStrategy;
- private $securityIdentityRetrievalStrategy;
-
- /**
- * Constructor.
- *
- * @param AclProviderInterface $aclProvider
- * @param ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy
- * @param SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy
- */
- public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy)
- {
- $this->aclProvider = $aclProvider;
- $this->objectIdentityRetrievalStrategy = $oidRetrievalStrategy;
- $this->securityIdentityRetrievalStrategy = $sidRetrievalStrategy;
- }
-
- /**
- * Batch loads ACLs for an entire collection; thus, it reduces the number
- * of required queries considerably.
- *
- * @param mixed $collection anything that can be passed to foreach()
- * @param TokenInterface[] $tokens an array of TokenInterface implementations
- */
- public function cache($collection, array $tokens = array())
- {
- $sids = array();
- foreach ($tokens as $token) {
- $sids = array_merge($sids, $this->securityIdentityRetrievalStrategy->getSecurityIdentities($token));
- }
-
- $oids = array();
- foreach ($collection as $domainObject) {
- $oids[] = $this->objectIdentityRetrievalStrategy->getObjectIdentity($domainObject);
- }
-
- $this->aclProvider->findAcls($oids, $sids);
- }
-}
diff --git a/Acl/Domain/AuditLogger.php b/Acl/Domain/AuditLogger.php
deleted file mode 100644
index e3f3bdd..0000000
--- a/Acl/Domain/AuditLogger.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Model\AuditableEntryInterface;
-use Symfony\Component\Security\Acl\Model\EntryInterface;
-use Symfony\Component\Security\Acl\Model\AuditLoggerInterface;
-
-/**
- * Base audit logger implementation.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-abstract class AuditLogger implements AuditLoggerInterface
-{
- /**
- * Performs some checks if logging was requested.
- *
- * @param bool $granted
- * @param EntryInterface $ace
- */
- public function logIfNeeded($granted, EntryInterface $ace)
- {
- if (!$ace instanceof AuditableEntryInterface) {
- return;
- }
-
- if ($granted && $ace->isAuditSuccess()) {
- $this->doLog($granted, $ace);
- } elseif (!$granted && $ace->isAuditFailure()) {
- $this->doLog($granted, $ace);
- }
- }
-
- /**
- * This method is only called when logging is needed.
- *
- * @param bool $granted
- * @param EntryInterface $ace
- */
- abstract protected function doLog($granted, EntryInterface $ace);
-}
diff --git a/Acl/Domain/DoctrineAclCache.php b/Acl/Domain/DoctrineAclCache.php
deleted file mode 100644
index 667a19e..0000000
--- a/Acl/Domain/DoctrineAclCache.php
+++ /dev/null
@@ -1,229 +0,0 @@
-<?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;
- }
-}
diff --git a/Acl/Domain/Entry.php b/Acl/Domain/Entry.php
deleted file mode 100644
index 55c4b37..0000000
--- a/Acl/Domain/Entry.php
+++ /dev/null
@@ -1,208 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Model\AclInterface;
-use Symfony\Component\Security\Acl\Model\AuditableEntryInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
-/**
- * Auditable ACE implementation.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class Entry implements AuditableEntryInterface
-{
- private $acl;
- private $mask;
- private $id;
- private $securityIdentity;
- private $strategy;
- private $auditFailure;
- private $auditSuccess;
- private $granting;
-
- /**
- * Constructor.
- *
- * @param int $id
- * @param AclInterface $acl
- * @param SecurityIdentityInterface $sid
- * @param string $strategy
- * @param int $mask
- * @param bool $granting
- * @param bool $auditFailure
- * @param bool $auditSuccess
- */
- public function __construct($id, AclInterface $acl, SecurityIdentityInterface $sid, $strategy, $mask, $granting, $auditFailure, $auditSuccess)
- {
- $this->id = $id;
- $this->acl = $acl;
- $this->securityIdentity = $sid;
- $this->strategy = $strategy;
- $this->mask = $mask;
- $this->granting = $granting;
- $this->auditFailure = $auditFailure;
- $this->auditSuccess = $auditSuccess;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getAcl()
- {
- return $this->acl;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getMask()
- {
- return $this->mask;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSecurityIdentity()
- {
- return $this->securityIdentity;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getStrategy()
- {
- return $this->strategy;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isAuditFailure()
- {
- return $this->auditFailure;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isAuditSuccess()
- {
- return $this->auditSuccess;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isGranting()
- {
- return $this->granting;
- }
-
- /**
- * Turns on/off auditing on permissions denials.
- *
- * Do never call this method directly. Use the respective methods on the
- * AclInterface instead.
- *
- * @param bool $boolean
- */
- public function setAuditFailure($boolean)
- {
- $this->auditFailure = $boolean;
- }
-
- /**
- * Turns on/off auditing on permission grants.
- *
- * Do never call this method directly. Use the respective methods on the
- * AclInterface instead.
- *
- * @param bool $boolean
- */
- public function setAuditSuccess($boolean)
- {
- $this->auditSuccess = $boolean;
- }
-
- /**
- * Sets the permission mask.
- *
- * Do never call this method directly. Use the respective methods on the
- * AclInterface instead.
- *
- * @param int $mask
- */
- public function setMask($mask)
- {
- $this->mask = $mask;
- }
-
- /**
- * Sets the mask comparison strategy.
- *
- * Do never call this method directly. Use the respective methods on the
- * AclInterface instead.
- *
- * @param string $strategy
- */
- public function setStrategy($strategy)
- {
- $this->strategy = $strategy;
- }
-
- /**
- * Implementation of \Serializable.
- *
- * @return string
- */
- public function serialize()
- {
- return serialize(array(
- $this->mask,
- $this->id,
- $this->securityIdentity,
- $this->strategy,
- $this->auditFailure,
- $this->auditSuccess,
- $this->granting,
- ));
- }
-
- /**
- * Implementation of \Serializable.
- *
- * @param string $serialized
- */
- public function unserialize($serialized)
- {
- list($this->mask,
- $this->id,
- $this->securityIdentity,
- $this->strategy,
- $this->auditFailure,
- $this->auditSuccess,
- $this->granting
- ) = unserialize($serialized);
- }
-}
diff --git a/Acl/Domain/FieldEntry.php b/Acl/Domain/FieldEntry.php
deleted file mode 100644
index 86b1e5b..0000000
--- a/Acl/Domain/FieldEntry.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Model\AclInterface;
-use Symfony\Component\Security\Acl\Model\FieldEntryInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
-/**
- * Field-aware ACE implementation which is auditable.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class FieldEntry extends Entry implements FieldEntryInterface
-{
- private $field;
-
- /**
- * Constructor.
- *
- * @param int $id
- * @param AclInterface $acl
- * @param string $field
- * @param SecurityIdentityInterface $sid
- * @param string $strategy
- * @param int $mask
- * @param bool $granting
- * @param bool $auditFailure
- * @param bool $auditSuccess
- */
- public function __construct($id, AclInterface $acl, $field, SecurityIdentityInterface $sid, $strategy, $mask, $granting, $auditFailure, $auditSuccess)
- {
- parent::__construct($id, $acl, $sid, $strategy, $mask, $granting, $auditFailure, $auditSuccess);
-
- $this->field = $field;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getField()
- {
- return $this->field;
- }
-
- /**
- * {@inheritdoc}
- */
- public function serialize()
- {
- return serialize(array(
- $this->field,
- parent::serialize(),
- ));
- }
-
- /**
- * {@inheritdoc}
- */
- public function unserialize($serialized)
- {
- list($this->field, $parentStr) = unserialize($serialized);
- parent::unserialize($parentStr);
- }
-}
diff --git a/Acl/Domain/ObjectIdentity.php b/Acl/Domain/ObjectIdentity.php
deleted file mode 100644
index ec817e2..0000000
--- a/Acl/Domain/ObjectIdentity.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?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 Symfony\Component\Security\Core\Util\ClassUtils;
-use Symfony\Component\Security\Acl\Exception\InvalidDomainObjectException;
-use Symfony\Component\Security\Acl\Model\DomainObjectInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
-
-/**
- * ObjectIdentity implementation.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-final class ObjectIdentity implements ObjectIdentityInterface
-{
- private $identifier;
- private $type;
-
- /**
- * Constructor.
- *
- * @param string $identifier
- * @param string $type
- *
- * @throws \InvalidArgumentException
- */
- public function __construct($identifier, $type)
- {
- if ('' === $identifier) {
- throw new \InvalidArgumentException('$identifier cannot be empty.');
- }
- if (empty($type)) {
- throw new \InvalidArgumentException('$type cannot be empty.');
- }
-
- $this->identifier = $identifier;
- $this->type = $type;
- }
-
- /**
- * Constructs an ObjectIdentity for the given domain object.
- *
- * @param object $domainObject
- *
- * @return ObjectIdentity
- *
- * @throws InvalidDomainObjectException
- */
- public static function fromDomainObject($domainObject)
- {
- if (!is_object($domainObject)) {
- throw new InvalidDomainObjectException('$domainObject must be an object.');
- }
-
- try {
- if ($domainObject instanceof DomainObjectInterface) {
- return new self($domainObject->getObjectIdentifier(), ClassUtils::getRealClass($domainObject));
- } elseif (method_exists($domainObject, 'getId')) {
- return new self((string) $domainObject->getId(), ClassUtils::getRealClass($domainObject));
- }
- } catch (\InvalidArgumentException $e) {
- throw new InvalidDomainObjectException($e->getMessage(), 0, $e);
- }
-
- throw new InvalidDomainObjectException('$domainObject must either implement the DomainObjectInterface, or have a method named "getId".');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getIdentifier()
- {
- return $this->identifier;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getType()
- {
- return $this->type;
- }
-
- /**
- * {@inheritdoc}
- */
- public function equals(ObjectIdentityInterface $identity)
- {
- // comparing the identifier with === might lead to problems, so we
- // waive this restriction
- return $this->identifier == $identity->getIdentifier()
- && $this->type === $identity->getType();
- }
-
- /**
- * Returns a textual representation of this object identity.
- *
- * @return string
- */
- public function __toString()
- {
- return sprintf('ObjectIdentity(%s, %s)', $this->identifier, $this->type);
- }
-}
diff --git a/Acl/Domain/ObjectIdentityRetrievalStrategy.php b/Acl/Domain/ObjectIdentityRetrievalStrategy.php
deleted file mode 100644
index 80de6e0..0000000
--- a/Acl/Domain/ObjectIdentityRetrievalStrategy.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Exception\InvalidDomainObjectException;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
-
-/**
- * Strategy to be used for retrieving object identities from domain objects.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class ObjectIdentityRetrievalStrategy implements ObjectIdentityRetrievalStrategyInterface
-{
- /**
- * {@inheritdoc}
- */
- public function getObjectIdentity($domainObject)
- {
- try {
- return ObjectIdentity::fromDomainObject($domainObject);
- } catch (InvalidDomainObjectException $e) {
- return;
- }
- }
-}
diff --git a/Acl/Domain/PermissionGrantingStrategy.php b/Acl/Domain/PermissionGrantingStrategy.php
deleted file mode 100644
index f8a09a6..0000000
--- a/Acl/Domain/PermissionGrantingStrategy.php
+++ /dev/null
@@ -1,211 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Exception\NoAceFoundException;
-use Symfony\Component\Security\Acl\Model\AclInterface;
-use Symfony\Component\Security\Acl\Model\AuditLoggerInterface;
-use Symfony\Component\Security\Acl\Model\EntryInterface;
-use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
-/**
- * The permission granting strategy to apply to the access control list.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface
-{
- const EQUAL = 'equal';
- const ALL = 'all';
- const ANY = 'any';
-
- private $auditLogger;
-
- /**
- * Sets the audit logger.
- *
- * @param AuditLoggerInterface $auditLogger
- */
- public function setAuditLogger(AuditLoggerInterface $auditLogger)
- {
- $this->auditLogger = $auditLogger;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isGranted(AclInterface $acl, array $masks, array $sids, $administrativeMode = false)
- {
- try {
- try {
- $aces = $acl->getObjectAces();
-
- if (!$aces) {
- throw new NoAceFoundException();
- }
-
- return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode);
- } catch (NoAceFoundException $e) {
- $aces = $acl->getClassAces();
-
- if (!$aces) {
- throw $e;
- }
-
- return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode);
- }
- } catch (NoAceFoundException $e) {
- if ($acl->isEntriesInheriting() && null !== $parentAcl = $acl->getParentAcl()) {
- return $parentAcl->isGranted($masks, $sids, $administrativeMode);
- }
-
- throw $e;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function isFieldGranted(AclInterface $acl, $field, array $masks, array $sids, $administrativeMode = false)
- {
- try {
- try {
- $aces = $acl->getObjectFieldAces($field);
- if (!$aces) {
- throw new NoAceFoundException();
- }
-
- return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode);
- } catch (NoAceFoundException $e) {
- $aces = $acl->getClassFieldAces($field);
- if (!$aces) {
- throw $e;
- }
-
- return $this->hasSufficientPermissions($acl, $aces, $masks, $sids, $administrativeMode);
- }
- } catch (NoAceFoundException $e) {
- if ($acl->isEntriesInheriting() && null !== $parentAcl = $acl->getParentAcl()) {
- return $parentAcl->isFieldGranted($field, $masks, $sids, $administrativeMode);
- }
-
- throw $e;
- }
- }
-
- /**
- * Makes an authorization decision.
- *
- * The order of ACEs, and SIDs is significant; the order of permission masks
- * not so much. It is important to note that the more specific security
- * identities should be at the beginning of the SIDs array in order for this
- * strategy to produce intuitive authorization decisions.
- *
- * First, we will iterate over permissions, then over security identities.
- * For each combination of permission, and identity we will test the
- * available ACEs until we find one which is applicable.
- *
- * The first applicable ACE will make the ultimate decision for the
- * permission/identity combination. If it is granting, this method will return
- * true, if it is denying, the method will continue to check the next
- * permission/identity combination.
- *
- * This process is repeated until either a granting ACE is found, or no
- * permission/identity combinations are left. Finally, we will either throw
- * an NoAceFoundException, or deny access.
- *
- * @param AclInterface $acl
- * @param EntryInterface[] $aces An array of ACE to check against
- * @param array $masks An array of permission masks
- * @param SecurityIdentityInterface[] $sids An array of SecurityIdentityInterface implementations
- * @param bool $administrativeMode True turns off audit logging
- *
- * @return bool true, or false; either granting, or denying access respectively
- *
- * @throws NoAceFoundException
- */
- private function hasSufficientPermissions(AclInterface $acl, array $aces, array $masks, array $sids, $administrativeMode)
- {
- $firstRejectedAce = null;
-
- foreach ($masks as $requiredMask) {
- foreach ($sids as $sid) {
- foreach ($aces as $ace) {
- if ($sid->equals($ace->getSecurityIdentity()) && $this->isAceApplicable($requiredMask, $ace)) {
- if ($ace->isGranting()) {
- if (!$administrativeMode && null !== $this->auditLogger) {
- $this->auditLogger->logIfNeeded(true, $ace);
- }
-
- return true;
- }
-
- if (null === $firstRejectedAce) {
- $firstRejectedAce = $ace;
- }
-
- break 2;
- }
- }
- }
- }
-
- if (null !== $firstRejectedAce) {
- if (!$administrativeMode && null !== $this->auditLogger) {
- $this->auditLogger->logIfNeeded(false, $firstRejectedAce);
- }
-
- return false;
- }
-
- throw new NoAceFoundException();
- }
-
- /**
- * Determines whether the ACE is applicable to the given permission/security
- * identity combination.
- *
- * Per default, we support three different comparison strategies.
- *
- * Strategy ALL:
- * The ACE will be considered applicable when all the turned-on bits in the
- * required mask are also turned-on in the ACE mask.
- *
- * Strategy ANY:
- * The ACE will be considered applicable when any of the turned-on bits in
- * the required mask is also turned-on the in the ACE mask.
- *
- * Strategy EQUAL:
- * The ACE will be considered applicable when the bitmasks are equal.
- *
- * @param int $requiredMask
- * @param EntryInterface $ace
- *
- * @return bool
- *
- * @throws \RuntimeException if the ACE strategy is not supported
- */
- private function isAceApplicable($requiredMask, EntryInterface $ace)
- {
- $strategy = $ace->getStrategy();
- if (self::ALL === $strategy) {
- return $requiredMask === ($ace->getMask() & $requiredMask);
- } elseif (self::ANY === $strategy) {
- return 0 !== ($ace->getMask() & $requiredMask);
- } elseif (self::EQUAL === $strategy) {
- return $requiredMask === $ace->getMask();
- }
-
- throw new \RuntimeException(sprintf('The strategy "%s" is not supported.', $strategy));
- }
-}
diff --git a/Acl/Domain/RoleSecurityIdentity.php b/Acl/Domain/RoleSecurityIdentity.php
deleted file mode 100644
index c28a1c5..0000000
--- a/Acl/Domain/RoleSecurityIdentity.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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 Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-use Symfony\Component\Security\Core\Role\Role;
-
-/**
- * A SecurityIdentity implementation for roles.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-final class RoleSecurityIdentity implements SecurityIdentityInterface
-{
- private $role;
-
- /**
- * Constructor.
- *
- * @param mixed $role a Role instance, or its string representation
- */
- public function __construct($role)
- {
- if ($role instanceof Role) {
- $role = $role->getRole();
- }
-
- $this->role = $role;
- }
-
- /**
- * Returns the role name.
- *
- * @return string
- */
- public function getRole()
- {
- return $this->role;
- }
-
- /**
- * {@inheritdoc}
- */
- public function equals(SecurityIdentityInterface $sid)
- {
- if (!$sid instanceof self) {
- return false;
- }
-
- return $this->role === $sid->getRole();
- }
-
- /**
- * Returns a textual representation of this security identity.
- *
- * This is solely used for debugging purposes, not to make an equality decision.
- *
- * @return string
- */
- public function __toString()
- {
- return sprintf('RoleSecurityIdentity(%s)', $this->role);
- }
-}
diff --git a/Acl/Domain/SecurityIdentityRetrievalStrategy.php b/Acl/Domain/SecurityIdentityRetrievalStrategy.php
deleted file mode 100644
index a08f67e..0000000
--- a/Acl/Domain/SecurityIdentityRetrievalStrategy.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?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 Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
-use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
-use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
-use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
-
-/**
- * Strategy for retrieving security identities.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class SecurityIdentityRetrievalStrategy implements SecurityIdentityRetrievalStrategyInterface
-{
- private $roleHierarchy;
- private $authenticationTrustResolver;
-
- /**
- * Constructor.
- *
- * @param RoleHierarchyInterface $roleHierarchy
- * @param AuthenticationTrustResolver $authenticationTrustResolver
- */
- public function __construct(RoleHierarchyInterface $roleHierarchy, AuthenticationTrustResolver $authenticationTrustResolver)
- {
- $this->roleHierarchy = $roleHierarchy;
- $this->authenticationTrustResolver = $authenticationTrustResolver;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSecurityIdentities(TokenInterface $token)
- {
- $sids = array();
-
- // add user security identity
- if (!$token instanceof AnonymousToken) {
- try {
- $sids[] = UserSecurityIdentity::fromToken($token);
- } catch (\InvalidArgumentException $e) {
- // ignore, user has no user security identity
- }
- }
-
- // add all reachable roles
- foreach ($this->roleHierarchy->getReachableRoles($token->getRoles()) as $role) {
- $sids[] = new RoleSecurityIdentity($role);
- }
-
- // 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;
- }
-}
diff --git a/Acl/Domain/UserSecurityIdentity.php b/Acl/Domain/UserSecurityIdentity.php
deleted file mode 100644
index ea17c63..0000000
--- a/Acl/Domain/UserSecurityIdentity.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?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 Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\User\UserInterface;
-use Symfony\Component\Security\Core\Util\ClassUtils;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
-/**
- * A SecurityIdentity implementation used for actual users.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-final class UserSecurityIdentity implements SecurityIdentityInterface
-{
- private $username;
- private $class;
-
- /**
- * Constructor.
- *
- * @param string $username the username representation
- * @param string $class the user's fully qualified class name
- *
- * @throws \InvalidArgumentException
- */
- public function __construct($username, $class)
- {
- if ('' === $username || null === $username) {
- throw new \InvalidArgumentException('$username must not be empty.');
- }
- if (empty($class)) {
- throw new \InvalidArgumentException('$class must not be empty.');
- }
-
- $this->username = (string) $username;
- $this->class = $class;
- }
-
- /**
- * Creates a user security identity from a UserInterface.
- *
- * @param UserInterface $user
- *
- * @return UserSecurityIdentity
- */
- public static function fromAccount(UserInterface $user)
- {
- return new self($user->getUsername(), ClassUtils::getRealClass($user));
- }
-
- /**
- * Creates a user security identity from a TokenInterface.
- *
- * @param TokenInterface $token
- *
- * @return UserSecurityIdentity
- */
- public static function fromToken(TokenInterface $token)
- {
- $user = $token->getUser();
-
- if ($user instanceof UserInterface) {
- return self::fromAccount($user);
- }
-
- return new self((string) $user, is_object($user) ? ClassUtils::getRealClass($user) : ClassUtils::getRealClass($token));
- }
-
- /**
- * Returns the username.
- *
- * @return string
- */
- public function getUsername()
- {
- return $this->username;
- }
-
- /**
- * Returns the user's class name.
- *
- * @return string
- */
- public function getClass()
- {
- return $this->class;
- }
-
- /**
- * {@inheritdoc}
- */
- public function equals(SecurityIdentityInterface $sid)
- {
- if (!$sid instanceof self) {
- return false;
- }
-
- return $this->username === $sid->getUsername()
- && $this->class === $sid->getClass();
- }
-
- /**
- * A textual representation of this security identity.
- *
- * This is not used for equality comparison, but only for debugging.
- *
- * @return string
- */
- public function __toString()
- {
- return sprintf('UserSecurityIdentity(%s, %s)', $this->username, $this->class);
- }
-}
diff --git a/Acl/Exception/AclAlreadyExistsException.php b/Acl/Exception/AclAlreadyExistsException.php
deleted file mode 100644
index 512da7f..0000000
--- a/Acl/Exception/AclAlreadyExistsException.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown when someone tries to create an ACL for an object
- * identity that already has one.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class AclAlreadyExistsException extends Exception
-{
-}
diff --git a/Acl/Exception/AclNotFoundException.php b/Acl/Exception/AclNotFoundException.php
deleted file mode 100644
index bd66c00..0000000
--- a/Acl/Exception/AclNotFoundException.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown when we cannot locate an ACL for a passed
- * ObjectIdentity implementation.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class AclNotFoundException extends Exception
-{
-}
diff --git a/Acl/Exception/ConcurrentModificationException.php b/Acl/Exception/ConcurrentModificationException.php
deleted file mode 100644
index a527d9c..0000000
--- a/Acl/Exception/ConcurrentModificationException.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown whenever you change shared properties of more than
- * one ACL of the same class type concurrently.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class ConcurrentModificationException extends Exception
-{
-}
diff --git a/Acl/Exception/Exception.php b/Acl/Exception/Exception.php
deleted file mode 100644
index f1e1001..0000000
--- a/Acl/Exception/Exception.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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\Exception;
-
-/**
- * Base ACL exception.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class Exception extends \RuntimeException
-{
-}
diff --git a/Acl/Exception/InvalidDomainObjectException.php b/Acl/Exception/InvalidDomainObjectException.php
deleted file mode 100644
index fc1a646..0000000
--- a/Acl/Exception/InvalidDomainObjectException.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown when ObjectIdentity fails to construct an object
- * identity from the passed domain object.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class InvalidDomainObjectException extends Exception
-{
-}
diff --git a/Acl/Exception/NoAceFoundException.php b/Acl/Exception/NoAceFoundException.php
deleted file mode 100644
index 4d194d9..0000000
--- a/Acl/Exception/NoAceFoundException.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown when we cannot locate an ACE that matches the
- * combination of permission masks and security identities.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class NoAceFoundException extends Exception
-{
- public function __construct()
- {
- parent::__construct('No applicable ACE was found.');
- }
-}
diff --git a/Acl/Exception/NotAllAclsFoundException.php b/Acl/Exception/NotAllAclsFoundException.php
deleted file mode 100644
index a634382..0000000
--- a/Acl/Exception/NotAllAclsFoundException.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown when you have requested ACLs for multiple object
- * identities, but the AclProvider implementation failed to find ACLs for all
- * identities.
- *
- * This exception contains the partial result.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class NotAllAclsFoundException extends AclNotFoundException
-{
- private $partialResult;
-
- /**
- * Sets the partial result.
- *
- * @param \SplObjectStorage $result
- */
- public function setPartialResult(\SplObjectStorage $result)
- {
- $this->partialResult = $result;
- }
-
- /**
- * Returns the partial result.
- *
- * @return \SplObjectStorage
- */
- public function getPartialResult()
- {
- return $this->partialResult;
- }
-}
diff --git a/Acl/Exception/SidNotLoadedException.php b/Acl/Exception/SidNotLoadedException.php
deleted file mode 100644
index cb8c4cc..0000000
--- a/Acl/Exception/SidNotLoadedException.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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\Exception;
-
-/**
- * This exception is thrown when ACEs for an SID are requested which has not
- * been loaded from the database.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class SidNotLoadedException extends Exception
-{
-}
diff --git a/Acl/Model/AclCacheInterface.php b/Acl/Model/AclCacheInterface.php
deleted file mode 100644
index 1e74585..0000000
--- a/Acl/Model/AclCacheInterface.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?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\Model;
-
-/**
- * AclCache Interface.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface AclCacheInterface
-{
- /**
- * Removes an ACL from the cache.
- *
- * @param string $primaryKey a serialized primary key
- */
- public function evictFromCacheById($primaryKey);
-
- /**
- * Removes an ACL from the cache.
- *
- * The ACL which is returned, must reference the passed object identity.
- *
- * @param ObjectIdentityInterface $oid
- */
- public function evictFromCacheByIdentity(ObjectIdentityInterface $oid);
-
- /**
- * Retrieves an ACL for the given object identity primary key from the cache.
- *
- * @param int $primaryKey
- *
- * @return AclInterface
- */
- public function getFromCacheById($primaryKey);
-
- /**
- * Retrieves an ACL for the given object identity from the cache.
- *
- * @param ObjectIdentityInterface $oid
- *
- * @return AclInterface
- */
- public function getFromCacheByIdentity(ObjectIdentityInterface $oid);
-
- /**
- * Stores a new ACL in the cache.
- *
- * @param AclInterface $acl
- */
- public function putInCache(AclInterface $acl);
-
- /**
- * Removes all ACLs from the cache.
- */
- public function clearCache();
-}
diff --git a/Acl/Model/AclInterface.php b/Acl/Model/AclInterface.php
deleted file mode 100644
index 13a6cf8..0000000
--- a/Acl/Model/AclInterface.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?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\Model;
-
-use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
-
-/**
- * This interface represents an access control list (ACL) for a domain object.
- * Each domain object can have exactly one associated ACL.
- *
- * An ACL contains all access control entries (ACE) for a given domain object.
- * In order to avoid needing references to the domain object itself, implementations
- * use ObjectIdentity implementations as an additional level of indirection.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface AclInterface extends \Serializable
-{
- /**
- * Returns all class-based ACEs associated with this ACL.
- *
- * @return array
- */
- public function getClassAces();
-
- /**
- * Returns all class-field-based ACEs associated with this ACL.
- *
- * @param string $field
- *
- * @return array
- */
- public function getClassFieldAces($field);
-
- /**
- * Returns all object-based ACEs associated with this ACL.
- *
- * @return array
- */
- public function getObjectAces();
-
- /**
- * Returns all object-field-based ACEs associated with this ACL.
- *
- * @param string $field
- *
- * @return array
- */
- public function getObjectFieldAces($field);
-
- /**
- * Returns the object identity associated with this ACL.
- *
- * @return ObjectIdentityInterface
- */
- public function getObjectIdentity();
-
- /**
- * Returns the parent ACL, or null if there is none.
- *
- * @return AclInterface|null
- */
- public function getParentAcl();
-
- /**
- * Whether this ACL is inheriting ACEs from a parent ACL.
- *
- * @return bool
- */
- public function isEntriesInheriting();
-
- /**
- * Determines whether field access is granted.
- *
- * @param string $field
- * @param array $masks
- * @param array $securityIdentities
- * @param bool $administrativeMode
- *
- * @return bool
- */
- public function isFieldGranted($field, array $masks, array $securityIdentities, $administrativeMode = false);
-
- /**
- * Determines whether access is granted.
- *
- * @param array $masks
- * @param array $securityIdentities
- * @param bool $administrativeMode
- *
- * @return bool
- *
- * @throws NoAceFoundException when no ACE was applicable for this request
- */
- public function isGranted(array $masks, array $securityIdentities, $administrativeMode = false);
-
- /**
- * Whether the ACL has loaded ACEs for all of the passed security identities.
- *
- * @param mixed $securityIdentities an implementation of SecurityIdentityInterface, or an array thereof
- *
- * @return bool
- */
- public function isSidLoaded($securityIdentities);
-}
diff --git a/Acl/Model/AclProviderInterface.php b/Acl/Model/AclProviderInterface.php
deleted file mode 100644
index f9b41cb..0000000
--- a/Acl/Model/AclProviderInterface.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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\Model;
-
-use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
-
-/**
- * Provides a common interface for retrieving ACLs.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface AclProviderInterface
-{
- /**
- * Retrieves all child object identities from the database.
- *
- * @param ObjectIdentityInterface $parentOid
- * @param bool $directChildrenOnly
- *
- * @return array returns an array of child 'ObjectIdentity's
- */
- public function findChildren(ObjectIdentityInterface $parentOid, $directChildrenOnly = false);
-
- /**
- * Returns the ACL that belongs to the given object identity.
- *
- * @param ObjectIdentityInterface $oid
- * @param SecurityIdentityInterface[] $sids
- *
- * @return AclInterface
- *
- * @throws AclNotFoundException when there is no ACL
- */
- public function findAcl(ObjectIdentityInterface $oid, array $sids = array());
-
- /**
- * Returns the ACLs that belong to the given object identities.
- *
- * @param ObjectIdentityInterface[] $oids an array of ObjectIdentityInterface implementations
- * @param SecurityIdentityInterface[] $sids an array of SecurityIdentityInterface implementations
- *
- * @return \SplObjectStorage mapping the passed object identities to ACLs
- *
- * @throws AclNotFoundException when we cannot find an ACL for all identities
- */
- public function findAcls(array $oids, array $sids = array());
-}
diff --git a/Acl/Model/AuditLoggerInterface.php b/Acl/Model/AuditLoggerInterface.php
deleted file mode 100644
index fde4de6..0000000
--- a/Acl/Model/AuditLoggerInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?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\Model;
-
-/**
- * Interface for audit loggers.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface AuditLoggerInterface
-{
- /**
- * This method is called whenever access is granted, or denied, and
- * administrative mode is turned off.
- *
- * @param bool $granted
- * @param EntryInterface $ace
- */
- public function logIfNeeded($granted, EntryInterface $ace);
-}
diff --git a/Acl/Model/AuditableAclInterface.php b/Acl/Model/AuditableAclInterface.php
deleted file mode 100644
index e7a60e5..0000000
--- a/Acl/Model/AuditableAclInterface.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?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\Model;
-
-/**
- * This interface adds auditing capabilities to the ACL.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface AuditableAclInterface extends MutableAclInterface
-{
- /**
- * Updates auditing for class-based ACE.
- *
- * @param int $index
- * @param bool $auditSuccess
- * @param bool $auditFailure
- */
- public function updateClassAuditing($index, $auditSuccess, $auditFailure);
-
- /**
- * Updates auditing for class-field-based ACE.
- *
- * @param int $index
- * @param string $field
- * @param bool $auditSuccess
- * @param bool $auditFailure
- */
- public function updateClassFieldAuditing($index, $field, $auditSuccess, $auditFailure);
-
- /**
- * Updates auditing for object-based ACE.
- *
- * @param int $index
- * @param bool $auditSuccess
- * @param bool $auditFailure
- */
- public function updateObjectAuditing($index, $auditSuccess, $auditFailure);
-
- /**
- * Updates auditing for object-field-based ACE.
- *
- * @param int $index
- * @param string $field
- * @param bool $auditSuccess
- * @param bool $auditFailure
- */
- public function updateObjectFieldAuditing($index, $field, $auditSuccess, $auditFailure);
-}
diff --git a/Acl/Model/AuditableEntryInterface.php b/Acl/Model/AuditableEntryInterface.php
deleted file mode 100644
index 9561577..0000000
--- a/Acl/Model/AuditableEntryInterface.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?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\Model;
-
-/**
- * ACEs can implement this interface if they support auditing capabilities.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface AuditableEntryInterface extends EntryInterface
-{
- /**
- * Whether auditing for successful grants is turned on.
- *
- * @return bool
- */
- public function isAuditFailure();
-
- /**
- * Whether auditing for successful denies is turned on.
- *
- * @return bool
- */
- public function isAuditSuccess();
-}
diff --git a/Acl/Model/DomainObjectInterface.php b/Acl/Model/DomainObjectInterface.php
deleted file mode 100644
index 195cb4e..0000000
--- a/Acl/Model/DomainObjectInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?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\Model;
-
-/**
- * This method can be implemented by domain objects which you want to store
- * ACLs for if they do not have a getId() method, or getId() does not return
- * a unique identifier.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface DomainObjectInterface
-{
- /**
- * Returns a unique identifier for this domain object.
- *
- * @return string
- */
- public function getObjectIdentifier();
-}
diff --git a/Acl/Model/EntryInterface.php b/Acl/Model/EntryInterface.php
deleted file mode 100644
index 0b244b7..0000000
--- a/Acl/Model/EntryInterface.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?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\Model;
-
-/**
- * This class represents an individual entry in the ACL list.
- *
- * Instances MUST be immutable, as they are returned by the ACL and should not
- * allow client modification.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface EntryInterface extends \Serializable
-{
- /**
- * The ACL this ACE is associated with.
- *
- * @return AclInterface
- */
- public function getAcl();
-
- /**
- * The primary key of this ACE.
- *
- * @return int
- */
- public function getId();
-
- /**
- * The permission mask of this ACE.
- *
- * @return int
- */
- public function getMask();
-
- /**
- * The security identity associated with this ACE.
- *
- * @return SecurityIdentityInterface
- */
- public function getSecurityIdentity();
-
- /**
- * The strategy for comparing masks.
- *
- * @return string
- */
- public function getStrategy();
-
- /**
- * Returns whether this ACE is granting, or denying.
- *
- * @return bool
- */
- public function isGranting();
-}
diff --git a/Acl/Model/FieldEntryInterface.php b/Acl/Model/FieldEntryInterface.php
deleted file mode 100644
index ae2f808..0000000
--- a/Acl/Model/FieldEntryInterface.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?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\Model;
-
-/**
- * Interface for entries which are restricted to specific fields.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface FieldEntryInterface extends EntryInterface
-{
- /**
- * Returns the field used for this entry.
- *
- * @return string
- */
- public function getField();
-}
diff --git a/Acl/Model/MutableAclInterface.php b/Acl/Model/MutableAclInterface.php
deleted file mode 100644
index 2ba7bd5..0000000
--- a/Acl/Model/MutableAclInterface.php
+++ /dev/null
@@ -1,158 +0,0 @@
-<?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\Model;
-
-/**
- * This interface adds mutators for the AclInterface.
- *
- * All changes to Access Control Entries must go through this interface. Access
- * Control Entries must never be modified directly.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface MutableAclInterface extends AclInterface
-{
- /**
- * Deletes a class-based ACE.
- *
- * @param int $index
- */
- public function deleteClassAce($index);
-
- /**
- * Deletes a class-field-based ACE.
- *
- * @param int $index
- * @param string $field
- */
- public function deleteClassFieldAce($index, $field);
-
- /**
- * Deletes an object-based ACE.
- *
- * @param int $index
- */
- public function deleteObjectAce($index);
-
- /**
- * Deletes an object-field-based ACE.
- *
- * @param int $index
- * @param string $field
- */
- public function deleteObjectFieldAce($index, $field);
-
- /**
- * Returns the primary key of this ACL.
- *
- * @return int
- */
- public function getId();
-
- /**
- * Inserts a class-based ACE.
- *
- * @param SecurityIdentityInterface $sid
- * @param int $mask
- * @param int $index
- * @param bool $granting
- * @param string $strategy
- */
- public function insertClassAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
-
- /**
- * Inserts a class-field-based ACE.
- *
- * @param string $field
- * @param SecurityIdentityInterface $sid
- * @param int $mask
- * @param int $index
- * @param bool $granting
- * @param string $strategy
- */
- public function insertClassFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
-
- /**
- * Inserts an object-based ACE.
- *
- * @param SecurityIdentityInterface $sid
- * @param int $mask
- * @param int $index
- * @param bool $granting
- * @param string $strategy
- */
- public function insertObjectAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
-
- /**
- * Inserts an object-field-based ACE.
- *
- * @param string $field
- * @param SecurityIdentityInterface $sid
- * @param int $mask
- * @param int $index
- * @param bool $granting
- * @param string $strategy
- */
- public function insertObjectFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
-
- /**
- * Sets whether entries are inherited.
- *
- * @param bool $boolean
- */
- public function setEntriesInheriting($boolean);
-
- /**
- * Sets the parent ACL.
- *
- * @param AclInterface|null $acl
- */
- public function setParentAcl(AclInterface $acl = null);
-
- /**
- * Updates a class-based ACE.
- *
- * @param int $index
- * @param int $mask
- * @param string $strategy if null the strategy should not be changed
- */
- public function updateClassAce($index, $mask, $strategy = null);
-
- /**
- * Updates a class-field-based ACE.
- *
- * @param int $index
- * @param string $field
- * @param int $mask
- * @param string $strategy if null the strategy should not be changed
- */
- public function updateClassFieldAce($index, $field, $mask, $strategy = null);
-
- /**
- * Updates an object-based ACE.
- *
- * @param int $index
- * @param int $mask
- * @param string $strategy if null the strategy should not be changed
- */
- public function updateObjectAce($index, $mask, $strategy = null);
-
- /**
- * Updates an object-field-based ACE.
- *
- * @param int $index
- * @param string $field
- * @param int $mask
- * @param string $strategy if null the strategy should not be changed
- */
- public function updateObjectFieldAce($index, $field, $mask, $strategy = null);
-}
diff --git a/Acl/Model/MutableAclProviderInterface.php b/Acl/Model/MutableAclProviderInterface.php
deleted file mode 100644
index ee6d7c4..0000000
--- a/Acl/Model/MutableAclProviderInterface.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?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\Model;
-
-use Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException;
-
-/**
- * Provides support for creating and storing ACL instances.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface MutableAclProviderInterface extends AclProviderInterface
-{
- /**
- * Creates a new ACL for the given object identity.
- *
- * @param ObjectIdentityInterface $oid
- *
- * @return MutableAclInterface
- *
- * @throws AclAlreadyExistsException when there already is an ACL for the given
- * object identity
- */
- public function createAcl(ObjectIdentityInterface $oid);
-
- /**
- * Deletes the ACL for a given object identity.
- *
- * This will automatically trigger a delete for any child ACLs. If you don't
- * want child ACLs to be deleted, you will have to set their parent ACL to null.
- *
- * @param ObjectIdentityInterface $oid
- */
- public function deleteAcl(ObjectIdentityInterface $oid);
-
- /**
- * Persists any changes which were made to the ACL, or any associated
- * access control entries.
- *
- * Changes to parent ACLs are not persisted.
- *
- * @param MutableAclInterface $acl
- */
- public function updateAcl(MutableAclInterface $acl);
-}
diff --git a/Acl/Model/ObjectIdentityInterface.php b/Acl/Model/ObjectIdentityInterface.php
deleted file mode 100644
index 6574b49..0000000
--- a/Acl/Model/ObjectIdentityInterface.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?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\Model;
-
-/**
- * Represents the identity of an individual domain object instance.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface ObjectIdentityInterface
-{
- /**
- * We specifically require this method so we can check for object equality
- * explicitly, and do not have to rely on referencial equality instead.
- *
- * Though in most cases, both checks should result in the same outcome.
- *
- * Referential Equality: $object1 === $object2
- * Example for Object Equality: $object1->getId() === $object2->getId()
- *
- * @param ObjectIdentityInterface $identity
- *
- * @return bool
- */
- public function equals(ObjectIdentityInterface $identity);
-
- /**
- * Obtains a unique identifier for this object. The identifier must not be
- * re-used for other objects with the same type.
- *
- * @return string cannot return null
- */
- public function getIdentifier();
-
- /**
- * Returns a type for the domain object. Typically, this is the PHP class name.
- *
- * @return string cannot return null
- */
- public function getType();
-}
diff --git a/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php b/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php
deleted file mode 100644
index 542066a..0000000
--- a/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?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\Model;
-
-/**
- * Retrieves the object identity for a given domain object.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface ObjectIdentityRetrievalStrategyInterface
-{
- /**
- * Retrieves the object identity from a domain object.
- *
- * @param object $domainObject
- *
- * @return ObjectIdentityInterface
- */
- public function getObjectIdentity($domainObject);
-}
diff --git a/Acl/Model/PermissionGrantingStrategyInterface.php b/Acl/Model/PermissionGrantingStrategyInterface.php
deleted file mode 100644
index fa3430d..0000000
--- a/Acl/Model/PermissionGrantingStrategyInterface.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?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\Model;
-
-/**
- * Interface used by permission granting implementations.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface PermissionGrantingStrategyInterface
-{
- /**
- * Determines whether access to a domain object is to be granted.
- *
- * @param AclInterface $acl
- * @param array $masks
- * @param array $sids
- * @param bool $administrativeMode
- *
- * @return bool
- */
- public function isGranted(AclInterface $acl, array $masks, array $sids, $administrativeMode = false);
-
- /**
- * Determines whether access to a domain object's field is to be granted.
- *
- * @param AclInterface $acl
- * @param string $field
- * @param array $masks
- * @param array $sids
- * @param bool $administrativeMode
- *
- * @return bool
- */
- public function isFieldGranted(AclInterface $acl, $field, array $masks, array $sids, $administrativeMode = false);
-}
diff --git a/Acl/Model/SecurityIdentityInterface.php b/Acl/Model/SecurityIdentityInterface.php
deleted file mode 100644
index 0a24a54..0000000
--- a/Acl/Model/SecurityIdentityInterface.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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\Model;
-
-/**
- * This interface provides an additional level of indirection, so that
- * we can work with abstracted versions of security objects and do
- * not have to save the entire objects.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface SecurityIdentityInterface
-{
- /**
- * This method is used to compare two security identities in order to
- * not rely on referential equality.
- *
- * @param SecurityIdentityInterface $identity
- */
- public function equals(SecurityIdentityInterface $identity);
-}
diff --git a/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php b/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php
deleted file mode 100644
index b5fcb75..0000000
--- a/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?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\Model;
-
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-
-/**
- * Interface for retrieving security identities from tokens.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface SecurityIdentityRetrievalStrategyInterface
-{
- /**
- * Retrieves the available security identities for the given token.
- *
- * The order in which the security identities are returned is significant.
- * Typically, security identities should be ordered from most specific to
- * least specific.
- *
- * @param TokenInterface $token
- *
- * @return SecurityIdentityInterface[] An array of SecurityIdentityInterface implementations
- */
- public function getSecurityIdentities(TokenInterface $token);
-}
diff --git a/Acl/Permission/AbstractMaskBuilder.php b/Acl/Permission/AbstractMaskBuilder.php
deleted file mode 100644
index 93f1755..0000000
--- a/Acl/Permission/AbstractMaskBuilder.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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\Permission;
-
-/**
- * This abstract class implements nearly all the MaskBuilderInterface methods.
- */
-abstract class AbstractMaskBuilder implements MaskBuilderInterface
-{
- /**
- * @var int
- */
- protected $mask;
-
- /**
- * Constructor.
- *
- * @param int $mask optional; defaults to 0
- */
- public function __construct($mask = 0)
- {
- $this->set($mask);
- }
-
- /**
- * {@inheritdoc}
- */
- public function set($mask)
- {
- if (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- $this->mask = $mask;
-
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function get()
- {
- return $this->mask;
- }
-
- /**
- * {@inheritdoc}
- */
- public function add($mask)
- {
- $this->mask |= $this->resolveMask($mask);
-
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function remove($mask)
- {
- $this->mask &= ~$this->resolveMask($mask);
-
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function reset()
- {
- $this->mask = 0;
-
- return $this;
- }
-}
diff --git a/Acl/Permission/BasicPermissionMap.php b/Acl/Permission/BasicPermissionMap.php
deleted file mode 100644
index fa5437d..0000000
--- a/Acl/Permission/BasicPermissionMap.php
+++ /dev/null
@@ -1,116 +0,0 @@
-<?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\Permission;
-
-/**
- * This is basic permission map complements the masks which have been defined
- * on the standard implementation of the MaskBuilder.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class BasicPermissionMap implements PermissionMapInterface, MaskBuilderRetrievalInterface
-{
- const PERMISSION_VIEW = 'VIEW';
- const PERMISSION_EDIT = 'EDIT';
- const PERMISSION_CREATE = 'CREATE';
- const PERMISSION_DELETE = 'DELETE';
- const PERMISSION_UNDELETE = 'UNDELETE';
- const PERMISSION_OPERATOR = 'OPERATOR';
- const PERMISSION_MASTER = 'MASTER';
- const PERMISSION_OWNER = 'OWNER';
-
- protected $map;
-
- public function __construct()
- {
- $this->map = array(
- self::PERMISSION_VIEW => array(
- MaskBuilder::MASK_VIEW,
- MaskBuilder::MASK_EDIT,
- MaskBuilder::MASK_OPERATOR,
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_EDIT => array(
- MaskBuilder::MASK_EDIT,
- MaskBuilder::MASK_OPERATOR,
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_CREATE => array(
- MaskBuilder::MASK_CREATE,
- MaskBuilder::MASK_OPERATOR,
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_DELETE => array(
- MaskBuilder::MASK_DELETE,
- MaskBuilder::MASK_OPERATOR,
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_UNDELETE => array(
- MaskBuilder::MASK_UNDELETE,
- MaskBuilder::MASK_OPERATOR,
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_OPERATOR => array(
- MaskBuilder::MASK_OPERATOR,
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_MASTER => array(
- MaskBuilder::MASK_MASTER,
- MaskBuilder::MASK_OWNER,
- ),
-
- self::PERMISSION_OWNER => array(
- MaskBuilder::MASK_OWNER,
- ),
- );
- }
-
- /**
- * {@inheritdoc}
- */
- public function getMasks($permission, $object)
- {
- if (!isset($this->map[$permission])) {
- return;
- }
-
- return $this->map[$permission];
- }
-
- /**
- * {@inheritdoc}
- */
- public function contains($permission)
- {
- return isset($this->map[$permission]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getMaskBuilder()
- {
- return new MaskBuilder();
- }
-}
diff --git a/Acl/Permission/MaskBuilder.php b/Acl/Permission/MaskBuilder.php
deleted file mode 100644
index ed13ecb..0000000
--- a/Acl/Permission/MaskBuilder.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?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\Permission;
-
-/**
- * This class allows you to build cumulative permissions easily, or convert
- * masks to a human-readable format.
- *
- * <code>
- * $builder = new MaskBuilder();
- * $builder
- * ->add('view')
- * ->add('create')
- * ->add('edit')
- * ;
- * var_dump($builder->get()); // int(7)
- * var_dump($builder->getPattern()); // string(32) ".............................ECV"
- * </code>
- *
- * We have defined some commonly used base permissions which you can use:
- * - VIEW: the SID is allowed to view the domain object / field
- * - CREATE: the SID is allowed to create new instances of the domain object / fields
- * - EDIT: the SID is allowed to edit existing instances of the domain object / field
- * - DELETE: the SID is allowed to delete domain objects
- * - UNDELETE: the SID is allowed to recover domain objects from trash
- * - OPERATOR: the SID is allowed to perform any action on the domain object
- * except for granting others permissions
- * - MASTER: the SID is allowed to perform any action on the domain object,
- * and is allowed to grant other SIDs any permission except for
- * MASTER and OWNER permissions
- * - OWNER: the SID is owning the domain object in question and can perform any
- * action on the domain object as well as grant any permission
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class MaskBuilder extends AbstractMaskBuilder
-{
- const MASK_VIEW = 1; // 1 << 0
- const MASK_CREATE = 2; // 1 << 1
- const MASK_EDIT = 4; // 1 << 2
- const MASK_DELETE = 8; // 1 << 3
- const MASK_UNDELETE = 16; // 1 << 4
- const MASK_OPERATOR = 32; // 1 << 5
- const MASK_MASTER = 64; // 1 << 6
- const MASK_OWNER = 128; // 1 << 7
- const MASK_IDDQD = 1073741823; // 1 << 0 | 1 << 1 | ... | 1 << 30
-
- const CODE_VIEW = 'V';
- const CODE_CREATE = 'C';
- const CODE_EDIT = 'E';
- const CODE_DELETE = 'D';
- const CODE_UNDELETE = 'U';
- const CODE_OPERATOR = 'O';
- const CODE_MASTER = 'M';
- const CODE_OWNER = 'N';
-
- const ALL_OFF = '................................';
- const OFF = '.';
- const ON = '*';
-
- /**
- * Returns a human-readable representation of the permission.
- *
- * @return string
- */
- public function getPattern()
- {
- $pattern = self::ALL_OFF;
- $length = strlen($pattern);
- $bitmask = str_pad(decbin($this->mask), $length, '0', STR_PAD_LEFT);
-
- for ($i = $length - 1; $i >= 0; --$i) {
- if ('1' === $bitmask[$i]) {
- try {
- $pattern[$i] = self::getCode(1 << ($length - $i - 1));
- } catch (\Exception $e) {
- $pattern[$i] = self::ON;
- }
- }
- }
-
- return $pattern;
- }
-
- /**
- * Returns the code for the passed mask.
- *
- * @param int $mask
- *
- * @return string
- *
- * @throws \InvalidArgumentException
- * @throws \RuntimeException
- */
- public static function getCode($mask)
- {
- if (!is_int($mask)) {
- throw new \InvalidArgumentException('$mask must be an integer.');
- }
-
- $reflection = new \ReflectionClass(get_called_class());
- foreach ($reflection->getConstants() as $name => $cMask) {
- if (0 !== strpos($name, 'MASK_') || $mask !== $cMask) {
- continue;
- }
-
- if (!defined($cName = 'static::CODE_'.substr($name, 5))) {
- throw new \RuntimeException('There was no code defined for this mask.');
- }
-
- return constant($cName);
- }
-
- throw new \InvalidArgumentException(sprintf('The mask "%d" is not supported.', $mask));
- }
-
- /**
- * Returns the mask for the passed code.
- *
- * @param mixed $code
- *
- * @return int
- *
- * @throws \InvalidArgumentException
- */
- public function resolveMask($code)
- {
- if (is_string($code)) {
- if (!defined($name = sprintf('static::MASK_%s', strtoupper($code)))) {
- throw new \InvalidArgumentException(sprintf('The code "%s" is not supported', $code));
- }
-
- return constant($name);
- }
-
- if (!is_int($code)) {
- throw new \InvalidArgumentException('$code must be an integer.');
- }
-
- return $code;
- }
-}
diff --git a/Acl/Permission/MaskBuilderInterface.php b/Acl/Permission/MaskBuilderInterface.php
deleted file mode 100644
index ef183de..0000000
--- a/Acl/Permission/MaskBuilderInterface.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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\Permission;
-
-/**
- * This is the interface that must be implemented by mask builders.
- */
-interface MaskBuilderInterface
-{
- /**
- * Set the mask of this permission.
- *
- * @param int $mask
- *
- * @return MaskBuilderInterface
- *
- * @throws \InvalidArgumentException if $mask is not an integer
- */
- public function set($mask);
-
- /**
- * Returns the mask of this permission.
- *
- * @return int
- */
- public function get();
-
- /**
- * Adds a mask to the permission.
- *
- * @param mixed $mask
- *
- * @return MaskBuilderInterface
- *
- * @throws \InvalidArgumentException
- */
- public function add($mask);
-
- /**
- * Removes a mask from the permission.
- *
- * @param mixed $mask
- *
- * @return MaskBuilderInterface
- *
- * @throws \InvalidArgumentException
- */
- public function remove($mask);
-
- /**
- * Resets the PermissionBuilder.
- *
- * @return MaskBuilderInterface
- */
- public function reset();
-
- /**
- * Returns the mask for the passed code.
- *
- * @param mixed $code
- *
- * @return int
- *
- * @throws \InvalidArgumentException
- */
- public function resolveMask($code);
-}
diff --git a/Acl/Permission/MaskBuilderRetrievalInterface.php b/Acl/Permission/MaskBuilderRetrievalInterface.php
deleted file mode 100644
index 2cde262..0000000
--- a/Acl/Permission/MaskBuilderRetrievalInterface.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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\Permission;
-
-/**
- * Retrieves the MaskBuilder.
- */
-interface MaskBuilderRetrievalInterface
-{
- /**
- * Returns a new instance of the MaskBuilder used in the permissionMap.
- *
- * @return MaskBuilderInterface
- */
- public function getMaskBuilder();
-}
diff --git a/Acl/Permission/PermissionMapInterface.php b/Acl/Permission/PermissionMapInterface.php
deleted file mode 100644
index 0b2f1ce..0000000
--- a/Acl/Permission/PermissionMapInterface.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?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\Permission;
-
-/**
- * This is the interface that must be implemented by permission maps.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-interface PermissionMapInterface
-{
- /**
- * Returns an array of bitmasks.
- *
- * The security identity must have been granted access to at least one of
- * these bitmasks.
- *
- * @param string $permission
- * @param object $object
- *
- * @return array may return null if permission/object combination is not supported
- */
- public function getMasks($permission, $object);
-
- /**
- * Whether this map contains the given permission.
- *
- * @param string $permission
- *
- * @return bool
- */
- public function contains($permission);
-}
diff --git a/Acl/Resources/bin/generateSql.php b/Acl/Resources/bin/generateSql.php
deleted file mode 100644
index c425651..0000000
--- a/Acl/Resources/bin/generateSql.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?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.
- */
-
-require_once __DIR__.'/../../../../ClassLoader/ClassLoader.php';
-
-use Symfony\Component\ClassLoader\ClassLoader;
-use Symfony\Component\Finder\Finder;
-use Symfony\Component\Security\Acl\Dbal\Schema;
-
-$loader = new ClassLoader();
-$loader->addPrefixes(array(
- 'Symfony' => __DIR__.'/../../../../../..',
- 'Doctrine\\Common' => __DIR__.'/../../../../../../../vendor/doctrine-common/lib',
- 'Doctrine\\DBAL\\Migrations' => __DIR__.'/../../../../../../../vendor/doctrine-migrations/lib',
- 'Doctrine\\DBAL' => __DIR__.'/../../../../../../../vendor/doctrine/dbal/lib',
- 'Doctrine' => __DIR__.'/../../../../../../../vendor/doctrine/lib',
-));
-$loader->register();
-
-$schema = new Schema(array(
- 'class_table_name' => 'acl_classes',
- 'entry_table_name' => 'acl_entries',
- 'oid_table_name' => 'acl_object_identities',
- 'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
- 'sid_table_name' => 'acl_security_identities',
-));
-
-$reflection = new ReflectionClass('Doctrine\\DBAL\\Platforms\\AbstractPlatform');
-$finder = new Finder();
-$finder->name('*Platform.php')->in(dirname($reflection->getFileName()));
-foreach ($finder as $file) {
- require_once $file->getPathname();
- $className = 'Doctrine\\DBAL\\Platforms\\'.$file->getBasename('.php');
-
- $reflection = new ReflectionClass($className);
- if ($reflection->isAbstract()) {
- continue;
- }
-
- $platform = $reflection->newInstance();
- $targetFile = sprintf(__DIR__.'/../schema/%s.sql', $platform->getName());
- file_put_contents($targetFile, implode("\n\n", $schema->toSql($platform)));
-}
diff --git a/Acl/Resources/schema/db2.sql b/Acl/Resources/schema/db2.sql
deleted file mode 100644
index 2d10c14..0000000
--- a/Acl/Resources/schema/db2.sql
+++ /dev/null
@@ -1,43 +0,0 @@
-CREATE TABLE acl_classes (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
-
-CREATE TABLE acl_security_identities (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, identifier VARCHAR(200) NOT NULL, username SMALLINT NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-
-CREATE TABLE acl_object_identities (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, parent_object_identity_id INTEGER DEFAULT NULL, class_id INTEGER NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting SMALLINT NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
-
-CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INTEGER NOT NULL, ancestor_id INTEGER NOT NULL, PRIMARY KEY(object_identity_id, ancestor_id))
-
-CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
-
-CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-
-CREATE TABLE acl_entries (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, class_id INTEGER NOT NULL, object_identity_id INTEGER DEFAULT NULL, security_identity_id INTEGER NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT NOT NULL, mask INTEGER NOT NULL, granting SMALLINT NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success SMALLINT NOT NULL, audit_failure SMALLINT NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
-
-CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
-
-CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
-
-CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
-
-CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id)
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/drizzle.sql b/Acl/Resources/schema/drizzle.sql
deleted file mode 100644
index 9398c29..0000000
--- a/Acl/Resources/schema/drizzle.sql
+++ /dev/null
@@ -1,21 +0,0 @@
-CREATE TABLE acl_classes (id INT AUTO_INCREMENT NOT NULL, class_type VARCHAR(200) NOT NULL, UNIQUE INDEX UNIQ_69DD750638A36066 (class_type), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_security_identities (id INT AUTO_INCREMENT NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 (identifier, username), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_object_identities (id INT AUTO_INCREMENT NOT NULL, parent_object_identity_id INT DEFAULT NULL, class_id INT NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 (object_identifier, class_id), INDEX IDX_9407E54977FA751A (parent_object_identity_id), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT NOT NULL, ancestor_id INT NOT NULL, INDEX IDX_825DE2993D9AB4A6 (object_identity_id), INDEX IDX_825DE299C671CEA1 (ancestor_id), PRIMARY KEY(object_identity_id, ancestor_id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_entries (id INT AUTO_INCREMENT NOT NULL, class_id INT NOT NULL, object_identity_id INT DEFAULT NULL, security_identity_id INT NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order INT NOT NULL, mask INT NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 (class_id, object_identity_id, field_name, ace_order), INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 (class_id, object_identity_id, security_identity_id), INDEX IDX_46C8B806EA000B10 (class_id), INDEX IDX_46C8B8063D9AB4A6 (object_identity_id), INDEX IDX_46C8B806DF9183C9 (security_identity_id), PRIMARY KEY(id)) COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/mssql.sql b/Acl/Resources/schema/mssql.sql
deleted file mode 100644
index 8126f78..0000000
--- a/Acl/Resources/schema/mssql.sql
+++ /dev/null
@@ -1,43 +0,0 @@
-CREATE TABLE acl_classes (id INT IDENTITY NOT NULL, class_type NVARCHAR(200) NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type) WHERE class_type IS NOT NULL
-
-CREATE TABLE acl_security_identities (id INT IDENTITY NOT NULL, identifier NVARCHAR(200) NOT NULL, username BIT NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username) WHERE identifier IS NOT NULL AND username IS NOT NULL
-
-CREATE TABLE acl_object_identities (id INT IDENTITY NOT NULL, parent_object_identity_id INT, class_id INT NOT NULL, object_identifier NVARCHAR(100) NOT NULL, entries_inheriting BIT NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id) WHERE object_identifier IS NOT NULL AND class_id IS NOT NULL
-
-CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT NOT NULL, ancestor_id INT NOT NULL, PRIMARY KEY (object_identity_id, ancestor_id))
-
-CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
-
-CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-
-CREATE TABLE acl_entries (id INT IDENTITY NOT NULL, class_id INT NOT NULL, object_identity_id INT, security_identity_id INT NOT NULL, field_name NVARCHAR(50), ace_order SMALLINT NOT NULL, mask INT NOT NULL, granting BIT NOT NULL, granting_strategy NVARCHAR(30) NOT NULL, audit_success BIT NOT NULL, audit_failure BIT NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order) WHERE class_id IS NOT NULL AND object_identity_id IS NOT NULL AND field_name IS NOT NULL AND ace_order IS NOT NULL
-
-CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
-
-CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
-
-CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
-
-CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id)
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/mysql.sql b/Acl/Resources/schema/mysql.sql
deleted file mode 100644
index 1c63f4d..0000000
--- a/Acl/Resources/schema/mysql.sql
+++ /dev/null
@@ -1,21 +0,0 @@
-CREATE TABLE acl_classes (id INT UNSIGNED AUTO_INCREMENT NOT NULL, class_type VARCHAR(200) NOT NULL, UNIQUE INDEX UNIQ_69DD750638A36066 (class_type), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_security_identities (id INT UNSIGNED AUTO_INCREMENT NOT NULL, identifier VARCHAR(200) NOT NULL, username TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 (identifier, username), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_object_identities (id INT UNSIGNED AUTO_INCREMENT NOT NULL, parent_object_identity_id INT UNSIGNED DEFAULT NULL, class_id INT UNSIGNED NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 (object_identifier, class_id), INDEX IDX_9407E54977FA751A (parent_object_identity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT UNSIGNED NOT NULL, ancestor_id INT UNSIGNED NOT NULL, INDEX IDX_825DE2993D9AB4A6 (object_identity_id), INDEX IDX_825DE299C671CEA1 (ancestor_id), PRIMARY KEY(object_identity_id, ancestor_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-CREATE TABLE acl_entries (id INT UNSIGNED AUTO_INCREMENT NOT NULL, class_id INT UNSIGNED NOT NULL, object_identity_id INT UNSIGNED DEFAULT NULL, security_identity_id INT UNSIGNED NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT UNSIGNED NOT NULL, mask INT NOT NULL, granting TINYINT(1) NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success TINYINT(1) NOT NULL, audit_failure TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 (class_id, object_identity_id, field_name, ace_order), INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 (class_id, object_identity_id, security_identity_id), INDEX IDX_46C8B806EA000B10 (class_id), INDEX IDX_46C8B8063D9AB4A6 (object_identity_id), INDEX IDX_46C8B806DF9183C9 (security_identity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/oracle.sql b/Acl/Resources/schema/oracle.sql
deleted file mode 100644
index 94821dc..0000000
--- a/Acl/Resources/schema/oracle.sql
+++ /dev/null
@@ -1,175 +0,0 @@
-CREATE TABLE acl_classes (id NUMBER(10) NOT NULL, class_type VARCHAR2(200) NOT NULL, PRIMARY KEY(id))
-
-DECLARE
- constraints_Count NUMBER;
-BEGIN
- SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_CLASSES' AND CONSTRAINT_TYPE = 'P';
- IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_CLASSES ADD CONSTRAINT ACL_CLASSES_AI_PK PRIMARY KEY (ID)';
- END IF;
-END;
-
-CREATE SEQUENCE ACL_CLASSES_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1
-
-CREATE TRIGGER ACL_CLASSES_AI_PK
- BEFORE INSERT
- ON ACL_CLASSES
- FOR EACH ROW
-DECLARE
- last_Sequence NUMBER;
- last_InsertID NUMBER;
-BEGIN
- SELECT ACL_CLASSES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
- SELECT ACL_CLASSES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- ELSE
- SELECT NVL(Last_Number, 0) INTO last_Sequence
- FROM User_Sequences
- WHERE Sequence_Name = 'ACL_CLASSES_SEQ';
- SELECT :NEW.ID INTO last_InsertID FROM DUAL;
- WHILE (last_InsertID > last_Sequence) LOOP
- SELECT ACL_CLASSES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
- END LOOP;
- END IF;
-END;
-
-CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
-
-CREATE TABLE acl_security_identities (id NUMBER(10) NOT NULL, identifier VARCHAR2(200) NOT NULL, username NUMBER(1) NOT NULL, PRIMARY KEY(id))
-
-DECLARE
- constraints_Count NUMBER;
-BEGIN
- SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_SECURITY_IDENTITIES' AND CONSTRAINT_TYPE = 'P';
- IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_SECURITY_IDENTITIES ADD CONSTRAINT ACL_SECURITY_IDENTITIES_AI_PK PRIMARY KEY (ID)';
- END IF;
-END;
-
-CREATE SEQUENCE ACL_SECURITY_IDENTITIES_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1
-
-CREATE TRIGGER ACL_SECURITY_IDENTITIES_AI_PK
- BEFORE INSERT
- ON ACL_SECURITY_IDENTITIES
- FOR EACH ROW
-DECLARE
- last_Sequence NUMBER;
- last_InsertID NUMBER;
-BEGIN
- SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
- SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- ELSE
- SELECT NVL(Last_Number, 0) INTO last_Sequence
- FROM User_Sequences
- WHERE Sequence_Name = 'ACL_SECURITY_IDENTITIES_SEQ';
- SELECT :NEW.ID INTO last_InsertID FROM DUAL;
- WHILE (last_InsertID > last_Sequence) LOOP
- SELECT ACL_SECURITY_IDENTITIES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
- END LOOP;
- END IF;
-END;
-
-CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-
-CREATE TABLE acl_object_identities (id NUMBER(10) NOT NULL, parent_object_identity_id NUMBER(10) DEFAULT NULL NULL, class_id NUMBER(10) NOT NULL, object_identifier VARCHAR2(100) NOT NULL, entries_inheriting NUMBER(1) NOT NULL, PRIMARY KEY(id))
-
-DECLARE
- constraints_Count NUMBER;
-BEGIN
- SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_OBJECT_IDENTITIES' AND CONSTRAINT_TYPE = 'P';
- IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_OBJECT_IDENTITIES ADD CONSTRAINT ACL_OBJECT_IDENTITIES_AI_PK PRIMARY KEY (ID)';
- END IF;
-END;
-
-CREATE SEQUENCE ACL_OBJECT_IDENTITIES_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1
-
-CREATE TRIGGER ACL_OBJECT_IDENTITIES_AI_PK
- BEFORE INSERT
- ON ACL_OBJECT_IDENTITIES
- FOR EACH ROW
-DECLARE
- last_Sequence NUMBER;
- last_InsertID NUMBER;
-BEGIN
- SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
- SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- ELSE
- SELECT NVL(Last_Number, 0) INTO last_Sequence
- FROM User_Sequences
- WHERE Sequence_Name = 'ACL_OBJECT_IDENTITIES_SEQ';
- SELECT :NEW.ID INTO last_InsertID FROM DUAL;
- WHILE (last_InsertID > last_Sequence) LOOP
- SELECT ACL_OBJECT_IDENTITIES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
- END LOOP;
- END IF;
-END;
-
-CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
-
-CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id NUMBER(10) NOT NULL, ancestor_id NUMBER(10) NOT NULL, PRIMARY KEY(object_identity_id, ancestor_id))
-
-CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
-
-CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-
-CREATE TABLE acl_entries (id NUMBER(10) NOT NULL, class_id NUMBER(10) NOT NULL, object_identity_id NUMBER(10) DEFAULT NULL NULL, security_identity_id NUMBER(10) NOT NULL, field_name VARCHAR2(50) DEFAULT NULL NULL, ace_order NUMBER(5) NOT NULL, mask NUMBER(10) NOT NULL, granting NUMBER(1) NOT NULL, granting_strategy VARCHAR2(30) NOT NULL, audit_success NUMBER(1) NOT NULL, audit_failure NUMBER(1) NOT NULL, PRIMARY KEY(id))
-
-DECLARE
- constraints_Count NUMBER;
-BEGIN
- SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'ACL_ENTRIES' AND CONSTRAINT_TYPE = 'P';
- IF constraints_Count = 0 OR constraints_Count = '' THEN
- EXECUTE IMMEDIATE 'ALTER TABLE ACL_ENTRIES ADD CONSTRAINT ACL_ENTRIES_AI_PK PRIMARY KEY (ID)';
- END IF;
-END;
-
-CREATE SEQUENCE ACL_ENTRIES_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1
-
-CREATE TRIGGER ACL_ENTRIES_AI_PK
- BEFORE INSERT
- ON ACL_ENTRIES
- FOR EACH ROW
-DECLARE
- last_Sequence NUMBER;
- last_InsertID NUMBER;
-BEGIN
- SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- IF (:NEW.ID IS NULL OR :NEW.ID = 0) THEN
- SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
- ELSE
- SELECT NVL(Last_Number, 0) INTO last_Sequence
- FROM User_Sequences
- WHERE Sequence_Name = 'ACL_ENTRIES_SEQ';
- SELECT :NEW.ID INTO last_InsertID FROM DUAL;
- WHILE (last_InsertID > last_Sequence) LOOP
- SELECT ACL_ENTRIES_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
- END LOOP;
- END IF;
-END;
-
-CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
-
-CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
-
-CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
-
-CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
-
-CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id)
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/postgresql.sql b/Acl/Resources/schema/postgresql.sql
deleted file mode 100644
index 05ca439..0000000
--- a/Acl/Resources/schema/postgresql.sql
+++ /dev/null
@@ -1,43 +0,0 @@
-CREATE TABLE acl_classes (id SERIAL NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
-
-CREATE TABLE acl_security_identities (id SERIAL NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-
-CREATE TABLE acl_object_identities (id SERIAL NOT NULL, parent_object_identity_id INT DEFAULT NULL, class_id INT NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
-
-CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INT NOT NULL, ancestor_id INT NOT NULL, PRIMARY KEY(object_identity_id, ancestor_id))
-
-CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
-
-CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-
-CREATE TABLE acl_entries (id SERIAL NOT NULL, class_id INT NOT NULL, object_identity_id INT DEFAULT NULL, security_identity_id INT NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT NOT NULL, mask INT NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
-
-CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
-
-CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
-
-CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
-
-CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id)
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id) NOT DEFERRABLE INITIALLY IMMEDIATE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE \ No newline at end of file
diff --git a/Acl/Resources/schema/sqlanywhere.sql b/Acl/Resources/schema/sqlanywhere.sql
deleted file mode 100644
index d73b102..0000000
--- a/Acl/Resources/schema/sqlanywhere.sql
+++ /dev/null
@@ -1,43 +0,0 @@
-CREATE TABLE acl_classes (id UNSIGNED INT IDENTITY NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
-
-CREATE TABLE acl_security_identities (id UNSIGNED INT IDENTITY NOT NULL, identifier VARCHAR(200) NOT NULL, username BIT NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-
-CREATE TABLE acl_object_identities (id UNSIGNED INT IDENTITY NOT NULL, parent_object_identity_id UNSIGNED INT DEFAULT NULL, class_id UNSIGNED INT NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BIT NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
-
-CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id UNSIGNED INT NOT NULL, ancestor_id UNSIGNED INT NOT NULL, PRIMARY KEY (object_identity_id, ancestor_id))
-
-CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
-
-CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-
-CREATE TABLE acl_entries (id UNSIGNED INT IDENTITY NOT NULL, class_id UNSIGNED INT NOT NULL, object_identity_id UNSIGNED INT DEFAULT NULL, security_identity_id UNSIGNED INT NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order UNSIGNED SMALLINT NOT NULL, mask INT NOT NULL, granting BIT NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BIT NOT NULL, audit_failure BIT NOT NULL, PRIMARY KEY (id))
-
-CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
-
-CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
-
-CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
-
-CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
-
-CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id)
-
-ALTER TABLE acl_object_identities ADD CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id)
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_object_identity_ancestors ADD CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON UPDATE CASCADE ON DELETE CASCADE
-
-ALTER TABLE acl_entries ADD CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON UPDATE CASCADE ON DELETE CASCADE \ No newline at end of file
diff --git a/Acl/Resources/schema/sqlite.sql b/Acl/Resources/schema/sqlite.sql
deleted file mode 100644
index 4429bfa..0000000
--- a/Acl/Resources/schema/sqlite.sql
+++ /dev/null
@@ -1,31 +0,0 @@
-CREATE TABLE acl_classes (id INTEGER NOT NULL, class_type VARCHAR(200) NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_69DD750638A36066 ON acl_classes (class_type)
-
-CREATE TABLE acl_security_identities (id INTEGER NOT NULL, identifier VARCHAR(200) NOT NULL, username BOOLEAN NOT NULL, PRIMARY KEY(id))
-
-CREATE UNIQUE INDEX UNIQ_8835EE78772E836AF85E0677 ON acl_security_identities (identifier, username)
-
-CREATE TABLE acl_object_identities (id INTEGER NOT NULL, parent_object_identity_id INTEGER UNSIGNED DEFAULT NULL, class_id INTEGER UNSIGNED NOT NULL, object_identifier VARCHAR(100) NOT NULL, entries_inheriting BOOLEAN NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_9407E54977FA751A FOREIGN KEY (parent_object_identity_id) REFERENCES acl_object_identities (id) NOT DEFERRABLE INITIALLY IMMEDIATE)
-
-CREATE UNIQUE INDEX UNIQ_9407E5494B12AD6EA000B10 ON acl_object_identities (object_identifier, class_id)
-
-CREATE INDEX IDX_9407E54977FA751A ON acl_object_identities (parent_object_identity_id)
-
-CREATE TABLE acl_object_identity_ancestors (object_identity_id INTEGER UNSIGNED NOT NULL, ancestor_id INTEGER UNSIGNED NOT NULL, PRIMARY KEY(object_identity_id, ancestor_id), CONSTRAINT FK_825DE2993D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_825DE299C671CEA1 FOREIGN KEY (ancestor_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)
-
-CREATE INDEX IDX_825DE2993D9AB4A6 ON acl_object_identity_ancestors (object_identity_id)
-
-CREATE INDEX IDX_825DE299C671CEA1 ON acl_object_identity_ancestors (ancestor_id)
-
-CREATE TABLE acl_entries (id INTEGER NOT NULL, class_id INTEGER UNSIGNED NOT NULL, object_identity_id INTEGER UNSIGNED DEFAULT NULL, security_identity_id INTEGER UNSIGNED NOT NULL, field_name VARCHAR(50) DEFAULT NULL, ace_order SMALLINT UNSIGNED NOT NULL, mask INTEGER NOT NULL, granting BOOLEAN NOT NULL, granting_strategy VARCHAR(30) NOT NULL, audit_success BOOLEAN NOT NULL, audit_failure BOOLEAN NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_46C8B806EA000B10 FOREIGN KEY (class_id) REFERENCES acl_classes (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_46C8B8063D9AB4A6 FOREIGN KEY (object_identity_id) REFERENCES acl_object_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_46C8B806DF9183C9 FOREIGN KEY (security_identity_id) REFERENCES acl_security_identities (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)
-
-CREATE UNIQUE INDEX UNIQ_46C8B806EA000B103D9AB4A64DEF17BCE4289BF4 ON acl_entries (class_id, object_identity_id, field_name, ace_order)
-
-CREATE INDEX IDX_46C8B806EA000B103D9AB4A6DF9183C9 ON acl_entries (class_id, object_identity_id, security_identity_id)
-
-CREATE INDEX IDX_46C8B806EA000B10 ON acl_entries (class_id)
-
-CREATE INDEX IDX_46C8B8063D9AB4A6 ON acl_entries (object_identity_id)
-
-CREATE INDEX IDX_46C8B806DF9183C9 ON acl_entries (security_identity_id) \ No newline at end of file
diff --git a/Acl/Tests/Dbal/AclProviderBenchmarkTest.php b/Acl/Tests/Dbal/AclProviderBenchmarkTest.php
deleted file mode 100644
index c95b474..0000000
--- a/Acl/Tests/Dbal/AclProviderBenchmarkTest.php
+++ /dev/null
@@ -1,267 +0,0 @@
-<?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\Tests\Dbal;
-
-use Symfony\Component\Security\Acl\Dbal\AclProvider;
-use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Acl\Dbal\Schema;
-use Doctrine\DBAL\DriverManager;
-
-/**
- * @group benchmark
- */
-class AclProviderBenchmarkTest extends \PHPUnit_Framework_TestCase
-{
- /** @var \Doctrine\DBAL\Connection */
- protected $con;
- protected $insertClassStmt;
- protected $insertSidStmt;
- protected $insertOidAncestorStmt;
- protected $insertOidStmt;
- protected $insertEntryStmt;
-
- protected function setUp()
- {
- try {
- $this->con = DriverManager::getConnection(array(
- 'driver' => 'pdo_mysql',
- 'host' => 'localhost',
- 'user' => 'root',
- 'dbname' => 'testdb',
- ));
- $this->con->connect();
- } catch (\Exception $e) {
- $this->markTestSkipped('Unable to connect to the database: '.$e->getMessage());
- }
- }
-
- protected function tearDown()
- {
- $this->con = null;
- }
-
- public function testFindAcls()
- {
- // $this->generateTestData();
-
- // get some random test object identities from the database
- $oids = array();
- $stmt = $this->con->executeQuery('SELECT object_identifier, class_type FROM acl_object_identities o INNER JOIN acl_classes c ON c.id = o.class_id ORDER BY RAND() LIMIT 25');
- foreach ($stmt->fetchAll() as $oid) {
- $oids[] = new ObjectIdentity($oid['object_identifier'], $oid['class_type']);
- }
-
- $provider = $this->getProvider();
-
- $start = microtime(true);
- $provider->findAcls($oids);
- $time = microtime(true) - $start;
- echo 'Total Time: '.$time."s\n";
- }
-
- /**
- * This generates a huge amount of test data to be used mainly for benchmarking
- * purposes, not so much for testing. That's why it's not called by default.
- */
- protected function generateTestData()
- {
- $sm = $this->con->getSchemaManager();
- $sm->dropAndCreateDatabase('testdb');
- $this->con->exec('USE testdb');
-
- // import the schema
- $schema = new Schema($options = $this->getOptions());
- foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
- $this->con->exec($sql);
- }
-
- // setup prepared statements
- $this->insertClassStmt = $this->con->prepare('INSERT INTO acl_classes (id, class_type) VALUES (?, ?)');
- $this->insertSidStmt = $this->con->prepare('INSERT INTO acl_security_identities (id, identifier, username) VALUES (?, ?, ?)');
- $this->insertOidStmt = $this->con->prepare('INSERT INTO acl_object_identities (id, class_id, object_identifier, parent_object_identity_id, entries_inheriting) VALUES (?, ?, ?, ?, ?)');
- $this->insertEntryStmt = $this->con->prepare('INSERT INTO acl_entries (id, class_id, object_identity_id, field_name, ace_order, security_identity_id, mask, granting, granting_strategy, audit_success, audit_failure) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
- $this->insertOidAncestorStmt = $this->con->prepare('INSERT INTO acl_object_identity_ancestors (object_identity_id, ancestor_id) VALUES (?, ?)');
-
- for ($i = 0; $i < 40000; ++$i) {
- $this->generateAclHierarchy();
- }
- }
-
- protected function generateAclHierarchy()
- {
- $rootId = $this->generateAcl($this->chooseClassId(), null, array());
-
- $this->generateAclLevel(rand(1, 15), $rootId, array($rootId));
- }
-
- protected function generateAclLevel($depth, $parentId, $ancestors)
- {
- $level = count($ancestors);
- for ($i = 0, $t = rand(1, 10); $i < $t; ++$i) {
- $id = $this->generateAcl($this->chooseClassId(), $parentId, $ancestors);
-
- if ($level < $depth) {
- $this->generateAclLevel($depth, $id, array_merge($ancestors, array($id)));
- }
- }
- }
-
- protected function chooseClassId()
- {
- static $id = 1000;
-
- if ($id === 1000 || ($id < 1500 && rand(0, 1))) {
- $this->insertClassStmt->execute(array($id, $this->getRandomString(rand(20, 100), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\\_')));
- ++$id;
-
- return $id - 1;
- } else {
- return rand(1000, $id - 1);
- }
- }
-
- protected function generateAcl($classId, $parentId, $ancestors)
- {
- static $id = 1000;
-
- $this->insertOidStmt->execute(array(
- $id,
- $classId,
- $this->getRandomString(rand(20, 50)),
- $parentId,
- rand(0, 1),
- ));
-
- $this->insertOidAncestorStmt->execute(array($id, $id));
- foreach ($ancestors as $ancestor) {
- $this->insertOidAncestorStmt->execute(array($id, $ancestor));
- }
-
- $this->generateAces($classId, $id);
- ++$id;
-
- return $id - 1;
- }
-
- protected function chooseSid()
- {
- static $id = 1000;
-
- if ($id === 1000 || ($id < 11000 && rand(0, 1))) {
- $this->insertSidStmt->execute(array(
- $id,
- $this->getRandomString(rand(5, 30)),
- rand(0, 1),
- ));
- ++$id;
-
- return $id - 1;
- } else {
- return rand(1000, $id - 1);
- }
- }
-
- protected function generateAces($classId, $objectId)
- {
- static $id = 1000;
-
- $sids = array();
- $fieldOrder = array();
-
- for ($i = 0; $i <= 30; ++$i) {
- $fieldName = rand(0, 1) ? null : $this->getRandomString(rand(10, 20));
-
- do {
- $sid = $this->chooseSid();
- } while (array_key_exists($sid, $sids) && in_array($fieldName, $sids[$sid], true));
-
- $fieldOrder[$fieldName] = array_key_exists($fieldName, $fieldOrder) ? $fieldOrder[$fieldName] + 1 : 0;
- if (!isset($sids[$sid])) {
- $sids[$sid] = array();
- }
- $sids[$sid][] = $fieldName;
-
- $strategy = rand(0, 2);
- if ($strategy === 0) {
- $strategy = PermissionGrantingStrategy::ALL;
- } elseif ($strategy === 1) {
- $strategy = PermissionGrantingStrategy::ANY;
- } else {
- $strategy = PermissionGrantingStrategy::EQUAL;
- }
-
- // id, cid, oid, field, order, sid, mask, granting, strategy, a success, a failure
- $this->insertEntryStmt->execute(array(
- $id,
- $classId,
- rand(0, 5) ? $objectId : null,
- $fieldName,
- $fieldOrder[$fieldName],
- $sid,
- $this->generateMask(),
- rand(0, 1),
- $strategy,
- rand(0, 1),
- rand(0, 1),
- ));
-
- ++$id;
- }
- }
-
- protected function generateMask()
- {
- $i = rand(1, 30);
- $mask = 0;
-
- while ($i <= 30) {
- $mask |= 1 << rand(0, 30);
- ++$i;
- }
-
- return $mask;
- }
-
- protected function getRandomString($length, $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
- {
- $s = '';
- $cLength = strlen($chars);
-
- while (strlen($s) < $length) {
- $s .= $chars[mt_rand(0, $cLength - 1)];
- }
-
- return $s;
- }
-
- protected function getOptions()
- {
- return array(
- 'oid_table_name' => 'acl_object_identities',
- 'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
- 'class_table_name' => 'acl_classes',
- 'sid_table_name' => 'acl_security_identities',
- 'entry_table_name' => 'acl_entries',
- );
- }
-
- protected function getStrategy()
- {
- return new PermissionGrantingStrategy();
- }
-
- protected function getProvider()
- {
- return new AclProvider($this->con, $this->getStrategy(), $this->getOptions());
- }
-}
diff --git a/Acl/Tests/Dbal/AclProviderTest.php b/Acl/Tests/Dbal/AclProviderTest.php
deleted file mode 100644
index 680c6c3..0000000
--- a/Acl/Tests/Dbal/AclProviderTest.php
+++ /dev/null
@@ -1,280 +0,0 @@
-<?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\Tests\Dbal;
-
-use Symfony\Component\Security\Acl\Dbal\AclProvider;
-use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Acl\Dbal\Schema;
-use Doctrine\DBAL\DriverManager;
-
-/**
- * @requires extension pdo_sqlite
- */
-class AclProviderTest extends \PHPUnit_Framework_TestCase
-{
- protected $con;
- protected $insertClassStmt;
- protected $insertEntryStmt;
- protected $insertOidStmt;
- protected $insertOidAncestorStmt;
- protected $insertSidStmt;
-
- /**
- * @expectedException \Symfony\Component\Security\Acl\Exception\AclNotFoundException
- * @expectedMessage There is no ACL for the given object identity.
- */
- public function testFindAclThrowsExceptionWhenNoAclExists()
- {
- $this->getProvider()->findAcl(new ObjectIdentity('foo', 'foo'));
- }
-
- public function testFindAclsThrowsExceptionUnlessAnACLIsFoundForEveryOID()
- {
- $oids = array();
- $oids[] = new ObjectIdentity('1', 'foo');
- $oids[] = new ObjectIdentity('foo', 'foo');
-
- try {
- $this->getProvider()->findAcls($oids);
-
- $this->fail('Provider did not throw an expected exception.');
- } catch (\Exception $e) {
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Exception\AclNotFoundException', $e);
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Exception\NotAllAclsFoundException', $e);
-
- $partialResult = $e->getPartialResult();
- $this->assertTrue($partialResult->contains($oids[0]));
- $this->assertFalse($partialResult->contains($oids[1]));
- }
- }
-
- public function testFindAcls()
- {
- $oids = array();
- $oids[] = new ObjectIdentity('1', 'foo');
- $oids[] = new ObjectIdentity('2', 'foo');
-
- $provider = $this->getProvider();
-
- $acls = $provider->findAcls($oids);
- $this->assertInstanceOf('SplObjectStorage', $acls);
- $this->assertCount(2, $acls);
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0]));
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1]));
- $this->assertTrue($oids[0]->equals($acl0->getObjectIdentity()));
- $this->assertTrue($oids[1]->equals($acl1->getObjectIdentity()));
- }
-
- public function testFindAclsWithDifferentTypes()
- {
- $oids = array();
- $oids[] = new ObjectIdentity('123', 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity');
- $oids[] = new ObjectIdentity('123', 'Bundle\MyBundle\Entity\AnotherEntity');
-
- $provider = $this->getProvider();
-
- $acls = $provider->findAcls($oids);
- $this->assertInstanceOf('SplObjectStorage', $acls);
- $this->assertCount(2, $acls);
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl0 = $acls->offsetGet($oids[0]));
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl1 = $acls->offsetGet($oids[1]));
- $this->assertTrue($oids[0]->equals($acl0->getObjectIdentity()));
- $this->assertTrue($oids[1]->equals($acl1->getObjectIdentity()));
- }
-
- public function testFindAclCachesAclInMemory()
- {
- $oid = new ObjectIdentity('1', 'foo');
- $provider = $this->getProvider();
-
- $acl = $provider->findAcl($oid);
- $this->assertSame($acl, $cAcl = $provider->findAcl($oid));
-
- $cAces = $cAcl->getObjectAces();
- foreach ($acl->getObjectAces() as $index => $ace) {
- $this->assertSame($ace, $cAces[$index]);
- }
- }
-
- public function testFindAcl()
- {
- $oid = new ObjectIdentity('1', 'foo');
- $provider = $this->getProvider();
-
- $acl = $provider->findAcl($oid);
-
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl);
- $this->assertTrue($oid->equals($acl->getObjectIdentity()));
- $this->assertEquals(4, $acl->getId());
- $this->assertCount(0, $acl->getClassAces());
- $this->assertCount(0, $this->getField($acl, 'classFieldAces'));
- $this->assertCount(3, $acl->getObjectAces());
- $this->assertCount(0, $this->getField($acl, 'objectFieldAces'));
-
- $aces = $acl->getObjectAces();
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Entry', $aces[0]);
- $this->assertTrue($aces[0]->isGranting());
- $this->assertTrue($aces[0]->isAuditSuccess());
- $this->assertTrue($aces[0]->isAuditFailure());
- $this->assertEquals('all', $aces[0]->getStrategy());
- $this->assertSame(2, $aces[0]->getMask());
-
- // check ACE are in correct order
- $i = 0;
- foreach ($aces as $index => $ace) {
- $this->assertEquals($i, $index);
- ++$i;
- }
-
- $sid = $aces[0]->getSecurityIdentity();
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\UserSecurityIdentity', $sid);
- $this->assertEquals('john.doe', $sid->getUsername());
- $this->assertEquals('SomeClass', $sid->getClass());
- }
-
- protected function setUp()
- {
- $this->con = DriverManager::getConnection(array(
- 'driver' => 'pdo_sqlite',
- 'memory' => true,
- ));
-
- // import the schema
- $schema = new Schema($options = $this->getOptions());
- foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
- $this->con->exec($sql);
- }
-
- // populate the schema with some test data
- $this->insertClassStmt = $this->con->prepare('INSERT INTO acl_classes (id, class_type) VALUES (?, ?)');
- foreach ($this->getClassData() as $data) {
- $this->insertClassStmt->execute($data);
- }
-
- $this->insertSidStmt = $this->con->prepare('INSERT INTO acl_security_identities (id, identifier, username) VALUES (?, ?, ?)');
- foreach ($this->getSidData() as $data) {
- $this->insertSidStmt->execute($data);
- }
-
- $this->insertOidStmt = $this->con->prepare('INSERT INTO acl_object_identities (id, class_id, object_identifier, parent_object_identity_id, entries_inheriting) VALUES (?, ?, ?, ?, ?)');
- foreach ($this->getOidData() as $data) {
- $this->insertOidStmt->execute($data);
- }
-
- $this->insertEntryStmt = $this->con->prepare('INSERT INTO acl_entries (id, class_id, object_identity_id, field_name, ace_order, security_identity_id, mask, granting, granting_strategy, audit_success, audit_failure) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
- foreach ($this->getEntryData() as $data) {
- $this->insertEntryStmt->execute($data);
- }
-
- $this->insertOidAncestorStmt = $this->con->prepare('INSERT INTO acl_object_identity_ancestors (object_identity_id, ancestor_id) VALUES (?, ?)');
- foreach ($this->getOidAncestorData() as $data) {
- $this->insertOidAncestorStmt->execute($data);
- }
- }
-
- protected function tearDown()
- {
- $this->con = null;
- }
-
- protected function getField($object, $field)
- {
- $reflection = new \ReflectionProperty($object, $field);
- $reflection->setAccessible(true);
-
- return $reflection->getValue($object);
- }
-
- protected function getEntryData()
- {
- // id, cid, oid, field, order, sid, mask, granting, strategy, a success, a failure
- return array(
- array(1, 1, 1, null, 0, 1, 1, 1, 'all', 1, 1),
- array(2, 1, 1, null, 1, 2, 1 << 2 | 1 << 1, 0, 'any', 0, 0),
- array(3, 3, 4, null, 0, 1, 2, 1, 'all', 1, 1),
- array(4, 3, 4, null, 2, 2, 1, 1, 'all', 1, 1),
- array(5, 3, 4, null, 1, 3, 1, 1, 'all', 1, 1),
- );
- }
-
- protected function getOidData()
- {
- // id, cid, oid, parent_oid, entries_inheriting
- return array(
- array(1, 1, '123', null, 1),
- array(2, 2, '123', 1, 1),
- array(3, 2, 'i:3:123', 1, 1),
- array(4, 3, '1', 2, 1),
- array(5, 3, '2', 2, 1),
- );
- }
-
- protected function getOidAncestorData()
- {
- return array(
- array(1, 1),
- array(2, 1),
- array(2, 2),
- array(3, 1),
- array(3, 3),
- array(4, 2),
- array(4, 1),
- array(4, 4),
- array(5, 2),
- array(5, 1),
- array(5, 5),
- );
- }
-
- protected function getSidData()
- {
- return array(
- array(1, 'SomeClass-john.doe', 1),
- array(2, 'MyClass-john.doe@foo.com', 1),
- array(3, 'FooClass-123', 1),
- array(4, 'MooClass-ROLE_USER', 1),
- array(5, 'ROLE_USER', 0),
- array(6, 'IS_AUTHENTICATED_FULLY', 0),
- );
- }
-
- protected function getClassData()
- {
- return array(
- array(1, 'Bundle\SomeVendor\MyBundle\Entity\SomeEntity'),
- array(2, 'Bundle\MyBundle\Entity\AnotherEntity'),
- array(3, 'foo'),
- );
- }
-
- protected function getOptions()
- {
- return array(
- 'oid_table_name' => 'acl_object_identities',
- 'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
- 'class_table_name' => 'acl_classes',
- 'sid_table_name' => 'acl_security_identities',
- 'entry_table_name' => 'acl_entries',
- );
- }
-
- protected function getStrategy()
- {
- return new PermissionGrantingStrategy();
- }
-
- protected function getProvider()
- {
- return new AclProvider($this->con, $this->getStrategy(), $this->getOptions());
- }
-}
diff --git a/Acl/Tests/Dbal/MutableAclProviderTest.php b/Acl/Tests/Dbal/MutableAclProviderTest.php
deleted file mode 100644
index c2169e4..0000000
--- a/Acl/Tests/Dbal/MutableAclProviderTest.php
+++ /dev/null
@@ -1,572 +0,0 @@
-<?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\Tests\Dbal;
-
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Model\FieldEntryInterface;
-use Symfony\Component\Security\Acl\Model\AuditableEntryInterface;
-use Symfony\Component\Security\Acl\Model\EntryInterface;
-use Symfony\Component\Security\Acl\Domain\Entry;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\Acl;
-use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
-use Symfony\Component\Security\Acl\Exception\ConcurrentModificationException;
-use Symfony\Component\Security\Acl\Dbal\AclProvider;
-use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
-use Symfony\Component\Security\Acl\Dbal\MutableAclProvider;
-use Symfony\Component\Security\Acl\Dbal\Schema;
-use Doctrine\DBAL\DriverManager;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-
-/**
- * @requires extension pdo_sqlite
- */
-class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
-{
- protected $con;
-
- public static function assertAceEquals(EntryInterface $a, EntryInterface $b)
- {
- self::assertInstanceOf(get_class($a), $b);
-
- foreach (array('getId', 'getMask', 'getStrategy', 'isGranting') as $getter) {
- self::assertSame($a->$getter(), $b->$getter());
- }
-
- self::assertTrue($a->getSecurityIdentity()->equals($b->getSecurityIdentity()));
- self::assertSame($a->getAcl()->getId(), $b->getAcl()->getId());
-
- if ($a instanceof AuditableEntryInterface) {
- self::assertSame($a->isAuditSuccess(), $b->isAuditSuccess());
- self::assertSame($a->isAuditFailure(), $b->isAuditFailure());
- }
-
- if ($a instanceof FieldEntryInterface) {
- self::assertSame($a->getField(), $b->getField());
- }
- }
-
- /**
- * @expectedException \Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException
- */
- public function testCreateAclThrowsExceptionWhenAclAlreadyExists()
- {
- $provider = $this->getProvider();
- $oid = new ObjectIdentity('123456', 'FOO');
- $provider->createAcl($oid);
- $provider->createAcl($oid);
- }
-
- public function testCreateAcl()
- {
- $provider = $this->getProvider();
- $oid = new ObjectIdentity('123456', 'FOO');
- $acl = $provider->createAcl($oid);
- $cachedAcl = $provider->findAcl($oid);
-
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Domain\Acl', $acl);
- $this->assertSame($acl, $cachedAcl);
- $this->assertTrue($acl->getObjectIdentity()->equals($oid));
- }
-
- public function testDeleteAcl()
- {
- $provider = $this->getProvider();
- $oid = new ObjectIdentity(1, 'Foo');
- $acl = $provider->createAcl($oid);
-
- $provider->deleteAcl($oid);
- $loadedAcls = $this->getField($provider, 'loadedAcls');
- $this->assertCount(0, $loadedAcls['Foo']);
-
- try {
- $provider->findAcl($oid);
- $this->fail('ACL has not been properly deleted.');
- } catch (AclNotFoundException $e) {
- }
- }
-
- public function testDeleteAclDeletesChildren()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $parentAcl = $provider->createAcl(new ObjectIdentity(2, 'Foo'));
- $acl->setParentAcl($parentAcl);
- $provider->updateAcl($acl);
- $provider->deleteAcl($parentAcl->getObjectIdentity());
-
- try {
- $provider->findAcl(new ObjectIdentity(1, 'Foo'));
- $this->fail('Child-ACLs have not been deleted.');
- } catch (AclNotFoundException $e) {
- }
- }
-
- public function testFindAclsAddsPropertyListener()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
-
- $propertyChanges = $this->getField($provider, 'propertyChanges');
- $this->assertCount(1, $propertyChanges);
- $this->assertTrue($propertyChanges->contains($acl));
- $this->assertEquals(array(), $propertyChanges->offsetGet($acl));
-
- $listeners = $this->getField($acl, 'listeners');
- $this->assertSame($provider, $listeners[0]);
- }
-
- public function testFindAclsAddsPropertyListenerOnlyOnce()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $acl = $provider->findAcl(new ObjectIdentity(1, 'Foo'));
-
- $propertyChanges = $this->getField($provider, 'propertyChanges');
- $this->assertCount(1, $propertyChanges);
- $this->assertTrue($propertyChanges->contains($acl));
- $this->assertEquals(array(), $propertyChanges->offsetGet($acl));
-
- $listeners = $this->getField($acl, 'listeners');
- $this->assertCount(1, $listeners);
- $this->assertSame($provider, $listeners[0]);
- }
-
- public function testFindAclsAddsPropertyListenerToParentAcls()
- {
- $provider = $this->getProvider();
- $this->importAcls($provider, array(
- 'main' => array(
- 'object_identifier' => '1',
- 'class_type' => 'foo',
- 'parent_acl' => 'parent',
- ),
- 'parent' => array(
- 'object_identifier' => '1',
- 'class_type' => 'anotherFoo',
- ),
- ));
-
- $propertyChanges = $this->getField($provider, 'propertyChanges');
- $this->assertCount(0, $propertyChanges);
-
- $acl = $provider->findAcl(new ObjectIdentity('1', 'foo'));
- $this->assertCount(2, $propertyChanges);
- $this->assertTrue($propertyChanges->contains($acl));
- $this->assertTrue($propertyChanges->contains($acl->getParentAcl()));
- }
-
- /**
- * @expectedException \InvalidArgumentException
- */
- public function testPropertyChangedDoesNotTrackUnmanagedAcls()
- {
- $provider = $this->getProvider();
- $acl = new Acl(1, new ObjectIdentity(1, 'foo'), new PermissionGrantingStrategy(), array(), false);
-
- $provider->propertyChanged($acl, 'classAces', array(), array('foo'));
- }
-
- public function testPropertyChangedTracksChangesToAclProperties()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $propertyChanges = $this->getField($provider, 'propertyChanges');
-
- $provider->propertyChanged($acl, 'entriesInheriting', false, true);
- $changes = $propertyChanges->offsetGet($acl);
- $this->assertTrue(isset($changes['entriesInheriting']));
- $this->assertFalse($changes['entriesInheriting'][0]);
- $this->assertTrue($changes['entriesInheriting'][1]);
-
- $provider->propertyChanged($acl, 'entriesInheriting', true, false);
- $provider->propertyChanged($acl, 'entriesInheriting', false, true);
- $provider->propertyChanged($acl, 'entriesInheriting', true, false);
- $changes = $propertyChanges->offsetGet($acl);
- $this->assertFalse(isset($changes['entriesInheriting']));
- }
-
- public function testPropertyChangedTracksChangesToAceProperties()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $ace = new Entry(1, $acl, new UserSecurityIdentity('foo', 'FooClass'), 'all', 1, true, true, true);
- $ace2 = new Entry(2, $acl, new UserSecurityIdentity('foo', 'FooClass'), 'all', 1, true, true, true);
- $propertyChanges = $this->getField($provider, 'propertyChanges');
-
- $provider->propertyChanged($ace, 'mask', 1, 3);
- $changes = $propertyChanges->offsetGet($acl);
- $this->assertTrue(isset($changes['aces']));
- $this->assertInstanceOf('\SplObjectStorage', $changes['aces']);
- $this->assertTrue($changes['aces']->contains($ace));
- $aceChanges = $changes['aces']->offsetGet($ace);
- $this->assertTrue(isset($aceChanges['mask']));
- $this->assertEquals(1, $aceChanges['mask'][0]);
- $this->assertEquals(3, $aceChanges['mask'][1]);
-
- $provider->propertyChanged($ace, 'strategy', 'all', 'any');
- $changes = $propertyChanges->offsetGet($acl);
- $this->assertTrue(isset($changes['aces']));
- $this->assertInstanceOf('\SplObjectStorage', $changes['aces']);
- $this->assertTrue($changes['aces']->contains($ace));
- $aceChanges = $changes['aces']->offsetGet($ace);
- $this->assertTrue(isset($aceChanges['mask']));
- $this->assertTrue(isset($aceChanges['strategy']));
- $this->assertEquals('all', $aceChanges['strategy'][0]);
- $this->assertEquals('any', $aceChanges['strategy'][1]);
-
- $provider->propertyChanged($ace, 'mask', 3, 1);
- $changes = $propertyChanges->offsetGet($acl);
- $aceChanges = $changes['aces']->offsetGet($ace);
- $this->assertFalse(isset($aceChanges['mask']));
- $this->assertTrue(isset($aceChanges['strategy']));
-
- $provider->propertyChanged($ace2, 'mask', 1, 3);
- $provider->propertyChanged($ace, 'strategy', 'any', 'all');
- $changes = $propertyChanges->offsetGet($acl);
- $this->assertTrue(isset($changes['aces']));
- $this->assertFalse($changes['aces']->contains($ace));
- $this->assertTrue($changes['aces']->contains($ace2));
-
- $provider->propertyChanged($ace2, 'mask', 3, 4);
- $provider->propertyChanged($ace2, 'mask', 4, 1);
- $changes = $propertyChanges->offsetGet($acl);
- $this->assertFalse(isset($changes['aces']));
- }
-
- /**
- * @expectedException \InvalidArgumentException
- */
- public function testUpdateAclDoesNotAcceptUntrackedAcls()
- {
- $provider = $this->getProvider();
- $acl = new Acl(1, new ObjectIdentity(1, 'Foo'), new PermissionGrantingStrategy(), array(), true);
- $provider->updateAcl($acl);
- }
-
- public function testUpdateDoesNothingWhenThereAreNoChanges()
- {
- $con = $this->getMock('Doctrine\DBAL\Connection', array(), array(), '', false);
- $con
- ->expects($this->never())
- ->method('beginTransaction')
- ;
- $con
- ->expects($this->never())
- ->method('executeQuery')
- ;
-
- $provider = new MutableAclProvider($con, new PermissionGrantingStrategy(), array());
- $acl = new Acl(1, new ObjectIdentity(1, 'Foo'), new PermissionGrantingStrategy(), array(), true);
- $propertyChanges = $this->getField($provider, 'propertyChanges');
- $propertyChanges->offsetSet($acl, array());
- $provider->updateAcl($acl);
- }
-
- public function testUpdateAclThrowsExceptionOnConcurrentModificationOfSharedProperties()
- {
- $provider = $this->getProvider();
- $acl1 = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $acl2 = $provider->createAcl(new ObjectIdentity(2, 'Foo'));
- $acl3 = $provider->createAcl(new ObjectIdentity(1, 'AnotherFoo'));
- $sid = new RoleSecurityIdentity('ROLE_FOO');
-
- $acl1->insertClassAce($sid, 1);
- $acl3->insertClassAce($sid, 1);
- $provider->updateAcl($acl1);
- $provider->updateAcl($acl3);
-
- $acl2->insertClassAce($sid, 16);
- $provider->updateAcl($acl2);
-
- $acl1->insertClassAce($sid, 3);
- $acl2->insertClassAce($sid, 5);
- try {
- $provider->updateAcl($acl1);
- $this->fail('Provider failed to detect a concurrent modification.');
- } catch (ConcurrentModificationException $e) {
- }
- }
-
- public function testUpdateAcl()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $sid = new UserSecurityIdentity('johannes', 'FooClass');
- $acl->setEntriesInheriting(!$acl->isEntriesInheriting());
-
- $acl->insertObjectAce($sid, 1);
- $acl->insertClassAce($sid, 5, 0, false);
- $acl->insertObjectAce($sid, 2, 1, true);
- $acl->insertClassFieldAce('field', $sid, 2, 0, true);
- $provider->updateAcl($acl);
-
- $acl->updateObjectAce(0, 3);
- $acl->deleteObjectAce(1);
- $acl->updateObjectAuditing(0, true, false);
- $acl->updateClassFieldAce(0, 'field', 15);
- $provider->updateAcl($acl);
-
- $reloadProvider = $this->getProvider();
- $reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
- $this->assertNotSame($acl, $reloadedAcl);
- $this->assertSame($acl->isEntriesInheriting(), $reloadedAcl->isEntriesInheriting());
-
- $aces = $acl->getObjectAces();
- $reloadedAces = $reloadedAcl->getObjectAces();
- $this->assertEquals(count($aces), count($reloadedAces));
- foreach ($aces as $index => $ace) {
- $this->assertAceEquals($ace, $reloadedAces[$index]);
- }
- }
-
- public function testUpdateAclWorksForChangingTheParentAcl()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $parentAcl = $provider->createAcl(new ObjectIdentity(1, 'AnotherFoo'));
- $acl->setParentAcl($parentAcl);
- $provider->updateAcl($acl);
-
- $reloadProvider = $this->getProvider();
- $reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
- $this->assertNotSame($acl, $reloadedAcl);
- $this->assertSame($parentAcl->getId(), $reloadedAcl->getParentAcl()->getId());
- }
-
- public function testUpdateAclUpdatesChildAclsCorrectly()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
-
- $parentAcl = $provider->createAcl(new ObjectIdentity(1, 'Bar'));
- $acl->setParentAcl($parentAcl);
- $provider->updateAcl($acl);
-
- $parentParentAcl = $provider->createAcl(new ObjectIdentity(1, 'Baz'));
- $parentAcl->setParentAcl($parentParentAcl);
- $provider->updateAcl($parentAcl);
-
- $newParentParentAcl = $provider->createAcl(new ObjectIdentity(2, 'Baz'));
- $parentAcl->setParentAcl($newParentParentAcl);
- $provider->updateAcl($parentAcl);
-
- $reloadProvider = $this->getProvider();
- $reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
- $this->assertEquals($newParentParentAcl->getId(), $reloadedAcl->getParentAcl()->getParentAcl()->getId());
- }
-
- public function testUpdateAclInsertingMultipleObjectFieldAcesThrowsDBConstraintViolations()
- {
- $provider = $this->getProvider();
- $oid = new ObjectIdentity(1, 'Foo');
- $sid1 = new UserSecurityIdentity('johannes', 'FooClass');
- $sid2 = new UserSecurityIdentity('guilro', 'FooClass');
- $sid3 = new UserSecurityIdentity('bmaz', 'FooClass');
- $fieldName = 'fieldName';
-
- $acl = $provider->createAcl($oid);
- $acl->insertObjectFieldAce($fieldName, $sid1, 4);
- $provider->updateAcl($acl);
-
- $acl = $provider->findAcl($oid);
- $acl->insertObjectFieldAce($fieldName, $sid2, 4);
- $provider->updateAcl($acl);
-
- $acl = $provider->findAcl($oid);
- $acl->insertObjectFieldAce($fieldName, $sid3, 4);
- $provider->updateAcl($acl);
- }
-
- public function testUpdateAclDeletingObjectFieldAcesThrowsDBConstraintViolations()
- {
- $provider = $this->getProvider();
- $oid = new ObjectIdentity(1, 'Foo');
- $sid1 = new UserSecurityIdentity('johannes', 'FooClass');
- $sid2 = new UserSecurityIdentity('guilro', 'FooClass');
- $sid3 = new UserSecurityIdentity('bmaz', 'FooClass');
- $fieldName = 'fieldName';
-
- $acl = $provider->createAcl($oid);
- $acl->insertObjectFieldAce($fieldName, $sid1, 4);
- $provider->updateAcl($acl);
-
- $acl = $provider->findAcl($oid);
- $acl->insertObjectFieldAce($fieldName, $sid2, 4);
- $provider->updateAcl($acl);
-
- $index = 0;
- $acl->deleteObjectFieldAce($index, $fieldName);
- $provider->updateAcl($acl);
-
- $acl = $provider->findAcl($oid);
- $acl->insertObjectFieldAce($fieldName, $sid3, 4);
- $provider->updateAcl($acl);
- }
-
- public function testUpdateUserSecurityIdentity()
- {
- $provider = $this->getProvider();
- $acl = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
- $sid = new UserSecurityIdentity('johannes', 'FooClass');
- $acl->setEntriesInheriting(!$acl->isEntriesInheriting());
-
- $acl->insertObjectAce($sid, 1);
- $acl->insertClassAce($sid, 5, 0, false);
- $acl->insertObjectAce($sid, 2, 1, true);
- $acl->insertClassFieldAce('field', $sid, 2, 0, true);
- $provider->updateAcl($acl);
-
- $newSid = new UserSecurityIdentity('mathieu', 'FooClass');
- $provider->updateUserSecurityIdentity($newSid, 'johannes');
-
- $reloadProvider = $this->getProvider();
- $reloadedAcl = $reloadProvider->findAcl(new ObjectIdentity(1, 'Foo'));
-
- $this->assertNotSame($acl, $reloadedAcl);
- $this->assertSame($acl->isEntriesInheriting(), $reloadedAcl->isEntriesInheriting());
-
- $aces = $acl->getObjectAces();
- $reloadedAces = $reloadedAcl->getObjectAces();
- $this->assertEquals(count($aces), count($reloadedAces));
- foreach ($reloadedAces as $ace) {
- $this->assertTrue($ace->getSecurityIdentity()->equals($newSid));
- }
- }
-
- /**
- * Imports acls.
- *
- * Data must have the following format:
- * array(
- * *name* => array(
- * 'object_identifier' => *required*
- * 'class_type' => *required*,
- * 'parent_acl' => *name (optional)*
- * ),
- * )
- *
- * @param AclProvider $provider
- * @param array $data
- *
- * @throws \InvalidArgumentException
- * @throws \Exception
- */
- protected function importAcls(AclProvider $provider, array $data)
- {
- $aclIds = $parentAcls = array();
- $con = $this->getField($provider, 'connection');
- $con->beginTransaction();
- try {
- foreach ($data as $name => $aclData) {
- if (!isset($aclData['object_identifier'], $aclData['class_type'])) {
- throw new \InvalidArgumentException('"object_identifier", and "class_type" must be present.');
- }
-
- $this->callMethod($provider, 'createObjectIdentity', array(new ObjectIdentity($aclData['object_identifier'], $aclData['class_type'])));
- $aclId = $con->lastInsertId();
- $aclIds[$name] = $aclId;
-
- $sql = $this->callMethod($provider, 'getInsertObjectIdentityRelationSql', array($aclId, $aclId));
- $con->executeQuery($sql);
-
- if (isset($aclData['parent_acl'])) {
- if (isset($aclIds[$aclData['parent_acl']])) {
- $con->executeQuery('UPDATE acl_object_identities SET parent_object_identity_id = '.$aclIds[$aclData['parent_acl']].' WHERE id = '.$aclId);
- $con->executeQuery($this->callMethod($provider, 'getInsertObjectIdentityRelationSql', array($aclId, $aclIds[$aclData['parent_acl']])));
- } else {
- $parentAcls[$aclId] = $aclData['parent_acl'];
- }
- }
- }
-
- foreach ($parentAcls as $aclId => $name) {
- if (!isset($aclIds[$name])) {
- throw new \InvalidArgumentException(sprintf('"%s" does not exist.', $name));
- }
-
- $con->executeQuery(sprintf('UPDATE acl_object_identities SET parent_object_identity_id = %d WHERE id = %d', $aclIds[$name], $aclId));
- $con->executeQuery($this->callMethod($provider, 'getInsertObjectIdentityRelationSql', array($aclId, $aclIds[$name])));
- }
-
- $con->commit();
- } catch (\Exception $e) {
- $con->rollBack();
-
- throw $e;
- }
- }
-
- protected function callMethod($object, $method, array $args)
- {
- $method = new \ReflectionMethod($object, $method);
- $method->setAccessible(true);
-
- return $method->invokeArgs($object, $args);
- }
-
- protected function setUp()
- {
- $this->con = DriverManager::getConnection(array(
- 'driver' => 'pdo_sqlite',
- 'memory' => true,
- ));
-
- // import the schema
- $schema = new Schema($this->getOptions());
- foreach ($schema->toSql($this->con->getDatabasePlatform()) as $sql) {
- $this->con->exec($sql);
- }
- }
-
- protected function tearDown()
- {
- $this->con = null;
- }
-
- protected function getField($object, $field)
- {
- $reflection = new \ReflectionProperty($object, $field);
- $reflection->setAccessible(true);
-
- return $reflection->getValue($object);
- }
-
- public function setField($object, $field, $value)
- {
- $reflection = new \ReflectionProperty($object, $field);
- $reflection->setAccessible(true);
- $reflection->setValue($object, $value);
- $reflection->setAccessible(false);
- }
-
- protected function getOptions()
- {
- return array(
- 'oid_table_name' => 'acl_object_identities',
- 'oid_ancestors_table_name' => 'acl_object_identity_ancestors',
- 'class_table_name' => 'acl_classes',
- 'sid_table_name' => 'acl_security_identities',
- 'entry_table_name' => 'acl_entries',
- );
- }
-
- protected function getStrategy()
- {
- return new PermissionGrantingStrategy();
- }
-
- protected function getProvider($cache = null)
- {
- return new MutableAclProvider($this->con, $this->getStrategy(), $this->getOptions(), $cache);
- }
-}
diff --git a/Acl/Tests/Domain/AclTest.php b/Acl/Tests/Domain/AclTest.php
deleted file mode 100644
index 84b9ba9..0000000
--- a/Acl/Tests/Domain/AclTest.php
+++ /dev/null
@@ -1,513 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Acl\Domain\Acl;
-
-class AclTest extends \PHPUnit_Framework_TestCase
-{
- public function testConstructor()
- {
- $acl = new Acl(1, $oid = new ObjectIdentity('foo', 'foo'), $permissionStrategy = new PermissionGrantingStrategy(), array(), true);
-
- $this->assertSame(1, $acl->getId());
- $this->assertSame($oid, $acl->getObjectIdentity());
- $this->assertNull($acl->getParentAcl());
- $this->assertTrue($acl->isEntriesInheriting());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- * @dataProvider getDeleteAceTests
- */
- public function testDeleteAceThrowsExceptionOnInvalidIndex($type)
- {
- $acl = $this->getAcl();
- $acl->{'delete'.$type.'Ace'}(0);
- }
-
- /**
- * @dataProvider getDeleteAceTests
- */
- public function testDeleteAce($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 1);
- $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 2, 1);
- $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 3, 2);
-
- $listener = $this->getListener(array(
- $type.'Aces', 'aceOrder', 'aceOrder', $type.'Aces',
- ));
- $acl->addPropertyChangedListener($listener);
-
- $this->assertCount(3, $acl->{'get'.$type.'Aces'}());
-
- $acl->{'delete'.$type.'Ace'}(0);
- $this->assertCount(2, $aces = $acl->{'get'.$type.'Aces'}());
- $this->assertEquals(2, $aces[0]->getMask());
- $this->assertEquals(3, $aces[1]->getMask());
-
- $acl->{'delete'.$type.'Ace'}(1);
- $this->assertCount(1, $aces = $acl->{'get'.$type.'Aces'}());
- $this->assertEquals(2, $aces[0]->getMask());
- }
-
- public function getDeleteAceTests()
- {
- return array(
- array('class'),
- array('object'),
- );
- }
-
- /**
- * @expectedException \OutOfBoundsException
- * @dataProvider getDeleteFieldAceTests
- */
- public function testDeleteFieldAceThrowsExceptionOnInvalidIndex($type)
- {
- $acl = $this->getAcl();
- $acl->{'delete'.$type.'Ace'}('foo', 0);
- }
-
- /**
- * @dataProvider getDeleteFieldAceTests
- */
- public function testDeleteFieldAce($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 1, 0);
- $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 2, 1);
- $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 3, 2);
-
- $listener = $this->getListener(array(
- $type.'Aces', 'aceOrder', 'aceOrder', $type.'Aces',
- ));
- $acl->addPropertyChangedListener($listener);
-
- $this->assertCount(3, $acl->{'get'.$type.'Aces'}('foo'));
-
- $acl->{'delete'.$type.'Ace'}(0, 'foo');
- $this->assertCount(2, $aces = $acl->{'get'.$type.'Aces'}('foo'));
- $this->assertEquals(2, $aces[0]->getMask());
- $this->assertEquals(3, $aces[1]->getMask());
-
- $acl->{'delete'.$type.'Ace'}(1, 'foo');
- $this->assertCount(1, $aces = $acl->{'get'.$type.'Aces'}('foo'));
- $this->assertEquals(2, $aces[0]->getMask());
- }
-
- public function getDeleteFieldAceTests()
- {
- return array(
- array('classField'),
- array('objectField'),
- );
- }
-
- /**
- * @dataProvider getInsertAceTests
- */
- public function testInsertAce($property, $method)
- {
- $acl = $this->getAcl();
-
- $listener = $this->getListener(array(
- $property, 'aceOrder', $property, 'aceOrder', $property,
- ));
- $acl->addPropertyChangedListener($listener);
-
- $sid = new RoleSecurityIdentity('foo');
- $acl->$method($sid, 1);
- $acl->$method($sid, 2);
- $acl->$method($sid, 3, 1, false);
-
- $this->assertCount(3, $aces = $acl->{'get'.$property}());
- $this->assertEquals(2, $aces[0]->getMask());
- $this->assertEquals(3, $aces[1]->getMask());
- $this->assertEquals(1, $aces[2]->getMask());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- * @dataProvider getInsertAceTests
- */
- public function testInsertClassAceThrowsExceptionOnInvalidIndex($property, $method)
- {
- $acl = $this->getAcl();
- $acl->$method(new RoleSecurityIdentity('foo'), 1, 1);
- }
-
- public function getInsertAceTests()
- {
- return array(
- array('classAces', 'insertClassAce'),
- array('objectAces', 'insertObjectAce'),
- );
- }
-
- /**
- * @dataProvider getInsertFieldAceTests
- */
- public function testInsertClassFieldAce($property, $method)
- {
- $acl = $this->getAcl();
-
- $listener = $this->getListener(array(
- $property, $property, 'aceOrder', $property,
- 'aceOrder', 'aceOrder', $property,
- ));
- $acl->addPropertyChangedListener($listener);
-
- $sid = new RoleSecurityIdentity('foo');
- $acl->$method('foo', $sid, 1);
- $acl->$method('foo2', $sid, 1);
- $acl->$method('foo', $sid, 3);
- $acl->$method('foo', $sid, 2);
-
- $this->assertCount(3, $aces = $acl->{'get'.$property}('foo'));
- $this->assertCount(1, $acl->{'get'.$property}('foo2'));
- $this->assertEquals(2, $aces[0]->getMask());
- $this->assertEquals(3, $aces[1]->getMask());
- $this->assertEquals(1, $aces[2]->getMask());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- * @dataProvider getInsertFieldAceTests
- */
- public function testInsertClassFieldAceThrowsExceptionOnInvalidIndex($property, $method)
- {
- $acl = $this->getAcl();
- $acl->$method('foo', new RoleSecurityIdentity('foo'), 1, 1);
- }
-
- public function getInsertFieldAceTests()
- {
- return array(
- array('classFieldAces', 'insertClassFieldAce'),
- array('objectFieldAces', 'insertObjectFieldAce'),
- );
- }
-
- public function testIsFieldGranted()
- {
- $sids = array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity('ROLE_IDDQD'));
- $masks = array(1, 2, 4);
- $strategy = $this->getMock('Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface');
- $acl = new Acl(1, new ObjectIdentity(1, 'foo'), $strategy, array(), true);
-
- $strategy
- ->expects($this->once())
- ->method('isFieldGranted')
- ->with($this->equalTo($acl), $this->equalTo('foo'), $this->equalTo($masks), $this->equalTo($sids), $this->isTrue())
- ->will($this->returnValue(true))
- ;
-
- $this->assertTrue($acl->isFieldGranted('foo', $masks, $sids, true));
- }
-
- public function testIsGranted()
- {
- $sids = array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity('ROLE_IDDQD'));
- $masks = array(1, 2, 4);
- $strategy = $this->getMock('Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface');
- $acl = new Acl(1, new ObjectIdentity(1, 'foo'), $strategy, array(), true);
-
- $strategy
- ->expects($this->once())
- ->method('isGranted')
- ->with($this->equalTo($acl), $this->equalTo($masks), $this->equalTo($sids), $this->isTrue())
- ->will($this->returnValue(true))
- ;
-
- $this->assertTrue($acl->isGranted($masks, $sids, true));
- }
-
- public function testSetGetParentAcl()
- {
- $acl = $this->getAcl();
- $parentAcl = $this->getAcl();
-
- $listener = $this->getListener(array('parentAcl'));
- $acl->addPropertyChangedListener($listener);
-
- $this->assertNull($acl->getParentAcl());
- $acl->setParentAcl($parentAcl);
- $this->assertSame($parentAcl, $acl->getParentAcl());
-
- $acl->setParentAcl(null);
- $this->assertNull($acl->getParentAcl());
- }
-
- public function testSetIsEntriesInheriting()
- {
- $acl = $this->getAcl();
-
- $listener = $this->getListener(array('entriesInheriting'));
- $acl->addPropertyChangedListener($listener);
-
- $this->assertTrue($acl->isEntriesInheriting());
- $acl->setEntriesInheriting(false);
- $this->assertFalse($acl->isEntriesInheriting());
- }
-
- public function testIsSidLoadedWhenAllSidsAreLoaded()
- {
- $acl = $this->getAcl();
-
- $this->assertTrue($acl->isSidLoaded(new UserSecurityIdentity('foo', 'Foo')));
- $this->assertTrue($acl->isSidLoaded(new RoleSecurityIdentity('ROLE_FOO', 'Foo')));
- }
-
- public function testIsSidLoaded()
- {
- $acl = new Acl(1, new ObjectIdentity('1', 'foo'), new PermissionGrantingStrategy(), array(new UserSecurityIdentity('foo', 'Foo'), new UserSecurityIdentity('johannes', 'Bar')), true);
-
- $this->assertTrue($acl->isSidLoaded(new UserSecurityIdentity('foo', 'Foo')));
- $this->assertTrue($acl->isSidLoaded(new UserSecurityIdentity('johannes', 'Bar')));
- $this->assertTrue($acl->isSidLoaded(array(
- new UserSecurityIdentity('foo', 'Foo'),
- new UserSecurityIdentity('johannes', 'Bar'),
- )));
- $this->assertFalse($acl->isSidLoaded(new RoleSecurityIdentity('ROLE_FOO')));
- $this->assertFalse($acl->isSidLoaded(new UserSecurityIdentity('schmittjoh@gmail.com', 'Moo')));
- $this->assertFalse($acl->isSidLoaded(array(
- new UserSecurityIdentity('foo', 'Foo'),
- new UserSecurityIdentity('johannes', 'Bar'),
- new RoleSecurityIdentity('ROLE_FOO'),
- )));
- }
-
- /**
- * @dataProvider getUpdateAceTests
- * @expectedException \OutOfBoundsException
- */
- public function testUpdateAceThrowsOutOfBoundsExceptionOnInvalidIndex($type)
- {
- $acl = $this->getAcl();
- $acl->{'update'.$type}(0, 1);
- }
-
- /**
- * @dataProvider getUpdateAceTests
- */
- public function testUpdateAce($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type}(new RoleSecurityIdentity('foo'), 1);
-
- $listener = $this->getListener(array(
- 'mask', 'mask', 'strategy',
- ));
- $acl->addPropertyChangedListener($listener);
-
- $aces = $acl->{'get'.$type.'s'}();
- $ace = reset($aces);
- $this->assertEquals(1, $ace->getMask());
- $this->assertEquals('all', $ace->getStrategy());
-
- $acl->{'update'.$type}(0, 3);
- $this->assertEquals(3, $ace->getMask());
- $this->assertEquals('all', $ace->getStrategy());
-
- $acl->{'update'.$type}(0, 1, 'foo');
- $this->assertEquals(1, $ace->getMask());
- $this->assertEquals('foo', $ace->getStrategy());
- }
-
- public function getUpdateAceTests()
- {
- return array(
- array('classAce'),
- array('objectAce'),
- );
- }
-
- /**
- * @dataProvider getUpdateFieldAceTests
- * @expectedException \OutOfBoundsException
- */
- public function testUpdateFieldAceThrowsExceptionOnInvalidIndex($type)
- {
- $acl = $this->getAcl();
- $acl->{'update'.$type}(0, 'foo', 1);
- }
-
- /**
- * @dataProvider getUpdateFieldAceTests
- */
- public function testUpdateFieldAce($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type}('foo', new UserSecurityIdentity('foo', 'Foo'), 1);
-
- $listener = $this->getListener(array(
- 'mask', 'mask', 'strategy',
- ));
- $acl->addPropertyChangedListener($listener);
-
- $aces = $acl->{'get'.$type.'s'}('foo');
- $ace = reset($aces);
- $this->assertEquals(1, $ace->getMask());
- $this->assertEquals('all', $ace->getStrategy());
-
- $acl->{'update'.$type}(0, 'foo', 3);
- $this->assertEquals(3, $ace->getMask());
- $this->assertEquals('all', $ace->getStrategy());
-
- $acl->{'update'.$type}(0, 'foo', 1, 'foo');
- $this->assertEquals(1, $ace->getMask());
- $this->assertEquals('foo', $ace->getStrategy());
- }
-
- public function getUpdateFieldAceTests()
- {
- return array(
- array('classFieldAce'),
- array('objectFieldAce'),
- );
- }
-
- /**
- * @dataProvider getUpdateAuditingTests
- * @expectedException \OutOfBoundsException
- */
- public function testUpdateAuditingThrowsExceptionOnInvalidIndex($type)
- {
- $acl = $this->getAcl();
- $acl->{'update'.$type.'Auditing'}(0, true, false);
- }
-
- /**
- * @dataProvider getUpdateAuditingTests
- */
- public function testUpdateAuditing($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type.'Ace'}(new RoleSecurityIdentity('foo'), 1);
-
- $listener = $this->getListener(array(
- 'auditFailure', 'auditSuccess', 'auditFailure',
- ));
- $acl->addPropertyChangedListener($listener);
-
- $aces = $acl->{'get'.$type.'Aces'}();
- $ace = reset($aces);
- $this->assertFalse($ace->isAuditSuccess());
- $this->assertFalse($ace->isAuditFailure());
-
- $acl->{'update'.$type.'Auditing'}(0, false, true);
- $this->assertFalse($ace->isAuditSuccess());
- $this->assertTrue($ace->isAuditFailure());
-
- $acl->{'update'.$type.'Auditing'}(0, true, false);
- $this->assertTrue($ace->isAuditSuccess());
- $this->assertFalse($ace->isAuditFailure());
- }
-
- public function getUpdateAuditingTests()
- {
- return array(
- array('class'),
- array('object'),
- );
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @dataProvider getUpdateFieldAuditingTests
- */
- public function testUpdateFieldAuditingThrowsExceptionOnInvalidField($type)
- {
- $acl = $this->getAcl();
- $acl->{'update'.$type.'Auditing'}(0, 'foo', true, true);
- }
-
- /**
- * @expectedException \OutOfBoundsException
- * @dataProvider getUpdateFieldAuditingTests
- */
- public function testUpdateFieldAuditingThrowsExceptionOnInvalidIndex($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 1);
- $acl->{'update'.$type.'Auditing'}(1, 'foo', true, false);
- }
-
- /**
- * @dataProvider getUpdateFieldAuditingTests
- */
- public function testUpdateFieldAuditing($type)
- {
- $acl = $this->getAcl();
- $acl->{'insert'.$type.'Ace'}('foo', new RoleSecurityIdentity('foo'), 1);
-
- $listener = $this->getListener(array(
- 'auditSuccess', 'auditSuccess', 'auditFailure',
- ));
- $acl->addPropertyChangedListener($listener);
-
- $aces = $acl->{'get'.$type.'Aces'}('foo');
- $ace = reset($aces);
- $this->assertFalse($ace->isAuditSuccess());
- $this->assertFalse($ace->isAuditFailure());
-
- $acl->{'update'.$type.'Auditing'}(0, 'foo', true, false);
- $this->assertTrue($ace->isAuditSuccess());
- $this->assertFalse($ace->isAuditFailure());
-
- $acl->{'update'.$type.'Auditing'}(0, 'foo', false, true);
- $this->assertFalse($ace->isAuditSuccess());
- $this->assertTrue($ace->isAuditFailure());
- }
-
- public function getUpdateFieldAuditingTests()
- {
- return array(
- array('classField'),
- array('objectField'),
- );
- }
-
- protected function getListener($expectedChanges)
- {
- $aceProperties = array('aceOrder', 'mask', 'strategy', 'auditSuccess', 'auditFailure');
-
- $listener = $this->getMock('Doctrine\Common\PropertyChangedListener');
- foreach ($expectedChanges as $index => $property) {
- if (in_array($property, $aceProperties)) {
- $class = 'Symfony\Component\Security\Acl\Domain\Entry';
- } else {
- $class = 'Symfony\Component\Security\Acl\Domain\Acl';
- }
-
- $listener
- ->expects($this->at($index))
- ->method('propertyChanged')
- ->with($this->isInstanceOf($class), $this->equalTo($property))
- ;
- }
-
- return $listener;
- }
-
- protected function getAcl()
- {
- return new Acl(1, new ObjectIdentity(1, 'foo'), new PermissionGrantingStrategy(), array(), true);
- }
-}
diff --git a/Acl/Tests/Domain/AuditLoggerTest.php b/Acl/Tests/Domain/AuditLoggerTest.php
deleted file mode 100644
index 15538d3..0000000
--- a/Acl/Tests/Domain/AuditLoggerTest.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?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\Tests\Domain;
-
-class AuditLoggerTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @dataProvider getTestLogData
- */
- public function testLogIfNeeded($granting, $audit)
- {
- $logger = $this->getLogger();
- $ace = $this->getEntry();
-
- if (true === $granting) {
- $ace
- ->expects($this->once())
- ->method('isAuditSuccess')
- ->will($this->returnValue($audit))
- ;
-
- $ace
- ->expects($this->never())
- ->method('isAuditFailure')
- ;
- } else {
- $ace
- ->expects($this->never())
- ->method('isAuditSuccess')
- ;
-
- $ace
- ->expects($this->once())
- ->method('isAuditFailure')
- ->will($this->returnValue($audit))
- ;
- }
-
- if (true === $audit) {
- $logger
- ->expects($this->once())
- ->method('doLog')
- ->with($this->equalTo($granting), $this->equalTo($ace))
- ;
- } else {
- $logger
- ->expects($this->never())
- ->method('doLog')
- ;
- }
-
- $logger->logIfNeeded($granting, $ace);
- }
-
- public function getTestLogData()
- {
- return array(
- array(true, false),
- array(true, true),
- array(false, false),
- array(false, true),
- );
- }
-
- protected function getEntry()
- {
- return $this->getMock('Symfony\Component\Security\Acl\Model\AuditableEntryInterface');
- }
-
- protected function getLogger()
- {
- return $this->getMockForAbstractClass('Symfony\Component\Security\Acl\Domain\AuditLogger');
- }
-}
diff --git a/Acl/Tests/Domain/DoctrineAclCacheTest.php b/Acl/Tests/Domain/DoctrineAclCacheTest.php
deleted file mode 100644
index 255f7f4..0000000
--- a/Acl/Tests/Domain/DoctrineAclCacheTest.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
-use Symfony\Component\Security\Acl\Domain\Acl;
-use Symfony\Component\Security\Acl\Domain\DoctrineAclCache;
-use Doctrine\Common\Cache\ArrayCache;
-
-class DoctrineAclCacheTest extends \PHPUnit_Framework_TestCase
-{
- protected $permissionGrantingStrategy;
-
- /**
- * @expectedException \InvalidArgumentException
- * @dataProvider getEmptyValue
- */
- public function testConstructorDoesNotAcceptEmptyPrefix($empty)
- {
- new DoctrineAclCache(new ArrayCache(), $this->getPermissionGrantingStrategy(), $empty);
- }
-
- public function getEmptyValue()
- {
- return array(
- array(null),
- array(false),
- array(''),
- );
- }
-
- public function test()
- {
- $cache = $this->getCache();
-
- $aclWithParent = $this->getAcl(1);
- $acl = $this->getAcl();
-
- $cache->putInCache($aclWithParent);
- $cache->putInCache($acl);
-
- $cachedAcl = $cache->getFromCacheByIdentity($acl->getObjectIdentity());
- $this->assertEquals($acl->getId(), $cachedAcl->getId());
- $this->assertNull($acl->getParentAcl());
-
- $cachedAclWithParent = $cache->getFromCacheByIdentity($aclWithParent->getObjectIdentity());
- $this->assertEquals($aclWithParent->getId(), $cachedAclWithParent->getId());
- $this->assertNotNull($cachedParentAcl = $cachedAclWithParent->getParentAcl());
- $this->assertEquals($aclWithParent->getParentAcl()->getId(), $cachedParentAcl->getId());
- }
-
- protected function getAcl($depth = 0)
- {
- static $id = 1;
-
- $acl = new Acl($id, new ObjectIdentity($id, 'foo'), $this->getPermissionGrantingStrategy(), array(), $depth > 0);
-
- // insert some ACEs
- $sid = new UserSecurityIdentity('johannes', 'Foo');
- $acl->insertClassAce($sid, 1);
- $acl->insertClassFieldAce('foo', $sid, 1);
- $acl->insertObjectAce($sid, 1);
- $acl->insertObjectFieldAce('foo', $sid, 1);
- ++$id;
-
- if ($depth > 0) {
- $acl->setParentAcl($this->getAcl($depth - 1));
- }
-
- return $acl;
- }
-
- protected function getPermissionGrantingStrategy()
- {
- if (null === $this->permissionGrantingStrategy) {
- $this->permissionGrantingStrategy = new PermissionGrantingStrategy();
- }
-
- return $this->permissionGrantingStrategy;
- }
-
- protected function getCache($cacheDriver = null, $prefix = DoctrineAclCache::PREFIX)
- {
- if (null === $cacheDriver) {
- $cacheDriver = new ArrayCache();
- }
-
- return new DoctrineAclCache($cacheDriver, $this->getPermissionGrantingStrategy(), $prefix);
- }
-}
diff --git a/Acl/Tests/Domain/EntryTest.php b/Acl/Tests/Domain/EntryTest.php
deleted file mode 100644
index ab8e481..0000000
--- a/Acl/Tests/Domain/EntryTest.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\Entry;
-
-class EntryTest extends \PHPUnit_Framework_TestCase
-{
- public function testConstructor()
- {
- $ace = $this->getAce($acl = $this->getAcl(), $sid = $this->getSid());
-
- $this->assertEquals(123, $ace->getId());
- $this->assertSame($acl, $ace->getAcl());
- $this->assertSame($sid, $ace->getSecurityIdentity());
- $this->assertEquals('foostrat', $ace->getStrategy());
- $this->assertEquals(123456, $ace->getMask());
- $this->assertTrue($ace->isGranting());
- $this->assertTrue($ace->isAuditSuccess());
- $this->assertFalse($ace->isAuditFailure());
- }
-
- public function testSetAuditSuccess()
- {
- $ace = $this->getAce();
-
- $this->assertTrue($ace->isAuditSuccess());
- $ace->setAuditSuccess(false);
- $this->assertFalse($ace->isAuditSuccess());
- $ace->setAuditSuccess(true);
- $this->assertTrue($ace->isAuditSuccess());
- }
-
- public function testSetAuditFailure()
- {
- $ace = $this->getAce();
-
- $this->assertFalse($ace->isAuditFailure());
- $ace->setAuditFailure(true);
- $this->assertTrue($ace->isAuditFailure());
- $ace->setAuditFailure(false);
- $this->assertFalse($ace->isAuditFailure());
- }
-
- public function testSetMask()
- {
- $ace = $this->getAce();
-
- $this->assertEquals(123456, $ace->getMask());
- $ace->setMask(4321);
- $this->assertEquals(4321, $ace->getMask());
- }
-
- public function testSetStrategy()
- {
- $ace = $this->getAce();
-
- $this->assertEquals('foostrat', $ace->getStrategy());
- $ace->setStrategy('foo');
- $this->assertEquals('foo', $ace->getStrategy());
- }
-
- public function testSerializeUnserialize()
- {
- $ace = $this->getAce();
-
- $serialized = serialize($ace);
- $uAce = unserialize($serialized);
-
- $this->assertNull($uAce->getAcl());
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface', $uAce->getSecurityIdentity());
- $this->assertEquals($ace->getId(), $uAce->getId());
- $this->assertEquals($ace->getMask(), $uAce->getMask());
- $this->assertEquals($ace->getStrategy(), $uAce->getStrategy());
- $this->assertEquals($ace->isGranting(), $uAce->isGranting());
- $this->assertEquals($ace->isAuditSuccess(), $uAce->isAuditSuccess());
- $this->assertEquals($ace->isAuditFailure(), $uAce->isAuditFailure());
- }
-
- protected function getAce($acl = null, $sid = null)
- {
- if (null === $acl) {
- $acl = $this->getAcl();
- }
- if (null === $sid) {
- $sid = $this->getSid();
- }
-
- return new Entry(
- 123,
- $acl,
- $sid,
- 'foostrat',
- 123456,
- true,
- false,
- true
- );
- }
-
- protected function getAcl()
- {
- return $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface');
- }
-
- protected function getSid()
- {
- return $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface');
- }
-}
diff --git a/Acl/Tests/Domain/FieldEntryTest.php b/Acl/Tests/Domain/FieldEntryTest.php
deleted file mode 100644
index 735e2e8..0000000
--- a/Acl/Tests/Domain/FieldEntryTest.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\FieldEntry;
-
-class FieldEntryTest extends \PHPUnit_Framework_TestCase
-{
- public function testConstructor()
- {
- $ace = $this->getAce();
-
- $this->assertEquals('foo', $ace->getField());
- }
-
- public function testSerializeUnserialize()
- {
- $ace = $this->getAce();
-
- $serialized = serialize($ace);
- $uAce = unserialize($serialized);
-
- $this->assertNull($uAce->getAcl());
- $this->assertInstanceOf('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface', $uAce->getSecurityIdentity());
- $this->assertEquals($ace->getId(), $uAce->getId());
- $this->assertEquals($ace->getField(), $uAce->getField());
- $this->assertEquals($ace->getMask(), $uAce->getMask());
- $this->assertEquals($ace->getStrategy(), $uAce->getStrategy());
- $this->assertEquals($ace->isGranting(), $uAce->isGranting());
- $this->assertEquals($ace->isAuditSuccess(), $uAce->isAuditSuccess());
- $this->assertEquals($ace->isAuditFailure(), $uAce->isAuditFailure());
- }
-
- protected function getAce($acl = null, $sid = null)
- {
- if (null === $acl) {
- $acl = $this->getAcl();
- }
- if (null === $sid) {
- $sid = $this->getSid();
- }
-
- return new FieldEntry(
- 123,
- $acl,
- 'foo',
- $sid,
- 'foostrat',
- 123456,
- true,
- false,
- true
- );
- }
-
- protected function getAcl()
- {
- return $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface');
- }
-
- protected function getSid()
- {
- return $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityInterface');
- }
-}
diff --git a/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php b/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php
deleted file mode 100644
index 59fc3bd..0000000
--- a/Acl/Tests/Domain/ObjectIdentityRetrievalStrategyTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\ObjectIdentityRetrievalStrategy;
-
-class ObjectIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
-{
- public function testGetObjectIdentityReturnsNullForInvalidDomainObject()
- {
- $strategy = new ObjectIdentityRetrievalStrategy();
- $this->assertNull($strategy->getObjectIdentity('foo'));
- }
-
- public function testGetObjectIdentity()
- {
- $strategy = new ObjectIdentityRetrievalStrategy();
- $domainObject = new DomainObject();
- $objectIdentity = $strategy->getObjectIdentity($domainObject);
-
- $this->assertEquals($domainObject->getId(), $objectIdentity->getIdentifier());
- $this->assertEquals(get_class($domainObject), $objectIdentity->getType());
- }
-}
-
-class DomainObject
-{
- public function getId()
- {
- return 'foo';
- }
-}
diff --git a/Acl/Tests/Domain/ObjectIdentityTest.php b/Acl/Tests/Domain/ObjectIdentityTest.php
deleted file mode 100644
index 770ada7..0000000
--- a/Acl/Tests/Domain/ObjectIdentityTest.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?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\Tests\Domain
-{
- use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
- use Symfony\Component\Security\Acl\Model\DomainObjectInterface;
-
- class ObjectIdentityTest extends \PHPUnit_Framework_TestCase
- {
- public function testConstructor()
- {
- $id = new ObjectIdentity('fooid', 'footype');
-
- $this->assertEquals('fooid', $id->getIdentifier());
- $this->assertEquals('footype', $id->getType());
- }
-
- // Test that constructor never changes passed type, even with proxies
- public function testConstructorWithProxy()
- {
- $id = new ObjectIdentity('fooid', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject');
-
- $this->assertEquals('fooid', $id->getIdentifier());
- $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
- }
-
- public function testFromDomainObjectPrefersInterfaceOverGetId()
- {
- $domainObject = new DomainObjectImplementation();
-
- $id = ObjectIdentity::fromDomainObject($domainObject);
- $this->assertEquals('getObjectIdentifier()', $id->getIdentifier());
- }
-
- public function testFromDomainObjectWithoutInterface()
- {
- $id = ObjectIdentity::fromDomainObject(new TestDomainObject());
- $this->assertEquals('getId()', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
- }
-
- public function testFromDomainObjectWithProxy()
- {
- $id = ObjectIdentity::fromDomainObject(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject());
- $this->assertEquals('getId()', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
- }
-
- public function testFromDomainObjectWithoutInterfaceEnforcesStringIdentifier()
- {
- $domainObject = new TestDomainObject();
- $domainObject->id = 1;
- $id = ObjectIdentity::fromDomainObject($domainObject);
-
- $this->assertSame('1', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
- }
-
- public function testFromDomainObjectWithoutInterfaceAllowsZeroAsIdentifier()
- {
- $domainObject = new TestDomainObject();
- $domainObject->id = '0';
- $id = ObjectIdentity::fromDomainObject($domainObject);
-
- $this->assertSame('0', $id->getIdentifier());
- $this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
- }
-
- /**
- * @dataProvider getCompareData
- */
- public function testEquals($oid1, $oid2, $equal)
- {
- if ($equal) {
- $this->assertTrue($oid1->equals($oid2));
- } else {
- $this->assertFalse($oid1->equals($oid2));
- }
- }
-
- public function getCompareData()
- {
- return array(
- array(new ObjectIdentity('123', 'foo'), new ObjectIdentity('123', 'foo'), true),
- array(new ObjectIdentity('123', 'foo'), new ObjectIdentity(123, 'foo'), true),
- array(new ObjectIdentity('1', 'foo'), new ObjectIdentity('2', 'foo'), false),
- array(new ObjectIdentity('1', 'bla'), new ObjectIdentity('1', 'blub'), false),
- );
- }
- }
-
- class TestDomainObject
- {
- public $id = 'getId()';
-
- public function getObjectIdentifier()
- {
- return 'getObjectIdentifier()';
- }
-
- public function getId()
- {
- return $this->id;
- }
- }
-
- class DomainObjectImplementation implements DomainObjectInterface
- {
- public function getObjectIdentifier()
- {
- return 'getObjectIdentifier()';
- }
-
- public function getId()
- {
- return 'getId()';
- }
- }
-}
-
-namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain
-{
- class TestDomainObject extends \Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject
- {
- }
-}
diff --git a/Acl/Tests/Domain/PermissionGrantingStrategyTest.php b/Acl/Tests/Domain/PermissionGrantingStrategyTest.php
deleted file mode 100644
index 34ef690..0000000
--- a/Acl/Tests/Domain/PermissionGrantingStrategyTest.php
+++ /dev/null
@@ -1,186 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\Acl;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy;
-use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
-
-class PermissionGrantingStrategyTest extends \PHPUnit_Framework_TestCase
-{
- public function testIsGrantedObjectAcesHavePriority()
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $acl->insertClassAce($sid, 1);
- $acl->insertObjectAce($sid, 1, 0, false);
- $this->assertFalse($strategy->isGranted($acl, array(1), array($sid)));
- }
-
- public function testIsGrantedFallsBackToClassAcesIfNoApplicableObjectAceWasFound()
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $acl->insertClassAce($sid, 1);
- $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
- }
-
- public function testIsGrantedFavorsLocalAcesOverParentAclAces()
- {
- $strategy = new PermissionGrantingStrategy();
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $acl = $this->getAcl($strategy);
- $acl->insertClassAce($sid, 1);
-
- $parentAcl = $this->getAcl($strategy);
- $acl->setParentAcl($parentAcl);
- $parentAcl->insertClassAce($sid, 1, 0, false);
-
- $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
- }
-
- public function testIsGrantedFallsBackToParentAcesIfNoLocalAcesAreApplicable()
- {
- $strategy = new PermissionGrantingStrategy();
- $sid = new UserSecurityIdentity('johannes', 'Foo');
- $anotherSid = new UserSecurityIdentity('ROLE_USER', 'Foo');
-
- $acl = $this->getAcl($strategy);
- $acl->insertClassAce($anotherSid, 1, 0, false);
-
- $parentAcl = $this->getAcl($strategy);
- $acl->setParentAcl($parentAcl);
- $parentAcl->insertClassAce($sid, 1);
-
- $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
- }
-
- /**
- * @expectedException \Symfony\Component\Security\Acl\Exception\NoAceFoundException
- */
- public function testIsGrantedReturnsExceptionIfNoAceIsFound()
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $strategy->isGranted($acl, array(1), array($sid));
- }
-
- public function testIsGrantedFirstApplicableEntryMakesUltimateDecisionForPermissionIdentityCombination()
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
- $aSid = new RoleSecurityIdentity('ROLE_USER');
-
- $acl->insertClassAce($aSid, 1);
- $acl->insertClassAce($sid, 1, 1, false);
- $acl->insertClassAce($sid, 1, 2);
- $this->assertFalse($strategy->isGranted($acl, array(1), array($sid, $aSid)));
-
- $acl->insertObjectAce($sid, 1, 0, false);
- $acl->insertObjectAce($aSid, 1, 1);
- $this->assertFalse($strategy->isGranted($acl, array(1), array($sid, $aSid)));
- }
-
- public function testIsGrantedCallsAuditLoggerOnGrant()
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $logger = $this->getMock('Symfony\Component\Security\Acl\Model\AuditLoggerInterface');
- $logger
- ->expects($this->once())
- ->method('logIfNeeded')
- ;
- $strategy->setAuditLogger($logger);
-
- $acl->insertObjectAce($sid, 1);
- $acl->updateObjectAuditing(0, true, false);
-
- $this->assertTrue($strategy->isGranted($acl, array(1), array($sid)));
- }
-
- public function testIsGrantedCallsAuditLoggerOnDeny()
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $logger = $this->getMock('Symfony\Component\Security\Acl\Model\AuditLoggerInterface');
- $logger
- ->expects($this->once())
- ->method('logIfNeeded')
- ;
- $strategy->setAuditLogger($logger);
-
- $acl->insertObjectAce($sid, 1, 0, false);
- $acl->updateObjectAuditing(0, false, true);
-
- $this->assertFalse($strategy->isGranted($acl, array(1), array($sid)));
- }
-
- /**
- * @dataProvider getAllStrategyTests
- */
- public function testIsGrantedStrategies($maskStrategy, $aceMask, $requiredMask, $result)
- {
- $strategy = new PermissionGrantingStrategy();
- $acl = $this->getAcl($strategy);
- $sid = new UserSecurityIdentity('johannes', 'Foo');
-
- $acl->insertObjectAce($sid, $aceMask, 0, true, $maskStrategy);
-
- if (false === $result) {
- try {
- $strategy->isGranted($acl, array($requiredMask), array($sid));
- $this->fail('The ACE is not supposed to match.');
- } catch (NoAceFoundException $e) {
- }
- } else {
- $this->assertTrue($strategy->isGranted($acl, array($requiredMask), array($sid)));
- }
- }
-
- public function getAllStrategyTests()
- {
- return array(
- array('all', 1 << 0 | 1 << 1, 1 << 0, true),
- array('all', 1 << 0 | 1 << 1, 1 << 2, false),
- array('all', 1 << 0 | 1 << 10, 1 << 0 | 1 << 10, true),
- array('all', 1 << 0 | 1 << 1, 1 << 0 | 1 << 1 || 1 << 2, false),
- array('any', 1 << 0 | 1 << 1, 1 << 0, true),
- array('any', 1 << 0 | 1 << 1, 1 << 0 | 1 << 2, true),
- array('any', 1 << 0 | 1 << 1, 1 << 2, false),
- array('equal', 1 << 0 | 1 << 1, 1 << 0, false),
- array('equal', 1 << 0 | 1 << 1, 1 << 1, false),
- array('equal', 1 << 0 | 1 << 1, 1 << 0 | 1 << 1, true),
- );
- }
-
- protected function getAcl($strategy)
- {
- static $id = 1;
-
- return new Acl($id++, new ObjectIdentity(1, 'Foo'), $strategy, array(), true);
- }
-}
diff --git a/Acl/Tests/Domain/RoleSecurityIdentityTest.php b/Acl/Tests/Domain/RoleSecurityIdentityTest.php
deleted file mode 100644
index ad5f236..0000000
--- a/Acl/Tests/Domain/RoleSecurityIdentityTest.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Core\Role\Role;
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-
-class RoleSecurityIdentityTest extends \PHPUnit_Framework_TestCase
-{
- public function testConstructor()
- {
- $id = new RoleSecurityIdentity('ROLE_FOO');
-
- $this->assertEquals('ROLE_FOO', $id->getRole());
- }
-
- public function testConstructorWithRoleInstance()
- {
- $id = new RoleSecurityIdentity(new Role('ROLE_FOO'));
-
- $this->assertEquals('ROLE_FOO', $id->getRole());
- }
-
- /**
- * @dataProvider getCompareData
- */
- public function testEquals($id1, $id2, $equal)
- {
- if ($equal) {
- $this->assertTrue($id1->equals($id2));
- } else {
- $this->assertFalse($id1->equals($id2));
- }
- }
-
- public function getCompareData()
- {
- return array(
- array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity('ROLE_FOO'), true),
- array(new RoleSecurityIdentity('ROLE_FOO'), new RoleSecurityIdentity(new Role('ROLE_FOO')), true),
- array(new RoleSecurityIdentity('ROLE_USER'), new RoleSecurityIdentity('ROLE_FOO'), false),
- array(new RoleSecurityIdentity('ROLE_FOO'), new UserSecurityIdentity('ROLE_FOO', 'Foo'), false),
- );
- }
-}
diff --git a/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php b/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php
deleted file mode 100644
index 160c27c..0000000
--- a/Acl/Tests/Domain/SecurityIdentityRetrievalStrategyTest.php
+++ /dev/null
@@ -1,196 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\SecurityIdentityRetrievalStrategy;
-
-class SecurityIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @dataProvider getSecurityIdentityRetrievalTests
- */
- public function testGetSecurityIdentities($user, array $roles, $authenticationStatus, array $sids)
- {
- $strategy = $this->getStrategy($roles, $authenticationStatus);
-
- if ('anonymous' === $authenticationStatus) {
- $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken')
- ->disableOriginalConstructor()
- ->getMock();
- } else {
- $class = '';
- if (is_string($user)) {
- $class = 'MyCustomTokenImpl';
- }
-
- $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')
- ->setMockClassName($class)
- ->getMock();
- }
- $token
- ->expects($this->once())
- ->method('getRoles')
- ->will($this->returnValue(array('foo')))
- ;
- if ('anonymous' === $authenticationStatus) {
- $token
- ->expects($this->never())
- ->method('getUser')
- ;
- } else {
- $token
- ->expects($this->once())
- ->method('getUser')
- ->will($this->returnValue($user))
- ;
- }
-
- $extractedSids = $strategy->getSecurityIdentities($token);
-
- foreach ($extractedSids as $index => $extractedSid) {
- if (!isset($sids[$index])) {
- $this->fail(sprintf('Expected SID at index %d, but there was none.', true));
- }
-
- if (false === $sids[$index]->equals($extractedSid)) {
- $this->fail(sprintf('Index: %d, expected SID "%s", but got "%s".', $index, $sids[$index], $extractedSid));
- }
- }
- }
-
- public function getSecurityIdentityRetrievalTests()
- {
- return array(
- array($this->getAccount('johannes', 'FooUser'), array('ROLE_USER', 'ROLE_SUPERADMIN'), 'fullFledged', array(
- new UserSecurityIdentity('johannes', 'FooUser'),
- new RoleSecurityIdentity('ROLE_USER'),
- new RoleSecurityIdentity('ROLE_SUPERADMIN'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
- )),
- array('johannes', array('ROLE_FOO'), 'fullFledged', array(
- new UserSecurityIdentity('johannes', 'MyCustomTokenImpl'),
- new RoleSecurityIdentity('ROLE_FOO'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
- )),
- array(new CustomUserImpl('johannes'), array('ROLE_FOO'), 'fullFledged', array(
- new UserSecurityIdentity('johannes', 'Symfony\Component\Security\Acl\Tests\Domain\CustomUserImpl'),
- new RoleSecurityIdentity('ROLE_FOO'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_FULLY'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
- )),
- array($this->getAccount('foo', 'FooBarUser'), array('ROLE_FOO'), 'rememberMe', array(
- new UserSecurityIdentity('foo', 'FooBarUser'),
- new RoleSecurityIdentity('ROLE_FOO'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_REMEMBERED'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
- )),
- array('guest', array('ROLE_FOO'), 'anonymous', array(
- new RoleSecurityIdentity('ROLE_FOO'),
- new RoleSecurityIdentity('IS_AUTHENTICATED_ANONYMOUSLY'),
- )),
- );
- }
-
- protected function getAccount($username, $class)
- {
- $account = $this->getMock('Symfony\Component\Security\Core\User\UserInterface', array(), array(), $class);
- $account
- ->expects($this->any())
- ->method('getUsername')
- ->will($this->returnValue($username))
- ;
-
- return $account;
- }
-
- protected function getStrategy(array $roles = array(), $authenticationStatus = 'fullFledged')
- {
- $roleHierarchy = $this->getMock('Symfony\Component\Security\Core\Role\RoleHierarchyInterface');
- $roleHierarchy
- ->expects($this->once())
- ->method('getReachableRoles')
- ->with($this->equalTo(array('foo')))
- ->will($this->returnValue($roles))
- ;
-
- $trustResolver = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver', array(), array('', ''));
-
- $trustResolver
- ->expects($this->at(0))
- ->method('isAnonymous')
- ->will($this->returnValue('anonymous' === $authenticationStatus))
- ;
-
- if ('fullFledged' === $authenticationStatus) {
- $trustResolver
- ->expects($this->once())
- ->method('isFullFledged')
- ->will($this->returnValue(true))
- ;
- $trustResolver
- ->expects($this->never())
- ->method('isRememberMe')
- ;
- } elseif ('rememberMe' === $authenticationStatus) {
- $trustResolver
- ->expects($this->once())
- ->method('isFullFledged')
- ->will($this->returnValue(false))
- ;
- $trustResolver
- ->expects($this->once())
- ->method('isRememberMe')
- ->will($this->returnValue(true))
- ;
- } else {
- $trustResolver
- ->expects($this->at(1))
- ->method('isAnonymous')
- ->will($this->returnValue(true))
- ;
- $trustResolver
- ->expects($this->once())
- ->method('isFullFledged')
- ->will($this->returnValue(false))
- ;
- $trustResolver
- ->expects($this->once())
- ->method('isRememberMe')
- ->will($this->returnValue(false))
- ;
- }
-
- return new SecurityIdentityRetrievalStrategy($roleHierarchy, $trustResolver);
- }
-}
-
-class CustomUserImpl
-{
- protected $name;
-
- public function __construct($name)
- {
- $this->name = $name;
- }
-
- public function __toString()
- {
- return $this->name;
- }
-}
diff --git a/Acl/Tests/Domain/UserSecurityIdentityTest.php b/Acl/Tests/Domain/UserSecurityIdentityTest.php
deleted file mode 100644
index 09d3f0d..0000000
--- a/Acl/Tests/Domain/UserSecurityIdentityTest.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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\Tests\Domain;
-
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-
-class UserSecurityIdentityTest extends \PHPUnit_Framework_TestCase
-{
- public function testConstructor()
- {
- $id = new UserSecurityIdentity('foo', 'Foo');
-
- $this->assertEquals('foo', $id->getUsername());
- $this->assertEquals('Foo', $id->getClass());
- }
-
- // Test that constructor never changes the type, even for proxies
- public function testConstructorWithProxy()
- {
- $id = new UserSecurityIdentity('foo', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\Foo');
-
- $this->assertEquals('foo', $id->getUsername());
- $this->assertEquals('Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Acl\Tests\Domain\Foo', $id->getClass());
- }
-
- /**
- * @dataProvider getCompareData
- */
- public function testEquals($id1, $id2, $equal)
- {
- $this->assertSame($equal, $id1->equals($id2));
- }
-
- public function getCompareData()
- {
- $account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')
- ->setMockClassName('USI_AccountImpl')
- ->getMock();
- $account
- ->expects($this->any())
- ->method('getUsername')
- ->will($this->returnValue('foo'))
- ;
-
- $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- $token
- ->expects($this->any())
- ->method('getUser')
- ->will($this->returnValue($account))
- ;
-
- return array(
- array(new UserSecurityIdentity('foo', 'Foo'), new UserSecurityIdentity('foo', 'Foo'), true),
- array(new UserSecurityIdentity('foo', 'Bar'), new UserSecurityIdentity('foo', 'Foo'), false),
- array(new UserSecurityIdentity('foo', 'Foo'), new UserSecurityIdentity('bar', 'Foo'), false),
- array(new UserSecurityIdentity('foo', 'Foo'), UserSecurityIdentity::fromAccount($account), false),
- array(new UserSecurityIdentity('bla', 'Foo'), new UserSecurityIdentity('blub', 'Foo'), false),
- array(new UserSecurityIdentity('foo', 'Foo'), new RoleSecurityIdentity('foo'), false),
- array(new UserSecurityIdentity('foo', 'Foo'), UserSecurityIdentity::fromToken($token), false),
- array(new UserSecurityIdentity('foo', 'USI_AccountImpl'), UserSecurityIdentity::fromToken($token), true),
- );
- }
-}
diff --git a/Acl/Tests/Permission/BasicPermissionMapTest.php b/Acl/Tests/Permission/BasicPermissionMapTest.php
deleted file mode 100644
index 2afe588..0000000
--- a/Acl/Tests/Permission/BasicPermissionMapTest.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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\Tests\Permission;
-
-use Symfony\Component\Security\Acl\Permission\BasicPermissionMap;
-
-class BasicPermissionMapTest extends \PHPUnit_Framework_TestCase
-{
- public function testGetMasksReturnsNullWhenNotSupportedMask()
- {
- $map = new BasicPermissionMap();
- $this->assertNull($map->getMasks('IS_AUTHENTICATED_REMEMBERED', null));
- }
-}
diff --git a/Acl/Tests/Permission/MaskBuilderTest.php b/Acl/Tests/Permission/MaskBuilderTest.php
deleted file mode 100644
index 8245669..0000000
--- a/Acl/Tests/Permission/MaskBuilderTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?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\Tests\Permission;
-
-use Symfony\Component\Security\Acl\Permission\MaskBuilder;
-
-class MaskBuilderTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @expectedException \InvalidArgumentException
- * @dataProvider getInvalidConstructorData
- */
- public function testConstructorWithNonInteger($invalidMask)
- {
- new MaskBuilder($invalidMask);
- }
-
- public function getInvalidConstructorData()
- {
- return array(
- array(234.463),
- array('asdgasdf'),
- array(array()),
- array(new \stdClass()),
- );
- }
-
- public function testConstructorWithoutArguments()
- {
- $builder = new MaskBuilder();
-
- $this->assertEquals(0, $builder->get());
- }
-
- public function testConstructor()
- {
- $builder = new MaskBuilder(123456);
-
- $this->assertEquals(123456, $builder->get());
- }
-
- public function testAddAndRemove()
- {
- $builder = new MaskBuilder();
-
- $builder
- ->add('view')
- ->add('eDiT')
- ->add('ownEr')
- ;
- $mask = $builder->get();
-
- $this->assertEquals(MaskBuilder::MASK_VIEW, $mask & MaskBuilder::MASK_VIEW);
- $this->assertEquals(MaskBuilder::MASK_EDIT, $mask & MaskBuilder::MASK_EDIT);
- $this->assertEquals(MaskBuilder::MASK_OWNER, $mask & MaskBuilder::MASK_OWNER);
- $this->assertEquals(0, $mask & MaskBuilder::MASK_MASTER);
- $this->assertEquals(0, $mask & MaskBuilder::MASK_CREATE);
- $this->assertEquals(0, $mask & MaskBuilder::MASK_DELETE);
- $this->assertEquals(0, $mask & MaskBuilder::MASK_UNDELETE);
-
- $builder->remove('edit')->remove('OWner');
- $mask = $builder->get();
- $this->assertEquals(0, $mask & MaskBuilder::MASK_EDIT);
- $this->assertEquals(0, $mask & MaskBuilder::MASK_OWNER);
- $this->assertEquals(MaskBuilder::MASK_VIEW, $mask & MaskBuilder::MASK_VIEW);
- }
-
- public function testGetPattern()
- {
- $builder = new MaskBuilder();
- $this->assertEquals(MaskBuilder::ALL_OFF, $builder->getPattern());
-
- $builder->add('view');
- $this->assertEquals(str_repeat('.', 31).'V', $builder->getPattern());
-
- $builder->add('owner');
- $this->assertEquals(str_repeat('.', 24).'N......V', $builder->getPattern());
-
- $builder->add(1 << 10);
- $this->assertEquals(str_repeat('.', 21).MaskBuilder::ON.'..N......V', $builder->getPattern());
- }
-
- public function testReset()
- {
- $builder = new MaskBuilder();
- $this->assertEquals(0, $builder->get());
-
- $builder->add('view');
- $this->assertTrue($builder->get() > 0);
-
- $builder->reset();
- $this->assertEquals(0, $builder->get());
- }
-}
diff --git a/Acl/Tests/Voter/AclVoterTest.php b/Acl/Tests/Voter/AclVoterTest.php
deleted file mode 100644
index 2148135..0000000
--- a/Acl/Tests/Voter/AclVoterTest.php
+++ /dev/null
@@ -1,432 +0,0 @@
-<?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\Tests\Voter;
-
-use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
-use Symfony\Component\Security\Acl\Voter\FieldVote;
-use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
-use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
-use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
-use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
-use Symfony\Component\Security\Acl\Voter\AclVoter;
-
-class AclVoterTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @dataProvider getSupportsAttributeTests
- */
- public function testSupportsAttribute($attribute, $supported)
- {
- list($voter, , $permissionMap) = $this->getVoter(true, false);
-
- $permissionMap
- ->expects($this->once())
- ->method('contains')
- ->with($this->identicalTo($attribute))
- ->will($this->returnValue($supported))
- ;
-
- $this->assertSame($supported, $voter->supportsAttribute($attribute));
- }
-
- /**
- * @dataProvider getSupportsAttributeNonStringTests
- */
- public function testSupportsAttributeNonString($attribute)
- {
- list($voter) = $this->getVoter(true, false);
-
- $this->assertFalse($voter->supportsAttribute($attribute));
- }
-
- public function getSupportsAttributeTests()
- {
- return array(
- array('foo', true),
- array('foo', false),
- );
- }
-
- public function getSupportsAttributeNonStringTests()
- {
- return array(
- array(new \stdClass()),
- array(1),
- array(true),
- array(array()),
- );
- }
-
- /**
- * @dataProvider getSupportsClassTests
- */
- public function testSupportsClass($class)
- {
- list($voter) = $this->getVoter();
-
- $this->assertTrue($voter->supportsClass($class));
- }
-
- public function getSupportsClassTests()
- {
- return array(
- array('foo'),
- array('bar'),
- array('moo'),
- );
- }
-
- public function testVote()
- {
- list($voter, , $permissionMap) = $this->getVoter();
- $permissionMap
- ->expects($this->atLeastOnce())
- ->method('getMasks')
- ->will($this->returnValue(null))
- ;
-
- $this->assertSame(VoterInterface::ACCESS_ABSTAIN, $voter->vote($this->getToken(), null, array('VIEW', 'EDIT', 'DELETE')));
- }
-
- /**
- * @dataProvider getTrueFalseTests
- */
- public function testVoteWhenNoObjectIsPassed($allowIfObjectIdentityUnavailable)
- {
- list($voter, , $permissionMap) = $this->getVoter($allowIfObjectIdentityUnavailable);
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->will($this->returnValue(array()))
- ;
-
- if ($allowIfObjectIdentityUnavailable) {
- $vote = VoterInterface::ACCESS_GRANTED;
- } else {
- $vote = VoterInterface::ACCESS_ABSTAIN;
- }
-
- $this->assertSame($vote, $voter->vote($this->getToken(), null, array('VIEW')));
- }
-
- /**
- * @dataProvider getTrueFalseTests
- */
- public function testVoteWhenOidStrategyReturnsNull($allowIfUnavailable)
- {
- list($voter, , $permissionMap, $oidStrategy) = $this->getVoter($allowIfUnavailable);
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->will($this->returnValue(array()))
- ;
-
- $oidStrategy
- ->expects($this->once())
- ->method('getObjectIdentity')
- ->will($this->returnValue(null))
- ;
-
- if ($allowIfUnavailable) {
- $vote = VoterInterface::ACCESS_GRANTED;
- } else {
- $vote = VoterInterface::ACCESS_ABSTAIN;
- }
-
- $this->assertSame($vote, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
- }
-
- public function getTrueFalseTests()
- {
- return array(array(true), array(false));
- }
-
- public function testVoteNoAclFound()
- {
- list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
-
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->will($this->returnValue(array()))
- ;
-
- $oidStrategy
- ->expects($this->once())
- ->method('getObjectIdentity')
- ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
- ;
-
- $sidStrategy
- ->expects($this->once())
- ->method('getSecurityIdentities')
- ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
- ;
-
- $provider
- ->expects($this->once())
- ->method('findAcl')
- ->with($this->equalTo($oid), $this->equalTo($sids))
- ->will($this->throwException(new AclNotFoundException('Not found.')))
- ;
-
- $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
- }
-
- /**
- * @dataProvider getTrueFalseTests
- */
- public function testVoteGrantsAccess($grant)
- {
- list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
-
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->with($this->equalTo('VIEW'))
- ->will($this->returnValue($masks = array(1, 2, 3)))
- ;
-
- $oidStrategy
- ->expects($this->once())
- ->method('getObjectIdentity')
- ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
- ;
-
- $sidStrategy
- ->expects($this->once())
- ->method('getSecurityIdentities')
- ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
- ;
-
- $provider
- ->expects($this->once())
- ->method('findAcl')
- ->with($this->equalTo($oid), $this->equalTo($sids))
- ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
- ;
-
- $acl
- ->expects($this->once())
- ->method('isGranted')
- ->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
- ->will($this->returnValue($grant))
- ;
-
- if ($grant) {
- $vote = VoterInterface::ACCESS_GRANTED;
- } else {
- $vote = VoterInterface::ACCESS_DENIED;
- }
-
- $this->assertSame($vote, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
- }
-
- public function testVoteNoAceFound()
- {
- list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
-
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->with($this->equalTo('VIEW'))
- ->will($this->returnValue($masks = array(1, 2, 3)))
- ;
-
- $oidStrategy
- ->expects($this->once())
- ->method('getObjectIdentity')
- ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
- ;
-
- $sidStrategy
- ->expects($this->once())
- ->method('getSecurityIdentities')
- ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
- ;
-
- $provider
- ->expects($this->once())
- ->method('findAcl')
- ->with($this->equalTo($oid), $this->equalTo($sids))
- ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
- ;
-
- $acl
- ->expects($this->once())
- ->method('isGranted')
- ->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
- ->will($this->throwException(new NoAceFoundException('No ACE')))
- ;
-
- $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new \stdClass(), array('VIEW')));
- }
-
- /**
- * @dataProvider getTrueFalseTests
- */
- public function testVoteGrantsFieldAccess($grant)
- {
- list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
-
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->with($this->equalTo('VIEW'))
- ->will($this->returnValue($masks = array(1, 2, 3)))
- ;
-
- $oidStrategy
- ->expects($this->once())
- ->method('getObjectIdentity')
- ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
- ;
-
- $sidStrategy
- ->expects($this->once())
- ->method('getSecurityIdentities')
- ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
- ;
-
- $provider
- ->expects($this->once())
- ->method('findAcl')
- ->with($this->equalTo($oid), $this->equalTo($sids))
- ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
- ;
-
- $acl
- ->expects($this->once())
- ->method('isFieldGranted')
- ->with($this->identicalTo('foo'), $this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
- ->will($this->returnValue($grant))
- ;
-
- if ($grant) {
- $vote = VoterInterface::ACCESS_GRANTED;
- } else {
- $vote = VoterInterface::ACCESS_DENIED;
- }
-
- $this->assertSame($vote, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW')));
- }
-
- public function testVoteNoFieldAceFound()
- {
- list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
-
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->with($this->equalTo('VIEW'))
- ->will($this->returnValue($masks = array(1, 2, 3)))
- ;
-
- $oidStrategy
- ->expects($this->once())
- ->method('getObjectIdentity')
- ->will($this->returnValue($oid = new ObjectIdentity('1', 'Foo')))
- ;
-
- $sidStrategy
- ->expects($this->once())
- ->method('getSecurityIdentities')
- ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
- ;
-
- $provider
- ->expects($this->once())
- ->method('findAcl')
- ->with($this->equalTo($oid), $this->equalTo($sids))
- ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
- ;
-
- $acl
- ->expects($this->once())
- ->method('isFieldGranted')
- ->with($this->identicalTo('foo'), $this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
- ->will($this->throwException(new NoAceFoundException('No ACE')))
- ;
-
- $this->assertSame(VoterInterface::ACCESS_DENIED, $voter->vote($this->getToken(), new FieldVote(new \stdClass(), 'foo'), array('VIEW')));
- }
-
- public function testWhenReceivingAnObjectIdentityInterfaceWeDontRetrieveANewObjectIdentity()
- {
- list($voter, $provider, $permissionMap, $oidStrategy, $sidStrategy) = $this->getVoter();
-
- $oid = new ObjectIdentity('someID', 'someType');
-
- $permissionMap
- ->expects($this->once())
- ->method('getMasks')
- ->with($this->equalTo('VIEW'))
- ->will($this->returnValue($masks = array(1, 2, 3)))
- ;
-
- $oidStrategy
- ->expects($this->never())
- ->method('getObjectIdentity')
- ;
-
- $sidStrategy
- ->expects($this->once())
- ->method('getSecurityIdentities')
- ->will($this->returnValue($sids = array(new UserSecurityIdentity('johannes', 'Foo'), new RoleSecurityIdentity('ROLE_FOO'))))
- ;
-
- $provider
- ->expects($this->once())
- ->method('findAcl')
- ->with($this->equalTo($oid), $this->equalTo($sids))
- ->will($this->returnValue($acl = $this->getMock('Symfony\Component\Security\Acl\Model\AclInterface')))
- ;
-
- $acl
- ->expects($this->once())
- ->method('isGranted')
- ->with($this->identicalTo($masks), $this->equalTo($sids), $this->isFalse())
- ->will($this->throwException(new NoAceFoundException('No ACE')))
- ;
-
- $voter->vote($this->getToken(), $oid, array('VIEW'));
- }
-
- protected function getToken()
- {
- return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
- }
-
- protected function getVoter($allowIfObjectIdentityUnavailable = true, $alwaysContains = true)
- {
- $provider = $this->getMock('Symfony\Component\Security\Acl\Model\AclProviderInterface');
- $permissionMap = $this->getMock('Symfony\Component\Security\Acl\Permission\PermissionMapInterface');
- $oidStrategy = $this->getMock('Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface');
- $sidStrategy = $this->getMock('Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface');
-
- if ($alwaysContains) {
- $permissionMap
- ->expects($this->any())
- ->method('contains')
- ->will($this->returnValue(true));
- }
-
- return array(
- new AclVoter($provider, $oidStrategy, $sidStrategy, $permissionMap, null, $allowIfObjectIdentityUnavailable),
- $provider,
- $permissionMap,
- $oidStrategy,
- $sidStrategy,
- );
- }
-}
diff --git a/Acl/Voter/AclVoter.php b/Acl/Voter/AclVoter.php
deleted file mode 100644
index ec6024a..0000000
--- a/Acl/Voter/AclVoter.php
+++ /dev/null
@@ -1,147 +0,0 @@
-<?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\Voter;
-
-use Psr\Log\LoggerInterface;
-use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
-use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
-use Symfony\Component\Security\Acl\Model\AclProviderInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
-use Symfony\Component\Security\Acl\Permission\PermissionMapInterface;
-use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
-use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
-
-/**
- * This voter can be used as a base class for implementing your own permissions.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class AclVoter implements VoterInterface
-{
- private $aclProvider;
- private $permissionMap;
- private $objectIdentityRetrievalStrategy;
- private $securityIdentityRetrievalStrategy;
- private $allowIfObjectIdentityUnavailable;
- private $logger;
-
- public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy, PermissionMapInterface $permissionMap, LoggerInterface $logger = null, $allowIfObjectIdentityUnavailable = true)
- {
- $this->aclProvider = $aclProvider;
- $this->permissionMap = $permissionMap;
- $this->objectIdentityRetrievalStrategy = $oidRetrievalStrategy;
- $this->securityIdentityRetrievalStrategy = $sidRetrievalStrategy;
- $this->logger = $logger;
- $this->allowIfObjectIdentityUnavailable = $allowIfObjectIdentityUnavailable;
- }
-
- public function supportsAttribute($attribute)
- {
- return is_string($attribute) && $this->permissionMap->contains($attribute);
- }
-
- public function vote(TokenInterface $token, $object, array $attributes)
- {
- foreach ($attributes as $attribute) {
- if (!$this->supportsAttribute($attribute)) {
- continue;
- }
-
- if (null === $masks = $this->permissionMap->getMasks($attribute, $object)) {
- continue;
- }
-
- if (null === $object) {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Object identity unavailable. Voting to %s.', $this->allowIfObjectIdentityUnavailable ? 'grant access' : 'abstain'));
- }
-
- return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN;
- } elseif ($object instanceof FieldVote) {
- $field = $object->getField();
- $object = $object->getDomainObject();
- } else {
- $field = null;
- }
-
- if ($object instanceof ObjectIdentityInterface) {
- $oid = $object;
- } elseif (null === $oid = $this->objectIdentityRetrievalStrategy->getObjectIdentity($object)) {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Object identity unavailable. Voting to %s.', $this->allowIfObjectIdentityUnavailable ? 'grant access' : 'abstain'));
- }
-
- return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN;
- }
-
- if (!$this->supportsClass($oid->getType())) {
- return self::ACCESS_ABSTAIN;
- }
-
- $sids = $this->securityIdentityRetrievalStrategy->getSecurityIdentities($token);
-
- try {
- $acl = $this->aclProvider->findAcl($oid, $sids);
-
- if (null === $field && $acl->isGranted($masks, $sids, false)) {
- if (null !== $this->logger) {
- $this->logger->debug('ACL found, permission granted. Voting to grant access.');
- }
-
- return self::ACCESS_GRANTED;
- } elseif (null !== $field && $acl->isFieldGranted($field, $masks, $sids, false)) {
- if (null !== $this->logger) {
- $this->logger->debug('ACL found, permission granted. Voting to grant access.');
- }
-
- return self::ACCESS_GRANTED;
- }
-
- if (null !== $this->logger) {
- $this->logger->debug('ACL found, insufficient permissions. Voting to deny access.');
- }
-
- return self::ACCESS_DENIED;
- } catch (AclNotFoundException $e) {
- if (null !== $this->logger) {
- $this->logger->debug('No ACL found for the object identity. Voting to deny access.');
- }
-
- return self::ACCESS_DENIED;
- } catch (NoAceFoundException $e) {
- if (null !== $this->logger) {
- $this->logger->debug('ACL found, no ACE applicable. Voting to deny access.');
- }
-
- return self::ACCESS_DENIED;
- }
- }
-
- // no attribute was supported
- return self::ACCESS_ABSTAIN;
- }
-
- /**
- * You can override this method when writing a voter for a specific domain
- * class.
- *
- * @param string $class The class name
- *
- * @return bool
- */
- public function supportsClass($class)
- {
- return true;
- }
-}
diff --git a/Acl/Voter/FieldVote.php b/Acl/Voter/FieldVote.php
deleted file mode 100644
index 8782f76..0000000
--- a/Acl/Voter/FieldVote.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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\Voter;
-
-/**
- * This class is a lightweight wrapper around field vote requests which does
- * not violate any interface contracts.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
-class FieldVote
-{
- private $domainObject;
- private $field;
-
- public function __construct($domainObject, $field)
- {
- $this->domainObject = $domainObject;
- $this->field = $field;
- }
-
- public function getDomainObject()
- {
- return $this->domainObject;
- }
-
- public function getField()
- {
- return $this->field;
- }
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22eb9cd..b33f053 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,26 @@
CHANGELOG
=========
+2.8.0
+-----
+
+ * deprecated `getKey()` of the `AnonymousToken`, `RememberMeToken`,
+ `AbstractRememberMeServices` and `DigestAuthenticationEntryPoint` classes in favor of `getSecret()`.
+ * deprecated `Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface`, use
+ `Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface` instead
+ * deprecated `Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface`, use
+ `Symfony\Component\Security\Http\Authentication\SimpleFormAuthenticatorInterface` instead
+ * deprecated `Symfony\Component\Security\Core\Util\ClassUtils`, use
+ `Symfony\Component\Security\Acl\Util\ClassUtils` instead
+ * deprecated the `Symfony\Component\Security\Core\Util\SecureRandom` class in favor of the `random_bytes()` function
+ * deprecated `supportsAttribute()` and `supportsClass()` methods of
+ `Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface` and
+ `Symfony\Component\Security\Core\Authorization\Voter\VoterInterface`.
+ * deprecated `getSupportedAttributes()` and `getSupportedClasses()` methods of
+ `Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter`, use `supports()` instead.
+ * deprecated the `intention` option for all the authentication listeners,
+ use the `csrf_token_id` option instead.
+
2.7.0
-----
diff --git a/Core/Authentication/Provider/AnonymousAuthenticationProvider.php b/Core/Authentication/Provider/AnonymousAuthenticationProvider.php
index 7fbbf85..ff3d15f 100644
--- a/Core/Authentication/Provider/AnonymousAuthenticationProvider.php
+++ b/Core/Authentication/Provider/AnonymousAuthenticationProvider.php
@@ -22,16 +22,22 @@ use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
*/
class AnonymousAuthenticationProvider implements AuthenticationProviderInterface
{
- private $key;
+ /**
+ * Used to determine if the token is created by the application
+ * instead of a malicious client.
+ *
+ * @var string
+ */
+ private $secret;
/**
* Constructor.
*
- * @param string $key The key shared with the authentication token
+ * @param string $secret The secret shared with the AnonymousToken
*/
- public function __construct($key)
+ public function __construct($secret)
{
- $this->key = $key;
+ $this->secret = $secret;
}
/**
@@ -43,7 +49,7 @@ class AnonymousAuthenticationProvider implements AuthenticationProviderInterface
return;
}
- if ($this->key !== $token->getKey()) {
+ if ($this->secret !== $token->getSecret()) {
throw new BadCredentialsException('The Token does not contain the expected key.');
}
diff --git a/Core/Authentication/Provider/LdapBindAuthenticationProvider.php b/Core/Authentication/Provider/LdapBindAuthenticationProvider.php
new file mode 100644
index 0000000..e887f99
--- /dev/null
+++ b/Core/Authentication/Provider/LdapBindAuthenticationProvider.php
@@ -0,0 +1,89 @@
+<?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\Core\Authentication\Provider;
+
+use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+use Symfony\Component\Security\Core\User\UserCheckerInterface;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Ldap\LdapClientInterface;
+use Symfony\Component\Ldap\Exception\ConnectionException;
+
+/**
+ * LdapBindAuthenticationProvider authenticates a user against an LDAP server.
+ *
+ * The only way to check user credentials is to try to connect the user with its
+ * credentials to the ldap.
+ *
+ * @author Charles Sarrazin <charles@sarraz.in>
+ */
+class LdapBindAuthenticationProvider extends UserAuthenticationProvider
+{
+ private $userProvider;
+ private $ldap;
+ private $dnString;
+
+ /**
+ * Constructor.
+ *
+ * @param UserProviderInterface $userProvider A UserProvider
+ * @param UserCheckerInterface $userChecker A UserChecker
+ * @param string $providerKey The provider key
+ * @param LdapClientInterface $ldap An Ldap client
+ * @param string $dnString A string used to create the bind DN
+ * @param bool $hideUserNotFoundExceptions Whether to hide user not found exception or not
+ */
+ public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, $providerKey, LdapClientInterface $ldap, $dnString = '{username}', $hideUserNotFoundExceptions = true)
+ {
+ parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions);
+
+ $this->userProvider = $userProvider;
+ $this->ldap = $ldap;
+ $this->dnString = $dnString;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function retrieveUser($username, UsernamePasswordToken $token)
+ {
+ if ('NONE_PROVIDED' === $username) {
+ throw new UsernameNotFoundException('Username can not be null');
+ }
+
+ return $this->userProvider->loadUserByUsername($username);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
+ {
+ $username = $token->getUsername();
+ $password = $token->getCredentials();
+
+ if ('' === $password) {
+ throw new BadCredentialsException('The presented password must not be empty.');
+ }
+
+ try {
+ $username = $this->ldap->escape($username, '', LDAP_ESCAPE_DN);
+ $dn = str_replace('{username}', $username, $this->dnString);
+
+ $this->ldap->bind($dn, $password);
+ } catch (ConnectionException $e) {
+ throw new BadCredentialsException('The presented password is invalid.');
+ }
+ }
+}
diff --git a/Core/Authentication/Provider/RememberMeAuthenticationProvider.php b/Core/Authentication/Provider/RememberMeAuthenticationProvider.php
index 82be1d1..f0a74eb 100644
--- a/Core/Authentication/Provider/RememberMeAuthenticationProvider.php
+++ b/Core/Authentication/Provider/RememberMeAuthenticationProvider.php
@@ -19,20 +19,20 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException;
class RememberMeAuthenticationProvider implements AuthenticationProviderInterface
{
private $userChecker;
- private $key;
+ private $secret;
private $providerKey;
/**
* Constructor.
*
* @param UserCheckerInterface $userChecker An UserCheckerInterface interface
- * @param string $key A key
- * @param string $providerKey A provider key
+ * @param string $secret A secret
+ * @param string $providerKey A provider secret
*/
- public function __construct(UserCheckerInterface $userChecker, $key, $providerKey)
+ public function __construct(UserCheckerInterface $userChecker, $secret, $providerKey)
{
$this->userChecker = $userChecker;
- $this->key = $key;
+ $this->secret = $secret;
$this->providerKey = $providerKey;
}
@@ -45,14 +45,14 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac
return;
}
- if ($this->key !== $token->getKey()) {
- throw new BadCredentialsException('The presented key does not match.');
+ if ($this->secret !== $token->getSecret()) {
+ throw new BadCredentialsException('The presented secret does not match.');
}
$user = $token->getUser();
$this->userChecker->checkPreAuth($user);
- $authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->key);
+ $authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->secret);
$authenticatedToken->setAttributes($token->getAttributes());
return $authenticatedToken;
diff --git a/Core/Authentication/SimpleFormAuthenticatorInterface.php b/Core/Authentication/SimpleFormAuthenticatorInterface.php
index 95ee881..ae2b58b 100644
--- a/Core/Authentication/SimpleFormAuthenticatorInterface.php
+++ b/Core/Authentication/SimpleFormAuthenticatorInterface.php
@@ -14,6 +14,8 @@ namespace Symfony\Component\Security\Core\Authentication;
use Symfony\Component\HttpFoundation\Request;
/**
+ * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use the same interface from Security\Http\Authentication instead.
+ *
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
interface SimpleFormAuthenticatorInterface extends SimpleAuthenticatorInterface
diff --git a/Core/Authentication/SimplePreAuthenticatorInterface.php b/Core/Authentication/SimplePreAuthenticatorInterface.php
index 6164e7d..c01f064 100644
--- a/Core/Authentication/SimplePreAuthenticatorInterface.php
+++ b/Core/Authentication/SimplePreAuthenticatorInterface.php
@@ -14,6 +14,8 @@ namespace Symfony\Component\Security\Core\Authentication;
use Symfony\Component\HttpFoundation\Request;
/**
+ * @deprecated Since version 2.8, to be removed in 3.0. Use the same interface from Security\Http\Authentication instead.
+ *
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
interface SimplePreAuthenticatorInterface extends SimpleAuthenticatorInterface
diff --git a/Core/Authentication/Token/AnonymousToken.php b/Core/Authentication/Token/AnonymousToken.php
index 0d7dea0..bbbfe64 100644
--- a/Core/Authentication/Token/AnonymousToken.php
+++ b/Core/Authentication/Token/AnonymousToken.php
@@ -20,20 +20,20 @@ use Symfony\Component\Security\Core\Role\RoleInterface;
*/
class AnonymousToken extends AbstractToken
{
- private $key;
+ private $secret;
/**
* Constructor.
*
- * @param string $key The key shared with the authentication provider
- * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string
- * @param RoleInterface[] $roles An array of roles
+ * @param string $secret A secret used to make sure the token is created by the app and not by a malicious client
+ * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string
+ * @param RoleInterface[] $roles An array of roles
*/
- public function __construct($key, $user, array $roles = array())
+ public function __construct($secret, $user, array $roles = array())
{
parent::__construct($roles);
- $this->key = $key;
+ $this->secret = $secret;
$this->setUser($user);
$this->setAuthenticated(true);
}
@@ -47,13 +47,23 @@ class AnonymousToken extends AbstractToken
}
/**
- * Returns the key.
- *
- * @return string The Key
+ * @deprecated Since version 2.8, to be removed in 3.0. Use getSecret() instead.
*/
public function getKey()
{
- return $this->key;
+ @trigger_error(__method__.'() is deprecated since version 2.8 and will be removed in 3.0. Use getSecret() instead.', E_USER_DEPRECATED);
+
+ return $this->getSecret();
+ }
+
+ /**
+ * Returns the secret.
+ *
+ * @return string
+ */
+ public function getSecret()
+ {
+ return $this->secret;
}
/**
@@ -61,7 +71,7 @@ class AnonymousToken extends AbstractToken
*/
public function serialize()
{
- return serialize(array($this->key, parent::serialize()));
+ return serialize(array($this->secret, parent::serialize()));
}
/**
@@ -69,7 +79,7 @@ class AnonymousToken extends AbstractToken
*/
public function unserialize($serialized)
{
- list($this->key, $parentStr) = unserialize($serialized);
+ list($this->secret, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
}
diff --git a/Core/Authentication/Token/RememberMeToken.php b/Core/Authentication/Token/RememberMeToken.php
index 609fdad..60e36f2 100644
--- a/Core/Authentication/Token/RememberMeToken.php
+++ b/Core/Authentication/Token/RememberMeToken.php
@@ -20,7 +20,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
*/
class RememberMeToken extends AbstractToken
{
- private $key;
+ private $secret;
private $providerKey;
/**
@@ -28,16 +28,16 @@ class RememberMeToken extends AbstractToken
*
* @param UserInterface $user
* @param string $providerKey
- * @param string $key
+ * @param string $secret A secret used to make sure the token is created by the app and not by a malicious client
*
* @throws \InvalidArgumentException
*/
- public function __construct(UserInterface $user, $providerKey, $key)
+ public function __construct(UserInterface $user, $providerKey, $secret)
{
parent::__construct($user->getRoles());
- if (empty($key)) {
- throw new \InvalidArgumentException('$key must not be empty.');
+ if (empty($secret)) {
+ throw new \InvalidArgumentException('$secret must not be empty.');
}
if (empty($providerKey)) {
@@ -45,7 +45,7 @@ class RememberMeToken extends AbstractToken
}
$this->providerKey = $providerKey;
- $this->key = $key;
+ $this->secret = $secret;
$this->setUser($user);
parent::setAuthenticated(true);
@@ -64,9 +64,9 @@ class RememberMeToken extends AbstractToken
}
/**
- * Returns the provider key.
+ * Returns the provider secret.
*
- * @return string The provider key
+ * @return string The provider secret
*/
public function getProviderKey()
{
@@ -74,13 +74,23 @@ class RememberMeToken extends AbstractToken
}
/**
- * Returns the key.
- *
- * @return string The Key
+ * @deprecated Since version 2.8, to be removed in 3.0. Use getSecret() instead.
*/
public function getKey()
{
- return $this->key;
+ @trigger_error(__method__.'() is deprecated since version 2.8 and will be removed in 3.0. Use getSecret() instead.', E_USER_DEPRECATED);
+
+ return $this->getSecret();
+ }
+
+ /**
+ * Returns the secret.
+ *
+ * @return string
+ */
+ public function getSecret()
+ {
+ return $this->secret;
}
/**
@@ -97,7 +107,7 @@ class RememberMeToken extends AbstractToken
public function serialize()
{
return serialize(array(
- $this->key,
+ $this->secret,
$this->providerKey,
parent::serialize(),
));
@@ -108,7 +118,7 @@ class RememberMeToken extends AbstractToken
*/
public function unserialize($serialized)
{
- list($this->key, $this->providerKey, $parentStr) = unserialize($serialized);
+ list($this->secret, $this->providerKey, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
}
diff --git a/Core/Authorization/AccessDecisionManager.php b/Core/Authorization/AccessDecisionManager.php
index b8b6a77..7cefef1 100644
--- a/Core/Authorization/AccessDecisionManager.php
+++ b/Core/Authorization/AccessDecisionManager.php
@@ -41,12 +41,8 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*
* @throws \InvalidArgumentException
*/
- public function __construct(array $voters, $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
+ public function __construct(array $voters = array(), $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
{
- if (!$voters) {
- throw new \InvalidArgumentException('You must at least add one voter.');
- }
-
$strategyMethod = 'decide'.ucfirst($strategy);
if (!is_callable(array($this, $strategyMethod))) {
throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy));
@@ -59,6 +55,16 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
}
/**
+ * Configures the voters.
+ *
+ * @param VoterInterface[] $voters An array of VoterInterface instances
+ */
+ public function setVoters(array $voters)
+ {
+ $this->voters = $voters;
+ }
+
+ /**
* {@inheritdoc}
*/
public function decide(TokenInterface $token, array $attributes, $object = null)
@@ -71,6 +77,8 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*/
public function supportsAttribute($attribute)
{
+ @trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
+
foreach ($this->voters as $voter) {
if ($voter->supportsAttribute($attribute)) {
return true;
@@ -85,6 +93,8 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*/
public function supportsClass($class)
{
+ @trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
+
foreach ($this->voters as $voter) {
if ($voter->supportsClass($class)) {
return true;
@@ -144,7 +154,6 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
{
$grant = 0;
$deny = 0;
- $abstain = 0;
foreach ($this->voters as $voter) {
$result = $voter->vote($token, $object, $attributes);
@@ -158,11 +167,6 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
++$deny;
break;
-
- default:
- ++$abstain;
-
- break;
}
}
@@ -174,7 +178,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
return false;
}
- if ($grant == $deny && $grant != 0) {
+ if ($grant > 0) {
return $this->allowIfEqualGrantedDeniedDecisions;
}
diff --git a/Core/Authorization/AccessDecisionManagerInterface.php b/Core/Authorization/AccessDecisionManagerInterface.php
index 16209ba..d18b5e3 100644
--- a/Core/Authorization/AccessDecisionManagerInterface.php
+++ b/Core/Authorization/AccessDecisionManagerInterface.php
@@ -37,6 +37,8 @@ interface AccessDecisionManagerInterface
* @param string $attribute An attribute
*
* @return bool true if this decision manager supports the attribute, false otherwise
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function supportsAttribute($attribute);
@@ -46,6 +48,8 @@ interface AccessDecisionManagerInterface
* @param string $class A class name
*
* @return true if this decision manager can process the class
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function supportsClass($class);
}
diff --git a/Core/Authorization/Voter/AbstractVoter.php b/Core/Authorization/Voter/AbstractVoter.php
index efa1562..5dcf787 100644
--- a/Core/Authorization/Voter/AbstractVoter.php
+++ b/Core/Authorization/Voter/AbstractVoter.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authorization\Voter;
+@trigger_error('The '.__NAMESPACE__.'\AbstractVoter class is deprecated since version 2.8, to be removed in 3.0. Upgrade to Symfony\Component\Security\Core\Authorization\Voter\Voter instead.', E_USER_DEPRECATED);
+
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
@@ -18,6 +20,8 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
* Abstract Voter implementation that reduces boilerplate code required to create a custom Voter.
*
* @author Roman Marintšenko <inoryy@gmail.com>
+ *
+ * @deprecated since version 2.8, to be removed in 3.0. Upgrade to Symfony\Component\Security\Core\Authorization\Voter\Voter instead.
*/
abstract class AbstractVoter implements VoterInterface
{
diff --git a/Core/Authorization/Voter/ExpressionVoter.php b/Core/Authorization/Voter/ExpressionVoter.php
index 98b8f50..96a7ece 100644
--- a/Core/Authorization/Voter/ExpressionVoter.php
+++ b/Core/Authorization/Voter/ExpressionVoter.php
@@ -102,6 +102,7 @@ class ExpressionVoter implements VoterInterface
'token' => $token,
'user' => $token->getUser(),
'object' => $object,
+ 'subject' => $object,
'roles' => array_map(function ($role) { return $role->getRole(); }, $roles),
'trust_resolver' => $this->trustResolver,
);
diff --git a/Core/Authorization/Voter/Voter.php b/Core/Authorization/Voter/Voter.php
new file mode 100644
index 0000000..2396b1e
--- /dev/null
+++ b/Core/Authorization/Voter/Voter.php
@@ -0,0 +1,86 @@
+<?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\Core\Authorization\Voter;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
+/**
+ * Voter is an abstract default implementation of a voter.
+ *
+ * @author Roman Marintšenko <inoryy@gmail.com>
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ */
+abstract class Voter implements VoterInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsAttribute($attribute)
+ {
+ throw new \BadMethodCallException('supportsAttribute method is deprecated since version 2.8, to be removed in 3.0');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsClass($class)
+ {
+ throw new \BadMethodCallException('supportsClass method is deprecated since version 2.8, to be removed in 3.0');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function vote(TokenInterface $token, $object, array $attributes)
+ {
+ // abstain vote by default in case none of the attributes are supported
+ $vote = self::ACCESS_ABSTAIN;
+
+ foreach ($attributes as $attribute) {
+ if (!$this->supports($attribute, $object)) {
+ continue;
+ }
+
+ // as soon as at least one attribute is supported, default is to deny access
+ $vote = self::ACCESS_DENIED;
+
+ if ($this->voteOnAttribute($attribute, $object, $token)) {
+ // grant access as soon as at least one attribute returns a positive response
+ return self::ACCESS_GRANTED;
+ }
+ }
+
+ return $vote;
+ }
+
+ /**
+ * Determines if the attribute and subject are supported by this voter.
+ *
+ * @param string $attribute An attribute
+ * @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type
+ *
+ * @return bool True if the attribute and subject are supported, false otherwise
+ */
+ abstract protected function supports($attribute, $subject);
+
+ /**
+ * Perform a single access check operation on a given attribute, subject and token.
+ * It is safe to assume that $attribute and $subject already passed the "supports()" method check.
+ *
+ * @param string $attribute
+ * @param mixed $subject
+ * @param TokenInterface $token
+ *
+ * @return bool
+ */
+ abstract protected function voteOnAttribute($attribute, $subject, TokenInterface $token);
+}
diff --git a/Core/Authorization/Voter/VoterInterface.php b/Core/Authorization/Voter/VoterInterface.php
index 1032cb2..91ddc1f 100644
--- a/Core/Authorization/Voter/VoterInterface.php
+++ b/Core/Authorization/Voter/VoterInterface.php
@@ -30,6 +30,8 @@ interface VoterInterface
* @param mixed $attribute An attribute (usually the attribute name string)
*
* @return bool true if this Voter supports the attribute, false otherwise
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function supportsAttribute($attribute);
@@ -39,6 +41,8 @@ interface VoterInterface
* @param string $class A class name
*
* @return bool true if this Voter can process the class
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function supportsClass($class);
diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php
index 83ae334..b992765 100644
--- a/Core/Encoder/BCryptPasswordEncoder.php
+++ b/Core/Encoder/BCryptPasswordEncoder.php
@@ -36,10 +36,6 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
*/
public function __construct($cost)
{
- if (!function_exists('password_hash')) {
- throw new \RuntimeException('To use the BCrypt encoder, you need to upgrade to PHP 5.5 or install the "ircmaxell/password-compat" via Composer.');
- }
-
$cost = (int) $cost;
if ($cost < 4 || $cost > 31) {
throw new \InvalidArgumentException('Cost must be in the range of 4-31.');
@@ -77,6 +73,8 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
$options = array('cost' => $this->cost);
if ($salt) {
+ @trigger_error('Passing a $salt to '.__METHOD__.'() is deprecated since version 2.8 and will be ignored in 3.0.', E_USER_DEPRECATED);
+
$options['salt'] = $salt;
}
diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php
index fcf2e47..d86f260 100644
--- a/Core/Encoder/BasePasswordEncoder.php
+++ b/Core/Encoder/BasePasswordEncoder.php
@@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Core\Encoder;
-use Symfony\Component\Security\Core\Util\StringUtils;
-
/**
* BasePasswordEncoder is the base class for all password encoders.
*
@@ -83,7 +81,7 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
*/
protected function comparePasswords($password1, $password2)
{
- return StringUtils::equals($password1, $password2);
+ return hash_equals($password1, $password2);
}
/**
diff --git a/Core/Encoder/Pbkdf2PasswordEncoder.php b/Core/Encoder/Pbkdf2PasswordEncoder.php
index 6f24c4f..8422a4b 100644
--- a/Core/Encoder/Pbkdf2PasswordEncoder.php
+++ b/Core/Encoder/Pbkdf2PasswordEncoder.php
@@ -64,11 +64,7 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
- if (function_exists('hash_pbkdf2')) {
- $digest = hash_pbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length, true);
- } else {
- $digest = $this->hashPbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length);
- }
+ $digest = hash_pbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length, true);
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
@@ -80,24 +76,4 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder
{
return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
-
- private function hashPbkdf2($algorithm, $password, $salt, $iterations, $length = 0)
- {
- // Number of blocks needed to create the derived key
- $blocks = ceil($length / strlen(hash($algorithm, null, true)));
- $digest = '';
-
- for ($i = 1; $i <= $blocks; ++$i) {
- $ib = $block = hash_hmac($algorithm, $salt.pack('N', $i), $password, true);
-
- // Iterations
- for ($j = 1; $j < $iterations; ++$j) {
- $ib ^= ($block = hash_hmac($algorithm, $block, $password, true));
- }
-
- $digest .= $ib;
- }
-
- return substr($digest, 0, $this->length);
- }
}
diff --git a/Core/Exception/AuthenticationExpiredException.php b/Core/Exception/AuthenticationExpiredException.php
new file mode 100644
index 0000000..caf2e6c
--- /dev/null
+++ b/Core/Exception/AuthenticationExpiredException.php
@@ -0,0 +1,31 @@
+<?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\Core\Exception;
+
+/**
+ * AuthenticationServiceException is thrown when an authenticated token becomes un-authentcated between requests.
+ *
+ * In practice, this is due to the User changing between requests (e.g. password changes),
+ * causes the token to become un-authenticated.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class AuthenticationExpiredException extends AccountStatusException
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Authentication expired because your account information has changed.';
+ }
+}
diff --git a/Core/Exception/CustomUserMessageAuthenticationException.php b/Core/Exception/CustomUserMessageAuthenticationException.php
new file mode 100644
index 0000000..9f5071f
--- /dev/null
+++ b/Core/Exception/CustomUserMessageAuthenticationException.php
@@ -0,0 +1,79 @@
+<?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\Core\Exception;
+
+/**
+ * An authentication exception where you can control the message shown to the user.
+ *
+ * Be sure that the message passed to this exception is something that
+ * can be shown safely to your user. In other words, avoid catching
+ * other exceptions and passing their message directly to this class.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class CustomUserMessageAuthenticationException extends AuthenticationException
+{
+ private $messageKey;
+
+ private $messageData = array();
+
+ public function __construct($message = '', array $messageData = array(), $code = 0, \Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->setSafeMessage($message, $messageData);
+ }
+
+ /**
+ * Set a message that will be shown to the user.
+ *
+ * @param string $messageKey The message or message key
+ * @param array $messageData Data to be passed into the translator
+ */
+ public function setSafeMessage($messageKey, array $messageData = array())
+ {
+ $this->messageKey = $messageKey;
+ $this->messageData = $messageData;
+ }
+
+ public function getMessageKey()
+ {
+ return $this->messageKey;
+ }
+
+ public function getMessageData()
+ {
+ return $this->messageData;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ parent::serialize(),
+ $this->messageKey,
+ $this->messageData,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($str)
+ {
+ list($parentData, $this->messageKey, $this->messageData) = unserialize($str);
+
+ parent::unserialize($parentData);
+ }
+}
diff --git a/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php
index 5a189b0..8f4b392 100644
--- a/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php
@@ -33,11 +33,11 @@ class AnonymousAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
- public function testAuthenticateWhenKeyIsNotValid()
+ public function testAuthenticateWhenSecretIsNotValid()
{
$provider = $this->getProvider('foo');
- $this->assertNull($provider->authenticate($this->getSupportedToken('bar')));
+ $provider->authenticate($this->getSupportedToken('bar'));
}
public function testAuthenticate()
@@ -48,19 +48,19 @@ class AnonymousAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
$this->assertSame($token, $provider->authenticate($token));
}
- protected function getSupportedToken($key)
+ protected function getSupportedToken($secret)
{
- $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken', array('getKey'), array(), '', false);
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken', array('getSecret'), array(), '', false);
$token->expects($this->any())
- ->method('getKey')
- ->will($this->returnValue($key))
+ ->method('getSecret')
+ ->will($this->returnValue($secret))
;
return $token;
}
- protected function getProvider($key)
+ protected function getProvider($secret)
{
- return new AnonymousAuthenticationProvider($key);
+ return new AnonymousAuthenticationProvider($secret);
}
}
diff --git a/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php
new file mode 100644
index 0000000..fbb4d73
--- /dev/null
+++ b/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php
@@ -0,0 +1,81 @@
+<?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\Core\Tests\Authentication\Provider;
+
+use Symfony\Component\Security\Core\Authentication\Provider\LdapBindAuthenticationProvider;
+use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\User\User;
+use Symfony\Component\Ldap\Exception\ConnectionException;
+
+/**
+ * @requires extension ldap
+ */
+class LdapBindAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedExceptionMessage The presented password must not be empty.
+ */
+ public function testEmptyPasswordShouldThrowAnException()
+ {
+ $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
+
+ $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap);
+ $reflection = new \ReflectionMethod($provider, 'checkAuthentication');
+ $reflection->setAccessible(true);
+
+ $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', '', 'key'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedExceptionMessage The presented password is invalid.
+ */
+ public function testBindFailureShouldThrowAnException()
+ {
+ $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $ldap
+ ->expects($this->once())
+ ->method('bind')
+ ->will($this->throwException(new ConnectionException()))
+ ;
+ $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
+
+ $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap);
+ $reflection = new \ReflectionMethod($provider, 'checkAuthentication');
+ $reflection->setAccessible(true);
+
+ $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', 'bar', 'key'));
+ }
+
+ public function testRetrieveUser()
+ {
+ $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
+ $userProvider
+ ->expects($this->once())
+ ->method('loadUserByUsername')
+ ->with('foo')
+ ;
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+
+ $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
+
+ $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap);
+ $reflection = new \ReflectionMethod($provider, 'retrieveUser');
+ $reflection->setAccessible(true);
+
+ $reflection->invoke($provider, 'foo', new UsernamePasswordToken('foo', 'bar', 'key'));
+ }
+}
diff --git a/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php
index a6fff4b..735d195 100644
--- a/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php
+++ b/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php
@@ -36,10 +36,10 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
- public function testAuthenticateWhenKeysDoNotMatch()
+ public function testAuthenticateWhenSecretsDoNotMatch()
{
- $provider = $this->getProvider(null, 'key1');
- $token = $this->getSupportedToken(null, 'key2');
+ $provider = $this->getProvider(null, 'secret1');
+ $token = $this->getSupportedToken(null, 'secret2');
$provider->authenticate($token);
}
@@ -77,7 +77,7 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('', $authToken->getCredentials());
}
- protected function getSupportedToken($user = null, $key = 'test')
+ protected function getSupportedToken($user = null, $secret = 'test')
{
if (null === $user) {
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
@@ -87,7 +87,7 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(array()));
}
- $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array('getProviderKey'), array($user, 'foo', $key));
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array('getProviderKey'), array($user, 'foo', $secret));
$token
->expects($this->once())
->method('getProviderKey')
diff --git a/Core/Tests/Authentication/Token/AnonymousTokenTest.php b/Core/Tests/Authentication/Token/AnonymousTokenTest.php
index b5cf006..cac2039 100644
--- a/Core/Tests/Authentication/Token/AnonymousTokenTest.php
+++ b/Core/Tests/Authentication/Token/AnonymousTokenTest.php
@@ -28,7 +28,7 @@ class AnonymousTokenTest extends \PHPUnit_Framework_TestCase
public function testGetKey()
{
$token = new AnonymousToken('foo', 'bar');
- $this->assertEquals('foo', $token->getKey());
+ $this->assertEquals('foo', $token->getSecret());
}
public function testGetCredentials()
diff --git a/Core/Tests/Authentication/Token/RememberMeTokenTest.php b/Core/Tests/Authentication/Token/RememberMeTokenTest.php
index 7449204..b83de4a 100644
--- a/Core/Tests/Authentication/Token/RememberMeTokenTest.php
+++ b/Core/Tests/Authentication/Token/RememberMeTokenTest.php
@@ -22,7 +22,7 @@ class RememberMeTokenTest extends \PHPUnit_Framework_TestCase
$token = new RememberMeToken($user, 'fookey', 'foo');
$this->assertEquals('fookey', $token->getProviderKey());
- $this->assertEquals('foo', $token->getKey());
+ $this->assertEquals('foo', $token->getSecret());
$this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles());
$this->assertSame($user, $token->getUser());
$this->assertTrue($token->isAuthenticated());
@@ -31,7 +31,7 @@ class RememberMeTokenTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
*/
- public function testConstructorKeyCannotBeNull()
+ public function testConstructorSecretCannotBeNull()
{
new RememberMeToken(
$this->getUser(),
@@ -43,7 +43,7 @@ class RememberMeTokenTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
*/
- public function testConstructorKeyCannotBeEmptyString()
+ public function testConstructorSecretCannotBeEmptyString()
{
new RememberMeToken(
$this->getUser(),
diff --git a/Core/Tests/Authorization/AccessDecisionManagerTest.php b/Core/Tests/Authorization/AccessDecisionManagerTest.php
index 7a9ab08..412af91 100644
--- a/Core/Tests/Authorization/AccessDecisionManagerTest.php
+++ b/Core/Tests/Authorization/AccessDecisionManagerTest.php
@@ -16,6 +16,9 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
{
+ /**
+ * @group legacy
+ */
public function testSupportsClass()
{
$manager = new AccessDecisionManager(array(
@@ -31,6 +34,9 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($manager->supportsClass('FooClass'));
}
+ /**
+ * @group legacy
+ */
public function testSupportsAttribute()
{
$manager = new AccessDecisionManager(array(
@@ -49,14 +55,6 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
*/
- public function testSetVotersEmpty()
- {
- $manager = new AccessDecisionManager(array());
- }
-
- /**
- * @expectedException \InvalidArgumentException
- */
public function testSetUnsupportedStrategy()
{
new AccessDecisionManager(array($this->getVoter(VoterInterface::ACCESS_GRANTED)), 'fooBar');
diff --git a/Core/Tests/Authorization/Voter/AbstractVoterTest.php b/Core/Tests/Authorization/Voter/AbstractVoterTest.php
index 2ab943b..b537c1b 100644
--- a/Core/Tests/Authorization/Voter/AbstractVoterTest.php
+++ b/Core/Tests/Authorization/Voter/AbstractVoterTest.php
@@ -11,9 +11,11 @@
namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
-use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
+/**
+ * @group legacy
+ */
class AbstractVoterTest extends \PHPUnit_Framework_TestCase
{
protected $token;
@@ -49,26 +51,8 @@ class AbstractVoterTest extends \PHPUnit_Framework_TestCase
*/
public function testVote(array $attributes, $expectedVote, $object, $message)
{
- $voter = new AbstractVoterTest_Voter();
+ $voter = new Fixtures\MyVoter();
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
}
}
-
-class AbstractVoterTest_Voter extends AbstractVoter
-{
- protected function getSupportedClasses()
- {
- return array('stdClass');
- }
-
- protected function getSupportedAttributes()
- {
- return array('EDIT', 'CREATE');
- }
-
- protected function isGranted($attribute, $object, $user = null)
- {
- return 'EDIT' === $attribute;
- }
-}
diff --git a/Core/Tests/Authorization/Voter/Fixtures/MyVoter.php b/Core/Tests/Authorization/Voter/Fixtures/MyVoter.php
new file mode 100644
index 0000000..b75f798
--- /dev/null
+++ b/Core/Tests/Authorization/Voter/Fixtures/MyVoter.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Symfony\Component\Security\Core\Tests\Authorization\Voter\Fixtures;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
+
+/**
+ * @group legacy
+ */
+class MyVoter extends AbstractVoter
+{
+ protected function getSupportedClasses()
+ {
+ return array('stdClass');
+ }
+
+ protected function getSupportedAttributes()
+ {
+ return array('EDIT', 'CREATE');
+ }
+
+ protected function isGranted($attribute, $object, $user = null)
+ {
+ return 'EDIT' === $attribute;
+ }
+}
diff --git a/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php b/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php
index c50ecf3..4b03bac 100644
--- a/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php
+++ b/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php
@@ -33,4 +33,19 @@ class RoleHierarchyVoterTest extends RoleVoterTest
array(array('ROLE_FOO'), array('ROLE_FOOBAR'), VoterInterface::ACCESS_GRANTED),
));
}
+
+ /**
+ * @dataProvider getVoteWithEmptyHierarchyTests
+ */
+ public function testVoteWithEmptyHierarchy($roles, $attributes, $expected)
+ {
+ $voter = new RoleHierarchyVoter(new RoleHierarchy(array()));
+
+ $this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes));
+ }
+
+ public function getVoteWithEmptyHierarchyTests()
+ {
+ return parent::getVoteTests();
+ }
}
diff --git a/Core/Tests/Authorization/Voter/VoterTest.php b/Core/Tests/Authorization/Voter/VoterTest.php
new file mode 100644
index 0000000..4bac44d
--- /dev/null
+++ b/Core/Tests/Authorization/Voter/VoterTest.php
@@ -0,0 +1,70 @@
+<?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\Core\Tests\Authorization\Voter;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authorization\Voter\Voter;
+use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
+
+class VoterTest extends \PHPUnit_Framework_TestCase
+{
+ protected $token;
+
+ protected function setUp()
+ {
+ $this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ }
+
+ public function getTests()
+ {
+ return array(
+ array(array('EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute and class are supported and attribute grants access'),
+ array(array('CREATE'), VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if attribute and class are supported and attribute does not grant access'),
+
+ array(array('DELETE', 'EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute is supported and grants access'),
+ array(array('DELETE', 'CREATE'), VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if one attribute is supported and denies access'),
+
+ array(array('CREATE', 'EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute grants access'),
+
+ array(array('DELETE'), VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attribute is supported'),
+
+ array(array('EDIT'), VoterInterface::ACCESS_ABSTAIN, $this, 'ACCESS_ABSTAIN if class is not supported'),
+
+ array(array('EDIT'), VoterInterface::ACCESS_ABSTAIN, null, 'ACCESS_ABSTAIN if object is null'),
+
+ array(array(), VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attributes were provided'),
+ );
+ }
+
+ /**
+ * @dataProvider getTests
+ */
+ public function testVote(array $attributes, $expectedVote, $object, $message)
+ {
+ $voter = new VoterTest_Voter();
+
+ $this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
+ }
+}
+
+class VoterTest_Voter extends Voter
+{
+ protected function voteOnAttribute($attribute, $object, TokenInterface $token)
+ {
+ return 'EDIT' === $attribute;
+ }
+
+ protected function supports($attribute, $object)
+ {
+ return $object instanceof \stdClass && in_array($attribute, array('EDIT', 'CREATE'));
+ }
+}
diff --git a/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php b/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php
new file mode 100644
index 0000000..408dd2a
--- /dev/null
+++ b/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php
@@ -0,0 +1,26 @@
+<?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\Core\Tests\Exception;
+
+use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
+
+class CustomUserMessageAuthenticationExceptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testConstructWithSAfeMessage()
+ {
+ $e = new CustomUserMessageAuthenticationException('SAFE MESSAGE', array('foo' => true));
+
+ $this->assertEquals('SAFE MESSAGE', $e->getMessageKey());
+ $this->assertEquals(array('foo' => true), $e->getMessageData());
+ $this->assertEquals('SAFE MESSAGE', $e->getMessage());
+ }
+}
diff --git a/Core/Tests/LegacySecurityContextInterfaceTest.php b/Core/Tests/LegacySecurityContextInterfaceTest.php
deleted file mode 100644
index a45ecf9..0000000
--- a/Core/Tests/LegacySecurityContextInterfaceTest.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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\Core\Tests;
-
-use Symfony\Component\Security\Core\SecurityContextInterface;
-use Symfony\Component\Security\Core\Security;
-
-/**
- * @group legacy
- */
-class LegacySecurityContextInterfaceTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * Test if the BC Layer is working as intended.
- */
- public function testConstantSync()
- {
- $this->assertSame(Security::ACCESS_DENIED_ERROR, SecurityContextInterface::ACCESS_DENIED_ERROR);
- $this->assertSame(Security::AUTHENTICATION_ERROR, SecurityContextInterface::AUTHENTICATION_ERROR);
- $this->assertSame(Security::LAST_USERNAME, SecurityContextInterface::LAST_USERNAME);
- }
-}
diff --git a/Core/Tests/LegacySecurityContextTest.php b/Core/Tests/LegacySecurityContextTest.php
index fbb847e..4502261 100644
--- a/Core/Tests/LegacySecurityContextTest.php
+++ b/Core/Tests/LegacySecurityContextTest.php
@@ -11,7 +11,9 @@
namespace Symfony\Component\Security\Core\Tests;
+use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\SecurityContext;
+use Symfony\Component\Security\Core\SecurityContextInterface;
/**
* @group legacy
@@ -117,4 +119,14 @@ class LegacySecurityContextTest extends \PHPUnit_Framework_TestCase
array(true, null),
);
}
+
+ /**
+ * Test if the BC Layer is working as intended.
+ */
+ public function testConstantSync()
+ {
+ $this->assertSame(Security::ACCESS_DENIED_ERROR, SecurityContextInterface::ACCESS_DENIED_ERROR);
+ $this->assertSame(Security::AUTHENTICATION_ERROR, SecurityContextInterface::AUTHENTICATION_ERROR);
+ $this->assertSame(Security::LAST_USERNAME, SecurityContextInterface::LAST_USERNAME);
+ }
}
diff --git a/Core/Tests/User/LdapUserProviderTest.php b/Core/Tests/User/LdapUserProviderTest.php
new file mode 100644
index 0000000..9b126e9
--- /dev/null
+++ b/Core/Tests/User/LdapUserProviderTest.php
@@ -0,0 +1,105 @@
+<?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\Core\Tests\User;
+
+use Symfony\Component\Security\Core\User\LdapUserProvider;
+use Symfony\Component\Ldap\Exception\ConnectionException;
+
+/**
+ * @requires extension ldap
+ */
+class LdapUserProviderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ */
+ public function testLoadUserByUsernameFailsIfCantConnectToLdap()
+ {
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $ldap
+ ->expects($this->once())
+ ->method('bind')
+ ->will($this->throwException(new ConnectionException()))
+ ;
+
+ $provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
+ $provider->loadUserByUsername('foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ */
+ public function testLoadUserByUsernameFailsIfNoLdapEntries()
+ {
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $ldap
+ ->expects($this->once())
+ ->method('escape')
+ ->will($this->returnValue('foo'))
+ ;
+
+ $provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
+ $provider->loadUserByUsername('foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ */
+ public function testLoadUserByUsernameFailsIfMoreThanOneLdapEntry()
+ {
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $ldap
+ ->expects($this->once())
+ ->method('escape')
+ ->will($this->returnValue('foo'))
+ ;
+ $ldap
+ ->expects($this->once())
+ ->method('find')
+ ->will($this->returnValue(array(
+ array(),
+ array(),
+ 'count' => 2,
+ )))
+ ;
+
+ $provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
+ $provider->loadUserByUsername('foo');
+ }
+
+ public function testSuccessfulLoadUserByUsername()
+ {
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $ldap
+ ->expects($this->once())
+ ->method('escape')
+ ->will($this->returnValue('foo'))
+ ;
+ $ldap
+ ->expects($this->once())
+ ->method('find')
+ ->will($this->returnValue(array(
+ array(
+ 'sAMAccountName' => 'foo',
+ 'userpassword' => 'bar',
+ ),
+ 'count' => 1,
+ )))
+ ;
+
+ $provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');
+ $this->assertInstanceOf(
+ 'Symfony\Component\Security\Core\User\User',
+ $provider->loadUserByUsername('foo')
+ );
+ }
+}
diff --git a/Core/Tests/Util/ClassUtilsTest.php b/Core/Tests/Util/ClassUtilsTest.php
index e8f0143..b048206 100644
--- a/Core/Tests/Util/ClassUtilsTest.php
+++ b/Core/Tests/Util/ClassUtilsTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Security\Core\Tests\Util
{
use Symfony\Component\Security\Core\Util\ClassUtils;
+ /**
+ * @group legacy
+ */
class ClassUtilsTest extends \PHPUnit_Framework_TestCase
{
public static function dataGetClass()
diff --git a/Core/Tests/Util/StringUtilsTest.php b/Core/Tests/Util/StringUtilsTest.php
index faeaf25..78d9b05 100644
--- a/Core/Tests/Util/StringUtilsTest.php
+++ b/Core/Tests/Util/StringUtilsTest.php
@@ -15,6 +15,8 @@ use Symfony\Component\Security\Core\Util\StringUtils;
/**
* Data from PHP.net's hash_equals tests.
+ *
+ * @group legacy
*/
class StringUtilsTest extends \PHPUnit_Framework_TestCase
{
diff --git a/Core/User/LdapUserProvider.php b/Core/User/LdapUserProvider.php
new file mode 100644
index 0000000..1593564
--- /dev/null
+++ b/Core/User/LdapUserProvider.php
@@ -0,0 +1,108 @@
+<?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\Core\User;
+
+use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
+use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+use Symfony\Component\Ldap\Exception\ConnectionException;
+use Symfony\Component\Ldap\LdapClientInterface;
+
+/**
+ * LdapUserProvider is a simple user provider on top of ldap.
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ * @author Charles Sarrazin <charles@sarraz.in>
+ */
+class LdapUserProvider implements UserProviderInterface
+{
+ private $ldap;
+ private $baseDn;
+ private $searchDn;
+ private $searchPassword;
+ private $defaultRoles;
+ private $defaultSearch;
+
+ /**
+ * @param LdapClientInterface $ldap
+ * @param string $baseDn
+ * @param string $searchDn
+ * @param string $searchPassword
+ * @param array $defaultRoles
+ * @param string $uidKey
+ * @param string $filter
+ */
+ public function __construct(LdapClientInterface $ldap, $baseDn, $searchDn = null, $searchPassword = null, array $defaultRoles = array(), $uidKey = 'sAMAccountName', $filter = '({uid_key}={username})')
+ {
+ $this->ldap = $ldap;
+ $this->baseDn = $baseDn;
+ $this->searchDn = $searchDn;
+ $this->searchPassword = $searchPassword;
+ $this->defaultRoles = $defaultRoles;
+ $this->defaultSearch = str_replace('{uid_key}', $uidKey, $filter);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadUserByUsername($username)
+ {
+ try {
+ $this->ldap->bind($this->searchDn, $this->searchPassword);
+ $username = $this->ldap->escape($username, '', LDAP_ESCAPE_FILTER);
+ $query = str_replace('{username}', $username, $this->defaultSearch);
+ $search = $this->ldap->find($this->baseDn, $query);
+ } catch (ConnectionException $e) {
+ throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username), 0, $e);
+ }
+
+ if (!$search) {
+ throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
+ }
+
+ if ($search['count'] > 1) {
+ throw new UsernameNotFoundException('More than one user found');
+ }
+
+ $user = $search[0];
+
+ return $this->loadUser($username, $user);
+ }
+
+ public function loadUser($username, $user)
+ {
+ $password = isset($user['userpassword']) ? $user['userpassword'] : null;
+
+ $roles = $this->defaultRoles;
+
+ return new User($username, $password, $roles);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function refreshUser(UserInterface $user)
+ {
+ if (!$user instanceof User) {
+ throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
+ }
+
+ return new User($user->getUsername(), null, $user->getRoles());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsClass($class)
+ {
+ return $class === 'Symfony\Component\Security\Core\User\User';
+ }
+}
diff --git a/Core/User/UserCheckerInterface.php b/Core/User/UserCheckerInterface.php
index 3dd8d51..62ea9f0 100644
--- a/Core/User/UserCheckerInterface.php
+++ b/Core/User/UserCheckerInterface.php
@@ -11,10 +11,13 @@
namespace Symfony\Component\Security\Core\User;
+use Symfony\Component\Security\Core\Exception\AccountStatusException;
+
/**
- * UserCheckerInterface checks user account when authentication occurs.
+ * Implement to throw AccountStatusException during the authentication process.
*
- * This should not be used to make authentication decisions.
+ * Can be used when you want to check the account status, e.g when the account is
+ * disabled or blocked. This should not be used to make authentication decisions.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@@ -24,6 +27,8 @@ interface UserCheckerInterface
* Checks the user account before authentication.
*
* @param UserInterface $user a UserInterface instance
+ *
+ * @throws AccountStatusException
*/
public function checkPreAuth(UserInterface $user);
@@ -31,6 +36,8 @@ interface UserCheckerInterface
* Checks the user account after authentication.
*
* @param UserInterface $user a UserInterface instance
+ *
+ * @throws AccountStatusException
*/
public function checkPostAuth(UserInterface $user);
}
diff --git a/Core/User/UserProviderInterface.php b/Core/User/UserProviderInterface.php
index d17e3b7..146ed65 100644
--- a/Core/User/UserProviderInterface.php
+++ b/Core/User/UserProviderInterface.php
@@ -43,8 +43,6 @@ interface UserProviderInterface
*
* @return UserInterface
*
- * @see UsernameNotFoundException
- *
* @throws UsernameNotFoundException if the user is not found
*/
public function loadUserByUsername($username);
diff --git a/Core/Util/ClassUtils.php b/Core/Util/ClassUtils.php
index 6c87096..06186ef 100644
--- a/Core/Util/ClassUtils.php
+++ b/Core/Util/ClassUtils.php
@@ -11,13 +11,15 @@
namespace Symfony\Component\Security\Core\Util;
-use Doctrine\Common\Util\ClassUtils as DoctrineClassUtils;
+use Symfony\Component\Security\Acl\Util\ClassUtils as AclClassUtils;
+
+@trigger_error('The '.__NAMESPACE__.'\ClassUtils class is deprecated since version 2.8, to be removed in 3.0. Use Symfony\Component\Security\Acl\Util\ClassUtils instead.', E_USER_DEPRECATED);
/**
* Class related functionality for objects that
* might or might not be proxy objects at the moment.
*
- * @see DoctrineClassUtils
+ * @deprecated ClassUtils is deprecated since version 2.8, to be removed in 3.0. Use Acl ClassUtils instead.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Johannes Schmitt <schmittjoh@gmail.com>
@@ -54,6 +56,11 @@ class ClassUtils
*/
public static function getRealClass($object)
{
+ if (class_exists('Symfony\Component\Security\Acl\Util\ClassUtils')) {
+ return AclClassUtils::getRealClass($object);
+ }
+
+ // fallback in case security-acl is not installed
$class = is_object($object) ? get_class($object) : $object;
if (false === $pos = strrpos($class, '\\'.self::MARKER.'\\')) {
diff --git a/Core/Util/SecureRandom.php b/Core/Util/SecureRandom.php
index 478f556..06ed893 100644
--- a/Core/Util/SecureRandom.php
+++ b/Core/Util/SecureRandom.php
@@ -11,11 +11,15 @@
namespace Symfony\Component\Security\Core\Util;
+@trigger_error('The '.__NAMESPACE__.'\SecureRandom class is deprecated since version 2.8 and will be removed in 3.0. Use the random_bytes() function instead.', E_USER_DEPRECATED);
+
/**
* A secure random number generator implementation.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * @deprecated since version 2.8, to be removed in 3.0. Use the random_bytes function instead
*/
final class SecureRandom implements SecureRandomInterface
{
diff --git a/Core/Util/SecureRandomInterface.php b/Core/Util/SecureRandomInterface.php
index 87d3ace..df5509b 100644
--- a/Core/Util/SecureRandomInterface.php
+++ b/Core/Util/SecureRandomInterface.php
@@ -15,6 +15,8 @@ namespace Symfony\Component\Security\Core\Util;
* Interface that needs to be implemented by all secure random number generators.
*
* @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @deprecated since version 2.8, to be removed in 3.0. Use the random_bytes function instead
*/
interface SecureRandomInterface
{
diff --git a/Core/Util/StringUtils.php b/Core/Util/StringUtils.php
index 343585c..bb0c8b2 100644
--- a/Core/Util/StringUtils.php
+++ b/Core/Util/StringUtils.php
@@ -11,10 +11,16 @@
namespace Symfony\Component\Security\Core\Util;
+@trigger_error('The '.__NAMESPACE__.'\\StringUtils class is deprecated since version 2.8 and will be removed in 3.0. Use hash_equals() instead.', E_USER_DEPRECATED);
+
+use Symfony\Polyfill\Util\Binary;
+
/**
* String utility functions.
*
* @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @deprecated since 2.8, to be removed in 3.0.
*/
class StringUtils
{
@@ -47,25 +53,7 @@ class StringUtils
$userInput = (string) $userInput;
}
- if (function_exists('hash_equals')) {
- return hash_equals($knownString, $userInput);
- }
-
- $knownLen = self::safeStrlen($knownString);
- $userLen = self::safeStrlen($userInput);
-
- if ($userLen !== $knownLen) {
- return false;
- }
-
- $result = 0;
-
- for ($i = 0; $i < $knownLen; ++$i) {
- $result |= (ord($knownString[$i]) ^ ord($userInput[$i]));
- }
-
- // They are only identical strings if $result is exactly 0...
- return 0 === $result;
+ return hash_equals($knownString, $userInput);
}
/**
@@ -77,17 +65,6 @@ class StringUtils
*/
public static function safeStrlen($string)
{
- // Premature optimization
- // Since this cannot be changed at runtime, we can cache it
- static $funcExists = null;
- if (null === $funcExists) {
- $funcExists = function_exists('mb_strlen');
- }
-
- if ($funcExists) {
- return mb_strlen($string, '8bit');
- }
-
- return strlen($string);
+ return Binary::strlen($string);
}
}
diff --git a/Core/composer.json b/Core/composer.json
index 354c55e..3362971 100644
--- a/Core/composer.json
+++ b/Core/composer.json
@@ -17,22 +17,25 @@
],
"require": {
"php": ">=5.3.9",
- "paragonie/random_compat": "~1.0"
+ "symfony/polyfill-php55": "~1.0",
+ "symfony/polyfill-php56": "~1.0",
+ "symfony/polyfill-php70": "~1.0",
+ "symfony/polyfill-util": "~1.0"
},
"require-dev": {
- "symfony/event-dispatcher": "~2.1",
- "symfony/expression-language": "~2.6",
- "symfony/http-foundation": "~2.4",
- "symfony/validator": "~2.5,>=2.5.9",
- "psr/log": "~1.0",
- "ircmaxell/password-compat": "1.0.*"
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/http-foundation": "~2.4|~3.0.0",
+ "symfony/ldap": "~2.8|~3.0.0",
+ "symfony/validator": "~2.5,>=2.5.9|~3.0.0",
+ "psr/log": "~1.0"
},
"suggest": {
"symfony/event-dispatcher": "",
"symfony/http-foundation": "",
"symfony/validator": "For using the user password constraint",
"symfony/expression-language": "For using the expression voter",
- "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5"
+ "symfony/ldap": "For using LDAP integration"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Security\\Core\\": "" },
@@ -43,7 +46,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
}
}
diff --git a/Csrf/CsrfTokenManager.php b/Csrf/CsrfTokenManager.php
index e129502..cdda543 100644
--- a/Csrf/CsrfTokenManager.php
+++ b/Csrf/CsrfTokenManager.php
@@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Csrf;
-use Symfony\Component\Security\Core\Util\StringUtils;
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage;
@@ -92,6 +91,6 @@ class CsrfTokenManager implements CsrfTokenManagerInterface
return false;
}
- return StringUtils::equals($this->storage->getToken($token->getId()), $token->getValue());
+ return hash_equals($this->storage->getToken($token->getId()), $token->getValue());
}
}
diff --git a/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php b/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php
index 1b325e5..e4ea80c 100644
--- a/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php
+++ b/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php
@@ -44,8 +44,7 @@ class UriSafeTokenGeneratorTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
- $this->random = $this->getMock('Symfony\Component\Security\Core\Util\SecureRandomInterface');
- $this->generator = new UriSafeTokenGenerator($this->random, self::ENTROPY);
+ $this->generator = new UriSafeTokenGenerator(self::ENTROPY);
}
protected function tearDown()
@@ -56,11 +55,6 @@ class UriSafeTokenGeneratorTest extends \PHPUnit_Framework_TestCase
public function testGenerateToken()
{
- $this->random->expects($this->once())
- ->method('nextBytes')
- ->with(self::ENTROPY / 8)
- ->will($this->returnValue(self::$bytes));
-
$token = $this->generator->generateToken();
$this->assertTrue(ctype_print($token), 'is printable');
diff --git a/Csrf/TokenGenerator/UriSafeTokenGenerator.php b/Csrf/TokenGenerator/UriSafeTokenGenerator.php
index 31e82ee..432adf2 100644
--- a/Csrf/TokenGenerator/UriSafeTokenGenerator.php
+++ b/Csrf/TokenGenerator/UriSafeTokenGenerator.php
@@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Csrf\TokenGenerator;
use Symfony\Component\Security\Core\Util\SecureRandomInterface;
-use Symfony\Component\Security\Core\Util\SecureRandom;
/**
* Generates CSRF tokens.
@@ -22,13 +21,6 @@ use Symfony\Component\Security\Core\Util\SecureRandom;
class UriSafeTokenGenerator implements TokenGeneratorInterface
{
/**
- * The generator for random values.
- *
- * @var SecureRandomInterface
- */
- private $random;
-
- /**
* The amount of entropy collected for each token (in bits).
*
* @var int
@@ -38,15 +30,17 @@ class UriSafeTokenGenerator implements TokenGeneratorInterface
/**
* Generates URI-safe CSRF tokens.
*
- * @param SecureRandomInterface|null $random The random value generator used for
- * generating entropy
- * @param int $entropy The amount of entropy collected for
- * each token (in bits)
+ * @param int $entropy The amount of entropy collected for each token (in bits)
*/
- public function __construct(SecureRandomInterface $random = null, $entropy = 256)
+ public function __construct($entropy = 256)
{
- $this->random = $random ?: new SecureRandom();
- $this->entropy = $entropy;
+ if ($entropy instanceof SecureRandomInterface || func_num_args() === 2) {
+ @trigger_error('The '.__METHOD__.' method now requires the entropy to be given as the first argument. The SecureRandomInterface will be removed in 3.0.', E_USER_DEPRECATED);
+
+ $this->entropy = func_num_args() === 2 ? func_get_arg(1) : 256;
+ } else {
+ $this->entropy = $entropy;
+ }
}
/**
@@ -57,7 +51,7 @@ class UriSafeTokenGenerator implements TokenGeneratorInterface
// Generate an URI safe base64 encoded string that does not contain "+",
// "/" or "=" which need to be URL encoded and make URLs unnecessarily
// longer.
- $bytes = $this->random->nextBytes($this->entropy / 8);
+ $bytes = random_bytes($this->entropy / 8);
return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '=');
}
diff --git a/Csrf/composer.json b/Csrf/composer.json
index 2930e32..4afc7ca 100644
--- a/Csrf/composer.json
+++ b/Csrf/composer.json
@@ -17,10 +17,12 @@
],
"require": {
"php": ">=5.3.9",
- "symfony/security-core": "~2.4"
+ "symfony/polyfill-php56": "~1.0",
+ "symfony/polyfill-php70": "~1.0",
+ "symfony/security-core": "~2.4|~3.0.0"
},
"require-dev": {
- "symfony/http-foundation": "~2.1"
+ "symfony/http-foundation": "~2.1|~3.0.0"
},
"suggest": {
"symfony/http-foundation": "For using the class SessionTokenStorage."
@@ -34,7 +36,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
}
}
diff --git a/Acl/.gitignore b/Guard/.gitignore
index c49a5d8..c49a5d8 100644
--- a/Acl/.gitignore
+++ b/Guard/.gitignore
diff --git a/Guard/AbstractGuardAuthenticator.php b/Guard/AbstractGuardAuthenticator.php
new file mode 100644
index 0000000..609d772
--- /dev/null
+++ b/Guard/AbstractGuardAuthenticator.php
@@ -0,0 +1,41 @@
+<?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\Guard;
+
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
+
+/**
+ * An optional base class that creates a PostAuthenticationGuardToken for you.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+abstract class AbstractGuardAuthenticator implements GuardAuthenticatorInterface
+{
+ /**
+ * Shortcut to create a PostAuthenticationGuardToken for you, if you don't really
+ * care about which authenticated token you're using.
+ *
+ * @param UserInterface $user
+ * @param string $providerKey
+ *
+ * @return PostAuthenticationGuardToken
+ */
+ public function createAuthenticatedToken(UserInterface $user, $providerKey)
+ {
+ return new PostAuthenticationGuardToken(
+ $user,
+ $providerKey,
+ $user->getRoles()
+ );
+ }
+}
diff --git a/Guard/Authenticator/AbstractFormLoginAuthenticator.php b/Guard/Authenticator/AbstractFormLoginAuthenticator.php
new file mode 100644
index 0000000..6d6d14e
--- /dev/null
+++ b/Guard/Authenticator/AbstractFormLoginAuthenticator.php
@@ -0,0 +1,111 @@
+<?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\Guard\Authenticator;
+
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * A base class to make form login authentication easier!
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+abstract class AbstractFormLoginAuthenticator extends AbstractGuardAuthenticator
+{
+ /**
+ * Return the URL to the login page.
+ *
+ * @return string
+ */
+ abstract protected function getLoginUrl();
+
+ /**
+ * The user will be redirected to the secure page they originally tried
+ * to access. But if no such page exists (i.e. the user went to the
+ * login page directly), this returns the URL the user should be redirected
+ * to after logging in successfully (e.g. your homepage).
+ *
+ * @return string
+ */
+ abstract protected function getDefaultSuccessRedirectUrl();
+
+ /**
+ * Override to change what happens after a bad username/password is submitted.
+ *
+ * @param Request $request
+ * @param AuthenticationException $exception
+ *
+ * @return RedirectResponse
+ */
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+ {
+ if ($request->getSession() instanceof SessionInterface) {
+ $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
+ }
+
+ $url = $this->getLoginUrl();
+
+ return new RedirectResponse($url);
+ }
+
+ /**
+ * Override to change what happens after successful authentication.
+ *
+ * @param Request $request
+ * @param TokenInterface $token
+ * @param string $providerKey
+ *
+ * @return RedirectResponse
+ */
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
+ {
+ $targetPath = null;
+
+ // if the user hit a secure page and start() was called, this was
+ // the URL they were on, and probably where you want to redirect to
+ if ($request->getSession() instanceof SessionInterface) {
+ $targetPath = $request->getSession()->get('_security.'.$providerKey.'.target_path');
+ }
+
+ if (!$targetPath) {
+ $targetPath = $this->getDefaultSuccessRedirectUrl();
+ }
+
+ return new RedirectResponse($targetPath);
+ }
+
+ public function supportsRememberMe()
+ {
+ return true;
+ }
+
+ /**
+ * Override to control what happens when the user hits a secure page
+ * but isn't logged in yet.
+ *
+ * @param Request $request
+ * @param AuthenticationException|null $authException
+ *
+ * @return RedirectResponse
+ */
+ public function start(Request $request, AuthenticationException $authException = null)
+ {
+ $url = $this->getLoginUrl();
+
+ return new RedirectResponse($url);
+ }
+}
diff --git a/Guard/Firewall/GuardAuthenticationListener.php b/Guard/Firewall/GuardAuthenticationListener.php
new file mode 100644
index 0000000..ed0a36e
--- /dev/null
+++ b/Guard/Firewall/GuardAuthenticationListener.php
@@ -0,0 +1,201 @@
+<?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\Guard\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
+use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
+use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
+use Symfony\Component\Security\Guard\GuardAuthenticatorInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Http\Firewall\ListenerInterface;
+use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
+
+/**
+ * Authentication listener for the "guard" system.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class GuardAuthenticationListener implements ListenerInterface
+{
+ private $guardHandler;
+ private $authenticationManager;
+ private $providerKey;
+ private $guardAuthenticators;
+ private $logger;
+ private $rememberMeServices;
+
+ /**
+ * @param GuardAuthenticatorHandler $guardHandler The Guard handler
+ * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance
+ * @param string $providerKey The provider (i.e. firewall) key
+ * @param GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
+ * @param LoggerInterface $logger A LoggerInterface instance
+ */
+ public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, $providerKey, array $guardAuthenticators, LoggerInterface $logger = null)
+ {
+ if (empty($providerKey)) {
+ throw new \InvalidArgumentException('$providerKey must not be empty.');
+ }
+
+ $this->guardHandler = $guardHandler;
+ $this->authenticationManager = $authenticationManager;
+ $this->providerKey = $providerKey;
+ $this->guardAuthenticators = $guardAuthenticators;
+ $this->logger = $logger;
+ }
+
+ /**
+ * Iterates over each authenticator to see if each wants to authenticate the request.
+ *
+ * @param GetResponseEvent $event
+ */
+ public function handle(GetResponseEvent $event)
+ {
+ if (null !== $this->logger) {
+ $this->logger->debug('Checking for guard authentication credentials.', array('firewall_key' => $this->providerKey, 'authenticators' => count($this->guardAuthenticators)));
+ }
+
+ foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
+ // get a key that's unique to *this* guard authenticator
+ // this MUST be the same as GuardAuthenticationProvider
+ $uniqueGuardKey = $this->providerKey.'_'.$key;
+
+ $this->executeGuardAuthenticator($uniqueGuardKey, $guardAuthenticator, $event);
+
+ if ($event->hasResponse()) {
+ if (null !== $this->logger) {
+ $this->logger->debug(sprintf('The "%s" authenticator set the response. Any later authenticator will not be called', get_class($guardAuthenticator)));
+ }
+
+ break;
+ }
+ }
+ }
+
+ private function executeGuardAuthenticator($uniqueGuardKey, GuardAuthenticatorInterface $guardAuthenticator, GetResponseEvent $event)
+ {
+ $request = $event->getRequest();
+ try {
+ if (null !== $this->logger) {
+ $this->logger->debug('Calling getCredentials() on guard configurator.', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
+ }
+
+ // allow the authenticator to fetch authentication info from the request
+ $credentials = $guardAuthenticator->getCredentials($request);
+
+ // allow null to be returned to skip authentication
+ if (null === $credentials) {
+ return;
+ }
+
+ // create a token with the unique key, so that the provider knows which authenticator to use
+ $token = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey);
+
+ if (null !== $this->logger) {
+ $this->logger->debug('Passing guard token information to the GuardAuthenticationProvider', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
+ }
+ // pass the token into the AuthenticationManager system
+ // this indirectly calls GuardAuthenticationProvider::authenticate()
+ $token = $this->authenticationManager->authenticate($token);
+
+ if (null !== $this->logger) {
+ $this->logger->info('Guard authentication successful!', array('token' => $token, 'authenticator' => get_class($guardAuthenticator)));
+ }
+
+ // sets the token on the token storage, etc
+ $this->guardHandler->authenticateWithToken($token, $request);
+ } catch (AuthenticationException $e) {
+ // oh no! Authentication failed!
+
+ if (null !== $this->logger) {
+ $this->logger->info('Guard authentication failed.', array('exception' => $e, 'authenticator' => get_class($guardAuthenticator)));
+ }
+
+ $response = $this->guardHandler->handleAuthenticationFailure($e, $request, $guardAuthenticator, $this->providerKey);
+
+ if ($response instanceof Response) {
+ $event->setResponse($response);
+ }
+
+ return;
+ }
+
+ // success!
+ $response = $this->guardHandler->handleAuthenticationSuccess($token, $request, $guardAuthenticator, $this->providerKey);
+ if ($response instanceof Response) {
+ if (null !== $this->logger) {
+ $this->logger->debug('Guard authenticator set success response.', array('response' => $response, 'authenticator' => get_class($guardAuthenticator)));
+ }
+
+ $event->setResponse($response);
+ } else {
+ if (null !== $this->logger) {
+ $this->logger->debug('Guard authenticator set no success response: request continues.', array('authenticator' => get_class($guardAuthenticator)));
+ }
+ }
+
+ // attempt to trigger the remember me functionality
+ $this->triggerRememberMe($guardAuthenticator, $request, $token, $response);
+ }
+
+ /**
+ * Should be called if this listener will support remember me.
+ *
+ * @param RememberMeServicesInterface $rememberMeServices
+ */
+ public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices)
+ {
+ $this->rememberMeServices = $rememberMeServices;
+ }
+
+ /**
+ * Checks to see if remember me is supported in the authenticator and
+ * on the firewall. If it is, the RememberMeServicesInterface is notified.
+ *
+ * @param GuardAuthenticatorInterface $guardAuthenticator
+ * @param Request $request
+ * @param TokenInterface $token
+ * @param Response $response
+ */
+ private function triggerRememberMe(GuardAuthenticatorInterface $guardAuthenticator, Request $request, TokenInterface $token, Response $response = null)
+ {
+ if (null === $this->rememberMeServices) {
+ if (null !== $this->logger) {
+ $this->logger->debug('Remember me skipped: it is not configured for the firewall.', array('authenticator' => get_class($guardAuthenticator)));
+ }
+
+ return;
+ }
+
+ if (!$guardAuthenticator->supportsRememberMe()) {
+ if (null !== $this->logger) {
+ $this->logger->debug('Remember me skipped: your authenticator does not support it.', array('authenticator' => get_class($guardAuthenticator)));
+ }
+
+ return;
+ }
+
+ if (!$response instanceof Response) {
+ throw new \LogicException(sprintf(
+ '%s::onAuthenticationSuccess *must* return a Response if you want to use the remember me functionality. Return a Response, or set remember_me to false under the guard configuration.',
+ get_class($guardAuthenticator)
+ ));
+ }
+
+ $this->rememberMeServices->loginSuccess($request, $response, $token);
+ }
+}
diff --git a/Guard/GuardAuthenticatorHandler.php b/Guard/GuardAuthenticatorHandler.php
new file mode 100644
index 0000000..5e1351d
--- /dev/null
+++ b/Guard/GuardAuthenticatorHandler.php
@@ -0,0 +1,139 @@
+<?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\Guard;
+
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
+use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
+use Symfony\Component\Security\Http\SecurityEvents;
+
+/**
+ * A utility class that does much of the *work* during the guard authentication process.
+ *
+ * By having the logic here instead of the listener, more of the process
+ * can be called directly (e.g. for manual authentication) or overridden.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class GuardAuthenticatorHandler
+{
+ private $tokenStorage;
+
+ private $dispatcher;
+
+ public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher = null)
+ {
+ $this->tokenStorage = $tokenStorage;
+ $this->dispatcher = $eventDispatcher;
+ }
+
+ /**
+ * Authenticates the given token in the system.
+ *
+ * @param TokenInterface $token
+ * @param Request $request
+ */
+ public function authenticateWithToken(TokenInterface $token, Request $request)
+ {
+ $this->tokenStorage->setToken($token);
+
+ if (null !== $this->dispatcher) {
+ $loginEvent = new InteractiveLoginEvent($request, $token);
+ $this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent);
+ }
+ }
+
+ /**
+ * Returns the "on success" response for the given GuardAuthenticator.
+ *
+ * @param TokenInterface $token
+ * @param Request $request
+ * @param GuardAuthenticatorInterface $guardAuthenticator
+ * @param string $providerKey The provider (i.e. firewall) key
+ *
+ * @return null|Response
+ */
+ public function handleAuthenticationSuccess(TokenInterface $token, Request $request, GuardAuthenticatorInterface $guardAuthenticator, $providerKey)
+ {
+ $response = $guardAuthenticator->onAuthenticationSuccess($request, $token, $providerKey);
+
+ // check that it's a Response or null
+ if ($response instanceof Response || null === $response) {
+ return $response;
+ }
+
+ throw new \UnexpectedValueException(sprintf(
+ 'The %s::onAuthenticationSuccess method must return null or a Response object. You returned %s.',
+ get_class($guardAuthenticator),
+ is_object($response) ? get_class($response) : gettype($response)
+ ));
+ }
+
+ /**
+ * Convenience method for authenticating the user and returning the
+ * Response *if any* for success.
+ *
+ * @param UserInterface $user
+ * @param Request $request
+ * @param GuardAuthenticatorInterface $authenticator
+ * @param string $providerKey The provider (i.e. firewall) key
+ *
+ * @return Response|null
+ */
+ public function authenticateUserAndHandleSuccess(UserInterface $user, Request $request, GuardAuthenticatorInterface $authenticator, $providerKey)
+ {
+ // create an authenticated token for the User
+ $token = $authenticator->createAuthenticatedToken($user, $providerKey);
+ // authenticate this in the system
+ $this->authenticateWithToken($token, $request);
+
+ // return the success metric
+ return $this->handleAuthenticationSuccess($token, $request, $authenticator, $providerKey);
+ }
+
+ /**
+ * Handles an authentication failure and returns the Response for the
+ * GuardAuthenticator.
+ *
+ * @param AuthenticationException $authenticationException
+ * @param Request $request
+ * @param GuardAuthenticatorInterface $guardAuthenticator
+ * @param string $providerKey The key of the firewall
+ *
+ * @return null|Response
+ */
+ public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, GuardAuthenticatorInterface $guardAuthenticator, $providerKey)
+ {
+ $token = $this->tokenStorage->getToken();
+ if ($token instanceof PostAuthenticationGuardToken && $providerKey === $token->getProviderKey()) {
+ $this->tokenStorage->setToken(null);
+ }
+
+ $response = $guardAuthenticator->onAuthenticationFailure($request, $authenticationException);
+ if ($response instanceof Response || null === $response) {
+ // returning null is ok, it means they want the request to continue
+ return $response;
+ }
+
+ throw new \UnexpectedValueException(sprintf(
+ 'The %s::onAuthenticationFailure method must return null or a Response object. You returned %s.',
+ get_class($guardAuthenticator),
+ is_object($response) ? get_class($response) : gettype($response)
+ ));
+ }
+}
diff --git a/Guard/GuardAuthenticatorInterface.php b/Guard/GuardAuthenticatorInterface.php
new file mode 100644
index 0000000..b28f06d
--- /dev/null
+++ b/Guard/GuardAuthenticatorInterface.php
@@ -0,0 +1,160 @@
+<?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\Guard;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
+use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
+
+/**
+ * The interface for all "guard" authenticators.
+ *
+ * The methods on this interface are called throughout the guard authentication
+ * process to give you the power to control most parts of the process from
+ * one location.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+interface GuardAuthenticatorInterface extends AuthenticationEntryPointInterface
+{
+ /**
+ * Get the authentication credentials from the request and return them
+ * as any type (e.g. an associate array). If you return null, authentication
+ * will be skipped.
+ *
+ * Whatever value you return here will be passed to getUser() and checkCredentials()
+ *
+ * For example, for a form login, you might:
+ *
+ * if ($request->request->has('_username')) {
+ * return array(
+ * 'username' => $request->request->get('_username'),
+ * 'password' => $request->request->get('_password'),
+ * );
+ * } else {
+ * return;
+ * }
+ *
+ * Or for an API token that's on a header, you might use:
+ *
+ * return array('api_key' => $request->headers->get('X-API-TOKEN'));
+ *
+ * @param Request $request
+ *
+ * @return mixed|null
+ */
+ public function getCredentials(Request $request);
+
+ /**
+ * Return a UserInterface object based on the credentials.
+ *
+ * The *credentials* are the return value from getCredentials()
+ *
+ * You may throw an AuthenticationException if you wish. If you return
+ * null, then a UsernameNotFoundException is thrown for you.
+ *
+ * @param mixed $credentials
+ * @param UserProviderInterface $userProvider
+ *
+ * @throws AuthenticationException
+ *
+ * @return UserInterface|null
+ */
+ public function getUser($credentials, UserProviderInterface $userProvider);
+
+ /**
+ * Returns true if the credentials are valid.
+ *
+ * If any value other than true is returned, authentication will
+ * fail. You may also throw an AuthenticationException if you wish
+ * to cause authentication to fail.
+ *
+ * The *credentials* are the return value from getCredentials()
+ *
+ * @param mixed $credentials
+ * @param UserInterface $user
+ *
+ * @return bool
+ *
+ * @throws AuthenticationException
+ */
+ public function checkCredentials($credentials, UserInterface $user);
+
+ /**
+ * Create an authenticated token for the given user.
+ *
+ * If you don't care about which token class is used or don't really
+ * understand what a "token" is, you can skip this method by extending
+ * the AbstractGuardAuthenticator class from your authenticator.
+ *
+ * @see AbstractGuardAuthenticator
+ *
+ * @param UserInterface $user
+ * @param string $providerKey The provider (i.e. firewall) key
+ *
+ * @return GuardTokenInterface
+ */
+ public function createAuthenticatedToken(UserInterface $user, $providerKey);
+
+ /**
+ * Called when authentication executed, but failed (e.g. wrong username password).
+ *
+ * This should return the Response sent back to the user, like a
+ * RedirectResponse to the login page or a 403 response.
+ *
+ * If you return null, the request will continue, but the user will
+ * not be authenticated. This is probably not what you want to do.
+ *
+ * @param Request $request
+ * @param AuthenticationException $exception
+ *
+ * @return Response|null
+ */
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception);
+
+ /**
+ * Called when authentication executed and was successful!
+ *
+ * This should return the Response sent back to the user, like a
+ * RedirectResponse to the last page they visited.
+ *
+ * If you return null, the current request will continue, and the user
+ * will be authenticated. This makes sense, for example, with an API.
+ *
+ * @param Request $request
+ * @param TokenInterface $token
+ * @param string $providerKey The provider (i.e. firewall) key
+ *
+ * @return Response|null
+ */
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey);
+
+ /**
+ * Does this method support remember me cookies?
+ *
+ * Remember me cookie will be set if *all* of the following are met:
+ * A) This method returns true
+ * B) The remember_me key under your firewall is configured
+ * C) The "remember me" functionality is activated. This is usually
+ * done by having a _remember_me checkbox in your form, but
+ * can be configured by the "always_remember_me" and "remember_me_parameter"
+ * parameters under the "remember_me" firewall key
+ *
+ * @return bool
+ */
+ public function supportsRememberMe();
+}
diff --git a/Acl/LICENSE b/Guard/LICENSE
index 12a7453..12a7453 100644
--- a/Acl/LICENSE
+++ b/Guard/LICENSE
diff --git a/Guard/Provider/GuardAuthenticationProvider.php b/Guard/Provider/GuardAuthenticationProvider.php
new file mode 100644
index 0000000..4347e02
--- /dev/null
+++ b/Guard/Provider/GuardAuthenticationProvider.php
@@ -0,0 +1,148 @@
+<?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\Guard\Provider;
+
+use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
+use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+use Symfony\Component\Security\Guard\GuardAuthenticatorInterface;
+use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
+use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
+use Symfony\Component\Security\Core\User\UserCheckerInterface;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException;
+
+/**
+ * Responsible for accepting the PreAuthenticationGuardToken and calling
+ * the correct authenticator to retrieve the authenticated token.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class GuardAuthenticationProvider implements AuthenticationProviderInterface
+{
+ /**
+ * @var GuardAuthenticatorInterface[]
+ */
+ private $guardAuthenticators;
+ private $userProvider;
+ private $providerKey;
+ private $userChecker;
+
+ /**
+ * @param GuardAuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener
+ * @param UserProviderInterface $userProvider The user provider
+ * @param string $providerKey The provider (i.e. firewall) key
+ * @param UserCheckerInterface $userChecker
+ */
+ public function __construct(array $guardAuthenticators, UserProviderInterface $userProvider, $providerKey, UserCheckerInterface $userChecker)
+ {
+ $this->guardAuthenticators = $guardAuthenticators;
+ $this->userProvider = $userProvider;
+ $this->providerKey = $providerKey;
+ $this->userChecker = $userChecker;
+ }
+
+ /**
+ * Finds the correct authenticator for the token and calls it.
+ *
+ * @param GuardTokenInterface $token
+ *
+ * @return TokenInterface
+ */
+ public function authenticate(TokenInterface $token)
+ {
+ if (!$this->supports($token)) {
+ throw new \InvalidArgumentException('GuardAuthenticationProvider only supports GuardTokenInterface.');
+ }
+
+ if (!$token instanceof PreAuthenticationGuardToken) {
+ /*
+ * The listener *only* passes PreAuthenticationGuardToken instances.
+ * This means that an authenticated token (e.g. PostAuthenticationGuardToken)
+ * is being passed here, which happens if that token becomes
+ * "not authenticated" (e.g. happens if the user changes between
+ * requests). In this case, the user should be logged out, so
+ * we will return an AnonymousToken to accomplish that.
+ */
+
+ // this should never happen - but technically, the token is
+ // authenticated... so it could just be returned
+ if ($token->isAuthenticated()) {
+ return $token;
+ }
+
+ // this AccountStatusException causes the user to be logged out
+ throw new AuthenticationExpiredException();
+ }
+
+ // find the *one* GuardAuthenticator that this token originated from
+ foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
+ // get a key that's unique to *this* guard authenticator
+ // this MUST be the same as GuardAuthenticationListener
+ $uniqueGuardKey = $this->providerKey.'_'.$key;
+
+ if ($uniqueGuardKey == $token->getGuardProviderKey()) {
+ return $this->authenticateViaGuard($guardAuthenticator, $token);
+ }
+ }
+
+ // no matching authenticator found - but there will be multiple GuardAuthenticationProvider
+ // instances that will be checked if you have multiple firewalls.
+ }
+
+ private function authenticateViaGuard(GuardAuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token)
+ {
+ // get the user from the GuardAuthenticator
+ $user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider);
+
+ if (null === $user) {
+ throw new UsernameNotFoundException(sprintf(
+ 'Null returned from %s::getUser()',
+ get_class($guardAuthenticator)
+ ));
+ }
+
+ if (!$user instanceof UserInterface) {
+ throw new \UnexpectedValueException(sprintf(
+ 'The %s::getUser() method must return a UserInterface. You returned %s.',
+ get_class($guardAuthenticator),
+ is_object($user) ? get_class($user) : gettype($user)
+ ));
+ }
+
+ $this->userChecker->checkPreAuth($user);
+ if (true !== $guardAuthenticator->checkCredentials($token->getCredentials(), $user)) {
+ throw new BadCredentialsException(sprintf('Authentication failed because %s::checkCredentials() did not return true.', get_class($guardAuthenticator)));
+ }
+ $this->userChecker->checkPostAuth($user);
+
+ // turn the UserInterface into a TokenInterface
+ $authenticatedToken = $guardAuthenticator->createAuthenticatedToken($user, $this->providerKey);
+ if (!$authenticatedToken instanceof TokenInterface) {
+ throw new \UnexpectedValueException(sprintf(
+ 'The %s::createAuthenticatedToken() method must return a TokenInterface. You returned %s.',
+ get_class($guardAuthenticator),
+ is_object($authenticatedToken) ? get_class($authenticatedToken) : gettype($authenticatedToken)
+ ));
+ }
+
+ return $authenticatedToken;
+ }
+
+ public function supports(TokenInterface $token)
+ {
+ return $token instanceof GuardTokenInterface;
+ }
+}
diff --git a/Acl/README.md b/Guard/README.md
index a6048fd..ce70622 100644
--- a/Acl/README.md
+++ b/Guard/README.md
@@ -1,10 +1,9 @@
-Security Component - ACL (Access Control List)
-==============================================
+Security Component - Guard
+==========================
-Security provides an infrastructure for sophisticated authorization systems,
-which makes it possible to easily separate the actual authorization logic from
-so called user providers that hold the users credentials. It is inspired by
-the Java Spring framework.
+The Guard component brings many layers of authentication together, making
+it much easier to create complex authentication systems where you have
+total control.
Resources
---------
diff --git a/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php b/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php
new file mode 100644
index 0000000..3dbbf84
--- /dev/null
+++ b/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php
@@ -0,0 +1,212 @@
+<?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\Guard\Tests\Authenticator;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
+
+/**
+ * @author Jean Pasdeloup <jpasdeloup@sedona.fr>
+ */
+class FormLoginAuthenticatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $requestWithoutSession;
+ private $requestWithSession;
+ private $authenticator;
+
+ const LOGIN_URL = 'http://login';
+ const DEFAULT_SUCCESS_URL = 'http://defaultsuccess';
+ const CUSTOM_SUCCESS_URL = 'http://customsuccess';
+
+ public function testAuthenticationFailureWithoutSession()
+ {
+ $failureResponse = $this->authenticator->onAuthenticationFailure($this->requestWithoutSession, new AuthenticationException());
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse);
+ $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl());
+ }
+
+ public function testAuthenticationFailureWithSession()
+ {
+ $this->requestWithSession->getSession()
+ ->expects($this->once())
+ ->method('set');
+
+ $failureResponse = $this->authenticator->onAuthenticationFailure($this->requestWithSession, new AuthenticationException());
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse);
+ $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl());
+ }
+
+ public function testAuthenticationSuccessWithoutSession()
+ {
+ $token = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $redirectResponse = $this->authenticator->onAuthenticationSuccess($this->requestWithoutSession, $token, 'providerkey');
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $redirectResponse);
+ $this->assertEquals(self::DEFAULT_SUCCESS_URL, $redirectResponse->getTargetUrl());
+ }
+
+ public function testAuthenticationSuccessWithSessionButEmpty()
+ {
+ $token = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->requestWithSession->getSession()
+ ->expects($this->once())
+ ->method('get')
+ ->will($this->returnValue(null));
+
+ $redirectResponse = $this->authenticator->onAuthenticationSuccess($this->requestWithSession, $token, 'providerkey');
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $redirectResponse);
+ $this->assertEquals(self::DEFAULT_SUCCESS_URL, $redirectResponse->getTargetUrl());
+ }
+
+ public function testAuthenticationSuccessWithSessionAndTarget()
+ {
+ $token = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->requestWithSession->getSession()
+ ->expects($this->once())
+ ->method('get')
+ ->will($this->returnValue(self::CUSTOM_SUCCESS_URL));
+
+ $redirectResponse = $this->authenticator->onAuthenticationSuccess($this->requestWithSession, $token, 'providerkey');
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $redirectResponse);
+ $this->assertEquals(self::CUSTOM_SUCCESS_URL, $redirectResponse->getTargetUrl());
+ }
+
+ public function testRememberMe()
+ {
+ $doSupport = $this->authenticator->supportsRememberMe();
+
+ $this->assertTrue($doSupport);
+ }
+
+ public function testStartWithoutSession()
+ {
+ $failureResponse = $this->authenticator->start($this->requestWithoutSession, new AuthenticationException());
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse);
+ $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl());
+ }
+
+ public function testStartWithSession()
+ {
+ $failureResponse = $this->authenticator->start($this->requestWithSession, new AuthenticationException());
+
+ $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse);
+ $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl());
+ }
+
+ protected function setUp()
+ {
+ $this->requestWithoutSession = new Request(array(), array(), array(), array(), array(), array());
+ $this->requestWithSession = new Request(array(), array(), array(), array(), array(), array());
+
+ $session = $this->getMockBuilder('Symfony\\Component\\HttpFoundation\\Session\\SessionInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->requestWithSession->setSession($session);
+
+ $this->authenticator = new TestFormLoginAuthenticator();
+ $this->authenticator
+ ->setLoginUrl(self::LOGIN_URL)
+ ->setDefaultSuccessRedirectUrl(self::DEFAULT_SUCCESS_URL)
+ ;
+ }
+
+ protected function tearDown()
+ {
+ $this->request = null;
+ $this->requestWithSession = null;
+ }
+}
+
+class TestFormLoginAuthenticator extends AbstractFormLoginAuthenticator
+{
+ private $loginUrl;
+ private $defaultSuccessRedirectUrl;
+
+ /**
+ * @param mixed $defaultSuccessRedirectUrl
+ *
+ * @return TestFormLoginAuthenticator
+ */
+ public function setDefaultSuccessRedirectUrl($defaultSuccessRedirectUrl)
+ {
+ $this->defaultSuccessRedirectUrl = $defaultSuccessRedirectUrl;
+
+ return $this;
+ }
+
+ /**
+ * @param mixed $loginUrl
+ *
+ * @return TestFormLoginAuthenticator
+ */
+ public function setLoginUrl($loginUrl)
+ {
+ $this->loginUrl = $loginUrl;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getLoginUrl()
+ {
+ return $this->loginUrl;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDefaultSuccessRedirectUrl()
+ {
+ return $this->defaultSuccessRedirectUrl;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCredentials(Request $request)
+ {
+ return 'credentials';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUser($credentials, UserProviderInterface $userProvider)
+ {
+ return $userProvider->loadUserByUsername($credentials);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function checkCredentials($credentials, UserInterface $user)
+ {
+ return true;
+ }
+}
diff --git a/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php b/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php
new file mode 100644
index 0000000..3224fee
--- /dev/null
+++ b/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php
@@ -0,0 +1,256 @@
+<?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\Guard\Tests\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener;
+use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+
+/**
+ * @author Ryan Weaver <weaverryan@gmail.com>
+ */
+class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
+{
+ private $authenticationManager;
+ private $guardAuthenticatorHandler;
+ private $event;
+ private $logger;
+ private $request;
+ private $rememberMeServices;
+
+ public function testHandleSuccess()
+ {
+ $authenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticateToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $providerKey = 'my_firewall';
+
+ $credentials = array('username' => 'weaverryan', 'password' => 'all_your_base');
+ $authenticator
+ ->expects($this->once())
+ ->method('getCredentials')
+ ->with($this->equalTo($this->request))
+ ->will($this->returnValue($credentials));
+
+ // a clone of the token that should be created internally
+ $uniqueGuardKey = 'my_firewall_0';
+ $nonAuthedToken = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey);
+
+ $this->authenticationManager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->with($this->equalTo($nonAuthedToken))
+ ->will($this->returnValue($authenticateToken));
+
+ $this->guardAuthenticatorHandler
+ ->expects($this->once())
+ ->method('authenticateWithToken')
+ ->with($authenticateToken, $this->request);
+
+ $this->guardAuthenticatorHandler
+ ->expects($this->once())
+ ->method('handleAuthenticationSuccess')
+ ->with($authenticateToken, $this->request, $authenticator, $providerKey);
+
+ $listener = new GuardAuthenticationListener(
+ $this->guardAuthenticatorHandler,
+ $this->authenticationManager,
+ $providerKey,
+ array($authenticator),
+ $this->logger
+ );
+
+ $listener->setRememberMeServices($this->rememberMeServices);
+ // should never be called - our handleAuthenticationSuccess() does not return a Response
+ $this->rememberMeServices
+ ->expects($this->never())
+ ->method('loginSuccess');
+
+ $listener->handle($this->event);
+ }
+
+ public function testHandleSuccessStopsAfterResponseIsSet()
+ {
+ $authenticator1 = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticator2 = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+
+ // mock the first authenticator to fail, and set a Response
+ $authenticator1
+ ->expects($this->once())
+ ->method('getCredentials')
+ ->willThrowException(new AuthenticationException());
+ $this->guardAuthenticatorHandler
+ ->expects($this->once())
+ ->method('handleAuthenticationFailure')
+ ->willReturn(new Response());
+ // the second authenticator should *never* be called
+ $authenticator2
+ ->expects($this->never())
+ ->method('getCredentials');
+
+ $listener = new GuardAuthenticationListener(
+ $this->guardAuthenticatorHandler,
+ $this->authenticationManager,
+ 'my_firewall',
+ array($authenticator1, $authenticator2),
+ $this->logger
+ );
+
+ $listener->handle($this->event);
+ }
+
+ public function testHandleSuccessWithRememberMe()
+ {
+ $authenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticateToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $providerKey = 'my_firewall_with_rememberme';
+
+ $authenticator
+ ->expects($this->once())
+ ->method('getCredentials')
+ ->with($this->equalTo($this->request))
+ ->will($this->returnValue(array('username' => 'anything_not_empty')));
+
+ $this->authenticationManager
+ ->expects($this->once())
+ ->method('authenticate')
+ ->will($this->returnValue($authenticateToken));
+
+ $successResponse = new Response('Success!');
+ $this->guardAuthenticatorHandler
+ ->expects($this->once())
+ ->method('handleAuthenticationSuccess')
+ ->will($this->returnValue($successResponse));
+
+ $listener = new GuardAuthenticationListener(
+ $this->guardAuthenticatorHandler,
+ $this->authenticationManager,
+ $providerKey,
+ array($authenticator),
+ $this->logger
+ );
+
+ $listener->setRememberMeServices($this->rememberMeServices);
+ $authenticator->expects($this->once())
+ ->method('supportsRememberMe')
+ ->will($this->returnValue(true));
+ // should be called - we do have a success Response
+ $this->rememberMeServices
+ ->expects($this->once())
+ ->method('loginSuccess');
+
+ $listener->handle($this->event);
+ }
+
+ public function testHandleCatchesAuthenticationException()
+ {
+ $authenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $providerKey = 'my_firewall2';
+
+ $authException = new AuthenticationException('Get outta here crazy user with a bad password!');
+ $authenticator
+ ->expects($this->once())
+ ->method('getCredentials')
+ ->will($this->throwException($authException));
+
+ // this is not called
+ $this->authenticationManager
+ ->expects($this->never())
+ ->method('authenticate');
+
+ $this->guardAuthenticatorHandler
+ ->expects($this->once())
+ ->method('handleAuthenticationFailure')
+ ->with($authException, $this->request, $authenticator, $providerKey);
+
+ $listener = new GuardAuthenticationListener(
+ $this->guardAuthenticatorHandler,
+ $this->authenticationManager,
+ $providerKey,
+ array($authenticator),
+ $this->logger
+ );
+
+ $listener->handle($this->event);
+ }
+
+ public function testReturnNullToSkipAuth()
+ {
+ $authenticatorA = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticatorB = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $providerKey = 'my_firewall3';
+
+ $authenticatorA
+ ->expects($this->once())
+ ->method('getCredentials')
+ ->will($this->returnValue(null));
+ $authenticatorB
+ ->expects($this->once())
+ ->method('getCredentials')
+ ->will($this->returnValue(null));
+
+ // this is not called
+ $this->authenticationManager
+ ->expects($this->never())
+ ->method('authenticate');
+
+ $this->guardAuthenticatorHandler
+ ->expects($this->never())
+ ->method('handleAuthenticationSuccess');
+
+ $listener = new GuardAuthenticationListener(
+ $this->guardAuthenticatorHandler,
+ $this->authenticationManager,
+ $providerKey,
+ array($authenticatorA, $authenticatorB),
+ $this->logger
+ );
+
+ $listener->handle($this->event);
+ }
+
+ protected function setUp()
+ {
+ $this->authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->guardAuthenticatorHandler = $this->getMockBuilder('Symfony\Component\Security\Guard\GuardAuthenticatorHandler')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->request = new Request(array(), array(), array(), array(), array(), array());
+
+ $this->event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getRequest'))
+ ->getMock();
+ $this->event
+ ->expects($this->any())
+ ->method('getRequest')
+ ->will($this->returnValue($this->request));
+
+ $this->logger = $this->getMock('Psr\Log\LoggerInterface');
+ $this->rememberMeServices = $this->getMock('Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface');
+ }
+
+ protected function tearDown()
+ {
+ $this->authenticationManager = null;
+ $this->guardAuthenticatorHandler = null;
+ $this->event = null;
+ $this->logger = null;
+ $this->request = null;
+ $this->rememberMeServices = null;
+ }
+}
diff --git a/Guard/Tests/GuardAuthenticatorHandlerTest.php b/Guard/Tests/GuardAuthenticatorHandlerTest.php
new file mode 100644
index 0000000..6f36702
--- /dev/null
+++ b/Guard/Tests/GuardAuthenticatorHandlerTest.php
@@ -0,0 +1,141 @@
+<?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\Guard\Tests;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
+use Symfony\Component\Security\Http\SecurityEvents;
+
+class GuardAuthenticatorHandlerTest extends \PHPUnit_Framework_TestCase
+{
+ private $tokenStorage;
+ private $dispatcher;
+ private $token;
+ private $request;
+ private $guardAuthenticator;
+
+ public function testAuthenticateWithToken()
+ {
+ $this->tokenStorage->expects($this->once())
+ ->method('setToken')
+ ->with($this->token);
+
+ $loginEvent = new InteractiveLoginEvent($this->request, $this->token);
+
+ $this->dispatcher
+ ->expects($this->once())
+ ->method('dispatch')
+ ->with($this->equalTo(SecurityEvents::INTERACTIVE_LOGIN), $this->equalTo($loginEvent))
+ ;
+
+ $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
+ $handler->authenticateWithToken($this->token, $this->request);
+ }
+
+ public function testHandleAuthenticationSuccess()
+ {
+ $providerKey = 'my_handleable_firewall';
+ $response = new Response('Guard all the things!');
+ $this->guardAuthenticator->expects($this->once())
+ ->method('onAuthenticationSuccess')
+ ->with($this->request, $this->token, $providerKey)
+ ->will($this->returnValue($response));
+
+ $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
+ $actualResponse = $handler->handleAuthenticationSuccess($this->token, $this->request, $this->guardAuthenticator, $providerKey);
+ $this->assertSame($response, $actualResponse);
+ }
+
+ public function testHandleAuthenticationFailure()
+ {
+ // setToken() not called - getToken() will return null, so there's nothing to clear
+ $this->tokenStorage->expects($this->never())
+ ->method('setToken')
+ ->with(null);
+ $authException = new AuthenticationException('Bad password!');
+
+ $response = new Response('Try again, but with the right password!');
+ $this->guardAuthenticator->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $authException)
+ ->will($this->returnValue($response));
+
+ $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
+ $actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, 'firewall_provider_key');
+ $this->assertSame($response, $actualResponse);
+ }
+
+ /**
+ * @dataProvider getTokenClearingTests
+ */
+ public function testHandleAuthenticationClearsToken($tokenClass, $tokenProviderKey, $actualProviderKey, $shouldTokenBeCleared)
+ {
+ $token = $this->getMockBuilder($tokenClass)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $token->expects($this->any())
+ ->method('getProviderKey')
+ ->will($this->returnValue($tokenProviderKey));
+
+ // make the $token be the current token
+ $this->tokenStorage->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue($token));
+
+ $this->tokenStorage->expects($shouldTokenBeCleared ? $this->once() : $this->never())
+ ->method('setToken')
+ ->with(null);
+ $authException = new AuthenticationException('Bad password!');
+
+ $response = new Response('Try again, but with the right password!');
+ $this->guardAuthenticator->expects($this->once())
+ ->method('onAuthenticationFailure')
+ ->with($this->request, $authException)
+ ->will($this->returnValue($response));
+
+ $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher);
+ $actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, $actualProviderKey);
+ $this->assertSame($response, $actualResponse);
+ }
+
+ public function getTokenClearingTests()
+ {
+ $tests = array();
+ // correct token class and matching firewall => clear the token
+ $tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'the_firewall_key', true);
+ $tests[] = array('Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'different_key', false);
+ $tests[] = array('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', 'the_firewall_key', 'the_firewall_key', false);
+
+ return $tests;
+ }
+
+ protected function setUp()
+ {
+ $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ $this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $this->request = new Request(array(), array(), array(), array(), array(), array());
+ $this->guardAuthenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ }
+
+ protected function tearDown()
+ {
+ $this->tokenStorage = null;
+ $this->dispatcher = null;
+ $this->token = null;
+ $this->request = null;
+ $this->guardAuthenticator = null;
+ }
+}
diff --git a/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/Guard/Tests/Provider/GuardAuthenticationProviderTest.php
new file mode 100644
index 0000000..bfcf24b
--- /dev/null
+++ b/Guard/Tests/Provider/GuardAuthenticationProviderTest.php
@@ -0,0 +1,150 @@
+<?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\Guard\Tests\Provider;
+
+use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider;
+use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
+
+/**
+ * @author Ryan Weaver <weaverryan@gmail.com>
+ */
+class GuardAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
+{
+ private $userProvider;
+ private $userChecker;
+ private $preAuthenticationToken;
+
+ public function testAuthenticate()
+ {
+ $providerKey = 'my_cool_firewall';
+
+ $authenticatorA = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticatorB = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticatorC = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+ $authenticators = array($authenticatorA, $authenticatorB, $authenticatorC);
+
+ // called 2 times - for authenticator A and B (stops on B because of match)
+ $this->preAuthenticationToken->expects($this->exactly(2))
+ ->method('getGuardProviderKey')
+ // it will return the "1" index, which will match authenticatorB
+ ->will($this->returnValue('my_cool_firewall_1'));
+
+ $enteredCredentials = array(
+ 'username' => '_weaverryan_test_user',
+ 'password' => 'guard_auth_ftw',
+ );
+ $this->preAuthenticationToken->expects($this->atLeastOnce())
+ ->method('getCredentials')
+ ->will($this->returnValue($enteredCredentials));
+
+ // authenticators A and C are never called
+ $authenticatorA->expects($this->never())
+ ->method('getUser');
+ $authenticatorC->expects($this->never())
+ ->method('getUser');
+
+ $mockedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $authenticatorB->expects($this->once())
+ ->method('getUser')
+ ->with($enteredCredentials, $this->userProvider)
+ ->will($this->returnValue($mockedUser));
+ // checkCredentials is called
+ $authenticatorB->expects($this->once())
+ ->method('checkCredentials')
+ ->with($enteredCredentials, $mockedUser)
+ // authentication works!
+ ->will($this->returnValue(true));
+ $authedToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $authenticatorB->expects($this->once())
+ ->method('createAuthenticatedToken')
+ ->with($mockedUser, $providerKey)
+ ->will($this->returnValue($authedToken));
+
+ // user checker should be called
+ $this->userChecker->expects($this->once())
+ ->method('checkPreAuth')
+ ->with($mockedUser);
+ $this->userChecker->expects($this->once())
+ ->method('checkPostAuth')
+ ->with($mockedUser);
+
+ $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, $providerKey, $this->userChecker);
+ $actualAuthedToken = $provider->authenticate($this->preAuthenticationToken);
+ $this->assertSame($authedToken, $actualAuthedToken);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ */
+ public function testCheckCredentialsReturningNonTrueFailsAuthentication()
+ {
+ $providerKey = 'my_uncool_firewall';
+
+ $authenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
+
+ // make sure the authenticator is used
+ $this->preAuthenticationToken->expects($this->any())
+ ->method('getGuardProviderKey')
+ // the 0 index, to match the only authenticator
+ ->will($this->returnValue('my_uncool_firewall_0'));
+
+ $this->preAuthenticationToken->expects($this->atLeastOnce())
+ ->method('getCredentials')
+ ->will($this->returnValue('non-null-value'));
+
+ $mockedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $authenticator->expects($this->once())
+ ->method('getUser')
+ ->will($this->returnValue($mockedUser));
+ // checkCredentials is called
+ $authenticator->expects($this->once())
+ ->method('checkCredentials')
+ // authentication fails :(
+ ->will($this->returnValue(null));
+
+ $provider = new GuardAuthenticationProvider(array($authenticator), $this->userProvider, $providerKey, $this->userChecker);
+ $provider->authenticate($this->preAuthenticationToken);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationExpiredException
+ */
+ public function testGuardWithNoLongerAuthenticatedTriggersLogout()
+ {
+ $providerKey = 'my_firewall_abc';
+
+ // create a token and mark it as NOT authenticated anymore
+ // this mimics what would happen if a user "changed" between request
+ $mockedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $token = new PostAuthenticationGuardToken($mockedUser, $providerKey, array('ROLE_USER'));
+ $token->setAuthenticated(false);
+
+ $provider = new GuardAuthenticationProvider(array(), $this->userProvider, $providerKey, $this->userChecker);
+ $actualToken = $provider->authenticate($token);
+ }
+
+ protected function setUp()
+ {
+ $this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
+ $this->userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
+ $this->preAuthenticationToken = $this->getMockBuilder('Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ protected function tearDown()
+ {
+ $this->userProvider = null;
+ $this->userChecker = null;
+ $this->preAuthenticationToken = null;
+ }
+}
diff --git a/Guard/Token/GuardTokenInterface.php b/Guard/Token/GuardTokenInterface.php
new file mode 100644
index 0000000..063ffd3
--- /dev/null
+++ b/Guard/Token/GuardTokenInterface.php
@@ -0,0 +1,27 @@
+<?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\Guard\Token;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
+/**
+ * A marker interface that both guard tokens implement.
+ *
+ * Any tokens passed to GuardAuthenticationProvider (i.e. any tokens that
+ * are handled by the guard auth system) must implement this
+ * interface.
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+interface GuardTokenInterface extends TokenInterface
+{
+}
diff --git a/Guard/Token/PostAuthenticationGuardToken.php b/Guard/Token/PostAuthenticationGuardToken.php
new file mode 100644
index 0000000..36c40ca
--- /dev/null
+++ b/Guard/Token/PostAuthenticationGuardToken.php
@@ -0,0 +1,90 @@
+<?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\Guard\Token;
+
+use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
+use Symfony\Component\Security\Core\Role\RoleInterface;
+use Symfony\Component\Security\Core\User\UserInterface;
+
+/**
+ * Used as an "authenticated" token, though it could be set to not-authenticated later.
+ *
+ * If you're using Guard authentication, you *must* use a class that implements
+ * GuardTokenInterface as your authenticated token (like this class).
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>n@gmail.com>
+ */
+class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface
+{
+ private $providerKey;
+
+ /**
+ * @param UserInterface $user The user!
+ * @param string $providerKey The provider (firewall) key
+ * @param RoleInterface[]|string[] $roles An array of roles
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function __construct(UserInterface $user, $providerKey, array $roles)
+ {
+ parent::__construct($roles);
+
+ if (empty($providerKey)) {
+ throw new \InvalidArgumentException('$providerKey (i.e. firewall key) must not be empty.');
+ }
+
+ $this->setUser($user);
+ $this->providerKey = $providerKey;
+
+ // this token is meant to be used after authentication success, so it is always authenticated
+ // you could set it as non authenticated later if you need to
+ parent::setAuthenticated(true);
+ }
+
+ /**
+ * This is meant to be only an authenticated token, where credentials
+ * have already been used and are thus cleared.
+ *
+ * {@inheritdoc}
+ */
+ public function getCredentials()
+ {
+ return array();
+ }
+
+ /**
+ * Returns the provider (firewall) key.
+ *
+ * @return string
+ */
+ public function getProviderKey()
+ {
+ return $this->providerKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize()
+ {
+ return serialize(array($this->providerKey, parent::serialize()));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
+ {
+ list($this->providerKey, $parentStr) = unserialize($serialized);
+ parent::unserialize($parentStr);
+ }
+}
diff --git a/Guard/Token/PreAuthenticationGuardToken.php b/Guard/Token/PreAuthenticationGuardToken.php
new file mode 100644
index 0000000..abbe985
--- /dev/null
+++ b/Guard/Token/PreAuthenticationGuardToken.php
@@ -0,0 +1,65 @@
+<?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\Guard\Token;
+
+use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
+
+/**
+ * The token used by the guard auth system before authentication.
+ *
+ * The GuardAuthenticationListener creates this, which is then consumed
+ * immediately by the GuardAuthenticationProvider. If authentication is
+ * successful, a different authenticated token is returned
+ *
+ * @author Ryan Weaver <ryan@knpuniversity.com>
+ */
+class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface
+{
+ private $credentials;
+ private $guardProviderKey;
+
+ /**
+ * @param mixed $credentials
+ * @param string $guardProviderKey Unique key that bind this token to a specific GuardAuthenticatorInterface
+ */
+ public function __construct($credentials, $guardProviderKey)
+ {
+ $this->credentials = $credentials;
+ $this->guardProviderKey = $guardProviderKey;
+
+ parent::__construct(array());
+
+ // never authenticated
+ parent::setAuthenticated(false);
+ }
+
+ public function getGuardProviderKey()
+ {
+ return $this->guardProviderKey;
+ }
+
+ /**
+ * Returns the user credentials, which might be an array of anything you
+ * wanted to put in there (e.g. username, password, favoriteColor).
+ *
+ * @return mixed The user credentials
+ */
+ public function getCredentials()
+ {
+ return $this->credentials;
+ }
+
+ public function setAuthenticated($authenticated)
+ {
+ throw new \LogicException('The PreAuthenticationGuardToken is *never* authenticated.');
+ }
+}
diff --git a/Acl/composer.json b/Guard/composer.json
index b292742..3208920 100644
--- a/Acl/composer.json
+++ b/Guard/composer.json
@@ -1,7 +1,7 @@
{
- "name": "symfony/security-acl",
+ "name": "symfony/security-guard",
"type": "library",
- "description": "Symfony Security Component - ACL (Access Control List)",
+ "description": "Symfony Security Component - Guard",
"keywords": [],
"homepage": "https://symfony.com",
"license": "MIT",
@@ -17,20 +17,14 @@
],
"require": {
"php": ">=5.3.9",
- "symfony/security-core": "~2.4"
+ "symfony/security-core": "~2.8|~3.0.0",
+ "symfony/security-http": "~2.7|~3.0.0"
},
"require-dev": {
- "doctrine/common": "~2.2",
- "doctrine/dbal": "~2.2",
"psr/log": "~1.0"
},
- "suggest": {
- "symfony/class-loader": "For using the ACL generateSql script",
- "symfony/finder": "For using the ACL generateSql script",
- "doctrine/dbal": "For using the built-in ACL implementation"
- },
"autoload": {
- "psr-4": { "Symfony\\Component\\Security\\Acl\\": "" },
+ "psr-4": { "Symfony\\Component\\Security\\Guard\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
@@ -38,7 +32,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
}
}
diff --git a/Acl/phpunit.xml.dist b/Guard/phpunit.xml.dist
index b1ea047..da5a382 100644
--- a/Acl/phpunit.xml.dist
+++ b/Guard/phpunit.xml.dist
@@ -16,7 +16,7 @@
</php>
<testsuites>
- <testsuite name="Symfony Security Component ACL Test Suite">
+ <testsuite name="Symfony Security Component Guard Suite">
<directory>./Tests/</directory>
</testsuite>
</testsuites>
diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php
index 830c00a..ea5c356 100644
--- a/Http/Authentication/DefaultAuthenticationFailureHandler.php
+++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php
@@ -17,6 +17,7 @@ use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Class with the default authentication failure handling logic.
@@ -82,7 +83,7 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
- if ($failureUrl = $request->get($this->options['failure_path_parameter'], null, true)) {
+ if ($failureUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['failure_path_parameter'])) {
$this->options['failure_path'] = $failureUrl;
}
diff --git a/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
index b6a7df5..bfc0c8b 100644
--- a/Http/Authentication/DefaultAuthenticationSuccessHandler.php
+++ b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Class with the default authentication success handling logic.
@@ -108,7 +109,7 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
return $this->options['default_target_path'];
}
- if ($targetUrl = $request->get($this->options['target_path_parameter'], null, true)) {
+ if ($targetUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['target_path_parameter'])) {
return $targetUrl;
}
diff --git a/Http/Authentication/SimpleFormAuthenticatorInterface.php b/Http/Authentication/SimpleFormAuthenticatorInterface.php
new file mode 100644
index 0000000..112688c
--- /dev/null
+++ b/Http/Authentication/SimpleFormAuthenticatorInterface.php
@@ -0,0 +1,21 @@
+<?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\Http\Authentication;
+
+use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface as BaseSimpleFormAuthenticatorInterface;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface SimpleFormAuthenticatorInterface extends BaseSimpleFormAuthenticatorInterface
+{
+}
diff --git a/Http/Authentication/SimplePreAuthenticatorInterface.php b/Http/Authentication/SimplePreAuthenticatorInterface.php
new file mode 100644
index 0000000..afa8049
--- /dev/null
+++ b/Http/Authentication/SimplePreAuthenticatorInterface.php
@@ -0,0 +1,21 @@
+<?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\Http\Authentication;
+
+use Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface as BaseSimplePreAuthenticatorInterface;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface SimplePreAuthenticatorInterface extends BaseSimplePreAuthenticatorInterface
+{
+}
diff --git a/Http/EntryPoint/AuthenticationEntryPointInterface.php b/Http/EntryPoint/AuthenticationEntryPointInterface.php
index c8e43e5..9bade0c 100644
--- a/Http/EntryPoint/AuthenticationEntryPointInterface.php
+++ b/Http/EntryPoint/AuthenticationEntryPointInterface.php
@@ -16,8 +16,8 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
- * AuthenticationEntryPointInterface is the interface used to start the
- * authentication scheme.
+ * Implement this interface for any classes that will be called to "start"
+ * the authentication process (see method for more details).
*
* @author Fabien Potencier <fabien@symfony.com>
*/
diff --git a/Http/EntryPoint/DigestAuthenticationEntryPoint.php b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
index 89f80ad..cdb98eb 100644
--- a/Http/EntryPoint/DigestAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
@@ -24,15 +24,15 @@ use Psr\Log\LoggerInterface;
*/
class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterface
{
- private $key;
+ private $secret;
private $realmName;
private $nonceValiditySeconds;
private $logger;
- public function __construct($realmName, $key, $nonceValiditySeconds = 300, LoggerInterface $logger = null)
+ public function __construct($realmName, $secret, $nonceValiditySeconds = 300, LoggerInterface $logger = null)
{
$this->realmName = $realmName;
- $this->key = $key;
+ $this->secret = $secret;
$this->nonceValiditySeconds = $nonceValiditySeconds;
$this->logger = $logger;
}
@@ -43,7 +43,7 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
public function start(Request $request, AuthenticationException $authException = null)
{
$expiryTime = microtime(true) + $this->nonceValiditySeconds * 1000;
- $signatureValue = md5($expiryTime.':'.$this->key);
+ $signatureValue = md5($expiryTime.':'.$this->secret);
$nonceValue = $expiryTime.':'.$signatureValue;
$nonceValueBase64 = base64_encode($nonceValue);
@@ -65,11 +65,21 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
}
/**
- * @return string
+ * @deprecated Since version 2.8, to be removed in 3.0. Use getSecret() instead.
*/
public function getKey()
{
- return $this->key;
+ @trigger_error(__method__.'() is deprecated since version 2.8 and will be removed in 3.0. Use getSecret() instead.', E_USER_DEPRECATED);
+
+ return $this->getSecret();
+ }
+
+ /**
+ * @return string
+ */
+ public function getSecret()
+ {
+ return $this->secret;
}
/**
diff --git a/Http/Firewall/AnonymousAuthenticationListener.php b/Http/Firewall/AnonymousAuthenticationListener.php
index f7feee8..0d60673 100644
--- a/Http/Firewall/AnonymousAuthenticationListener.php
+++ b/Http/Firewall/AnonymousAuthenticationListener.php
@@ -27,14 +27,14 @@ use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
class AnonymousAuthenticationListener implements ListenerInterface
{
private $tokenStorage;
- private $key;
+ private $secret;
private $authenticationManager;
private $logger;
- public function __construct(TokenStorageInterface $tokenStorage, $key, LoggerInterface $logger = null, AuthenticationManagerInterface $authenticationManager = null)
+ public function __construct(TokenStorageInterface $tokenStorage, $secret, LoggerInterface $logger = null, AuthenticationManagerInterface $authenticationManager = null)
{
$this->tokenStorage = $tokenStorage;
- $this->key = $key;
+ $this->secret = $secret;
$this->authenticationManager = $authenticationManager;
$this->logger = $logger;
}
@@ -51,7 +51,7 @@ class AnonymousAuthenticationListener implements ListenerInterface
}
try {
- $token = new AnonymousToken($this->key, 'anon.', array());
+ $token = new AnonymousToken($this->secret, 'anon.', array());
if (null !== $this->authenticationManager) {
$token = $this->authenticationManager->authenticate($token);
}
diff --git a/Http/Firewall/DigestAuthenticationListener.php b/Http/Firewall/DigestAuthenticationListener.php
index 702cf33..71bdf6c 100644
--- a/Http/Firewall/DigestAuthenticationListener.php
+++ b/Http/Firewall/DigestAuthenticationListener.php
@@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\User\UserProviderInterface;
-use Symfony\Component\Security\Core\Util\StringUtils;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -79,7 +78,7 @@ class DigestAuthenticationListener implements ListenerInterface
}
try {
- $digestAuth->validateAndDecode($this->authenticationEntryPoint->getKey(), $this->authenticationEntryPoint->getRealmName());
+ $digestAuth->validateAndDecode($this->authenticationEntryPoint->getSecret(), $this->authenticationEntryPoint->getRealmName());
} catch (BadCredentialsException $e) {
$this->fail($event, $request, $e);
@@ -100,7 +99,7 @@ class DigestAuthenticationListener implements ListenerInterface
return;
}
- if (!StringUtils::equals($serverDigestMd5, $digestAuth->getResponse())) {
+ if (!hash_equals($serverDigestMd5, $digestAuth->getResponse())) {
if (null !== $this->logger) {
$this->logger->debug('Unexpected response from the DigestAuth received; is the header returning a clear text passwords?', array('expected' => $serverDigestMd5, 'received' => $digestAuth->getResponse()));
}
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php
index 96f5685..e19d39c 100644
--- a/Http/Firewall/LogoutListener.php
+++ b/Http/Firewall/LogoutListener.php
@@ -24,6 +24,7 @@ use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* LogoutListener logout users.
@@ -56,11 +57,21 @@ class LogoutListener implements ListenerInterface
throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
}
+ if (isset($options['intention'])) {
+ if (isset($options['csrf_token_id'])) {
+ throw new \InvalidArgumentException(sprintf('You should only define an option for one of "intention" or "csrf_token_id" for the "%s". Use the "csrf_token_id" as it replaces "intention".', __CLASS__));
+ }
+
+ @trigger_error('The "intention" option for the '.__CLASS__.' is deprecated since version 2.8 and will be removed in 3.0. Use the "csrf_token_id" option instead.', E_USER_DEPRECATED);
+
+ $options['csrf_token_id'] = $options['intention'];
+ }
+
$this->tokenStorage = $tokenStorage;
$this->httpUtils = $httpUtils;
$this->options = array_merge(array(
'csrf_parameter' => '_csrf_token',
- 'intention' => 'logout',
+ 'csrf_token_id' => 'logout',
'logout_path' => '/logout',
), $options);
$this->successHandler = $successHandler;
@@ -98,9 +109,9 @@ class LogoutListener implements ListenerInterface
}
if (null !== $this->csrfTokenManager) {
- $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+ $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
- if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
+ if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['csrf_token_id'], $csrfToken))) {
throw new LogoutException('Invalid CSRF token.');
}
}
diff --git a/Http/Firewall/SimpleFormAuthenticationListener.php b/Http/Firewall/SimpleFormAuthenticationListener.php
index 8123e0e..331d018 100644
--- a/Http/Firewall/SimpleFormAuthenticationListener.php
+++ b/Http/Firewall/SimpleFormAuthenticationListener.php
@@ -27,6 +27,7 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInt
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Psr\Log\LoggerInterface;
@@ -70,6 +71,16 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
}
+ if (isset($options['intention'])) {
+ if (isset($options['csrf_token_id'])) {
+ throw new \InvalidArgumentException(sprintf('You should only define an option for one of "intention" or "csrf_token_id" for the "%s". Use the "csrf_token_id" as it replaces "intention".', __CLASS__));
+ }
+
+ @trigger_error('The "intention" option for the '.__CLASS__.' is deprecated since version 2.8 and will be removed in 3.0. Use the "csrf_token_id" option instead.', E_USER_DEPRECATED);
+
+ $options['csrf_token_id'] = $options['intention'];
+ }
+
$this->simpleAuthenticator = $simpleAuthenticator;
$this->csrfTokenManager = $csrfTokenManager;
@@ -77,7 +88,7 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
- 'intention' => 'authenticate',
+ 'csrf_token_id' => 'authenticate',
'post_only' => true,
), $options);
@@ -102,19 +113,19 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
protected function attemptAuthentication(Request $request)
{
if (null !== $this->csrfTokenManager) {
- $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+ $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
- if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
+ if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['csrf_token_id'], $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}
if ($this->options['post_only']) {
- $username = trim($request->request->get($this->options['username_parameter'], null, true));
- $password = $request->request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
} else {
- $username = trim($request->get($this->options['username_parameter'], null, true));
- $password = $request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index ba4329b..866d0c3 100644
--- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -19,6 +19,7 @@ use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
@@ -48,11 +49,21 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
throw new InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
}
+ if (isset($options['intention'])) {
+ if (isset($options['csrf_token_id'])) {
+ throw new \InvalidArgumentException(sprintf('You should only define an option for one of "intention" or "csrf_token_id" for the "%s". Use the "csrf_token_id" as it replaces "intention".', __CLASS__));
+ }
+
+ @trigger_error('The "intention" option for the '.__CLASS__.' is deprecated since version 2.8 and will be removed in 3.0. Use the "csrf_token_id" option instead.', E_USER_DEPRECATED);
+
+ $options['csrf_token_id'] = $options['intention'];
+ }
+
parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
- 'intention' => 'authenticate',
+ 'csrf_token_id' => 'authenticate',
'post_only' => true,
), $options), $logger, $dispatcher);
@@ -77,19 +88,19 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
protected function attemptAuthentication(Request $request)
{
if (null !== $this->csrfTokenManager) {
- $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+ $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
- if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
+ if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['csrf_token_id'], $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
}
if ($this->options['post_only']) {
- $username = trim($request->request->get($this->options['username_parameter'], null, true));
- $password = $request->request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
} else {
- $username = trim($request->get($this->options['username_parameter'], null, true));
- $password = $request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
diff --git a/Http/Logout/LogoutUrlGenerator.php b/Http/Logout/LogoutUrlGenerator.php
index 4ad63cc..761e56a 100644
--- a/Http/Logout/LogoutUrlGenerator.php
+++ b/Http/Logout/LogoutUrlGenerator.php
@@ -86,7 +86,7 @@ class LogoutUrlGenerator
* Generates the logout URL for the firewall.
*
* @param string|null $key The firewall key or null to use the current firewall key
- * @param bool|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
+ * @param int $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
*
* @return string The logout URL
*
diff --git a/Http/ParameterBagUtils.php b/Http/ParameterBagUtils.php
new file mode 100644
index 0000000..eed5421
--- /dev/null
+++ b/Http/ParameterBagUtils.php
@@ -0,0 +1,96 @@
+<?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\Http;
+
+use Symfony\Component\HttpFoundation\ParameterBag;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\PropertyAccess\Exception\AccessException;
+use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+
+/**
+ * @internal
+ */
+final class ParameterBagUtils
+{
+ private static $propertyAccessor;
+
+ /**
+ * Returns a "parameter" value.
+ *
+ * Paths like foo[bar] will be evaluated to find deeper items in nested data structures.
+ *
+ * @param ParameterBag $parameters The parameter bag
+ * @param string $path The key
+ *
+ * @return mixed
+ *
+ * @throws InvalidArgumentException when the given path is malformed
+ */
+ public static function getParameterBagValue(ParameterBag $parameters, $path)
+ {
+ if (false === $pos = strpos($path, '[')) {
+ return $parameters->get($path);
+ }
+
+ $root = substr($path, 0, $pos);
+
+ if (null === $value = $parameters->get($root)) {
+ return;
+ }
+
+ if (null === self::$propertyAccessor) {
+ self::$propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ try {
+ return self::$propertyAccessor->getValue($value, substr($path, $pos));
+ } catch (AccessException $e) {
+ return;
+ }
+ }
+
+ /**
+ * Returns a request "parameter" value.
+ *
+ * Paths like foo[bar] will be evaluated to find deeper items in nested data structures.
+ *
+ * @param Request $request The request
+ * @param string $path The key
+ *
+ * @return mixed
+ *
+ * @throws InvalidArgumentException when the given path is malformed
+ */
+ public static function getRequestParameterValue(Request $request, $path)
+ {
+ if (false === $pos = strpos($path, '[')) {
+ return $request->get($path);
+ }
+
+ $root = substr($path, 0, $pos);
+
+ if (null === $value = $request->get($root)) {
+ return;
+ }
+
+ if (null === self::$propertyAccessor) {
+ self::$propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ try {
+ return self::$propertyAccessor->getValue($value, substr($path, $pos));
+ } catch (AccessException $e) {
+ return;
+ }
+ }
+}
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index cd8640d..8627bc8 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -23,6 +23,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
use Psr\Log\LoggerInterface;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Base class implementing the RememberMeServicesInterface.
@@ -39,24 +40,24 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
'httponly' => true,
);
private $providerKey;
- private $key;
+ private $secret;
private $userProviders;
/**
* Constructor.
*
* @param array $userProviders
- * @param string $key
+ * @param string $secret
* @param string $providerKey
* @param array $options
* @param LoggerInterface $logger
*
* @throws \InvalidArgumentException
*/
- public function __construct(array $userProviders, $key, $providerKey, array $options = array(), LoggerInterface $logger = null)
+ public function __construct(array $userProviders, $secret, $providerKey, array $options = array(), LoggerInterface $logger = null)
{
- if (empty($key)) {
- throw new \InvalidArgumentException('$key must not be empty.');
+ if (empty($secret)) {
+ throw new \InvalidArgumentException('$secret must not be empty.');
}
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
@@ -66,7 +67,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
}
$this->userProviders = $userProviders;
- $this->key = $key;
+ $this->secret = $secret;
$this->providerKey = $providerKey;
$this->options = array_merge($this->options, $options);
$this->logger = $logger;
@@ -84,11 +85,21 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
}
/**
- * @return string
+ * @deprecated Since version 2.8, to be removed in 3.0. Use getSecret() instead.
*/
public function getKey()
{
- return $this->key;
+ @trigger_error(__method__.'() is deprecated since version 2.8 and will be removed in 3.0. Use getSecret() instead.', E_USER_DEPRECATED);
+
+ return $this->getSecret();
+ }
+
+ /**
+ * @return string
+ */
+ public function getSecret()
+ {
+ return $this->secret;
}
/**
@@ -125,7 +136,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
$this->logger->info('Remember-me cookie accepted.');
}
- return new RememberMeToken($user, $this->providerKey, $this->key);
+ return new RememberMeToken($user, $this->providerKey, $this->secret);
} catch (CookieTheftException $e) {
$this->cancelCookie($request);
@@ -312,7 +323,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
return true;
}
- $parameter = $request->get($this->options['remember_me_parameter'], null, true);
+ $parameter = ParameterBagUtils::getRequestParameterValue($request, $this->options['remember_me_parameter']);
if (null === $parameter && null !== $this->logger) {
$this->logger->debug('Did not send remember-me cookie.', array('parameter' => $this->options['remember_me_parameter']));
diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
index cbbbb23..807a4a7 100644
--- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
+++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
@@ -21,7 +21,6 @@ use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Util\SecureRandomInterface;
use Psr\Log\LoggerInterface;
-use Symfony\Component\Security\Core\Util\StringUtils;
/**
* Concrete implementation of the RememberMeServicesInterface which needs
@@ -33,23 +32,26 @@ use Symfony\Component\Security\Core\Util\StringUtils;
class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
{
private $tokenProvider;
- private $secureRandom;
/**
* Constructor.
*
+ * Note: The $secureRandom parameter is deprecated since version 2.8 and will be removed in 3.0.
+ *
* @param array $userProviders
- * @param string $key
+ * @param string $secret
* @param string $providerKey
* @param array $options
* @param LoggerInterface $logger
* @param SecureRandomInterface $secureRandom
*/
- public function __construct(array $userProviders, $key, $providerKey, array $options, LoggerInterface $logger = null, SecureRandomInterface $secureRandom)
+ public function __construct(array $userProviders, $secret, $providerKey, array $options = array(), LoggerInterface $logger = null, SecureRandomInterface $secureRandom = null)
{
- parent::__construct($userProviders, $key, $providerKey, $options, $logger);
+ if (null !== $secureRandom) {
+ @trigger_error('The $secureRandom parameter in '.__METHOD__.' is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
- $this->secureRandom = $secureRandom;
+ parent::__construct($userProviders, $secret, $providerKey, $options, $logger);
}
/**
@@ -91,7 +93,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
list($series, $tokenValue) = $cookieParts;
$persistentToken = $this->tokenProvider->loadTokenBySeries($series);
- if (!StringUtils::equals($persistentToken->getTokenValue(), $tokenValue)) {
+ if (!hash_equals($persistentToken->getTokenValue(), $tokenValue)) {
throw new CookieTheftException('This token was already used. The account is possibly compromised.');
}
@@ -99,7 +101,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
throw new AuthenticationException('The cookie has expired.');
}
- $tokenValue = base64_encode($this->secureRandom->nextBytes(64));
+ $tokenValue = base64_encode(random_bytes(64));
$this->tokenProvider->updateToken($series, $tokenValue, new \DateTime());
$request->attributes->set(self::COOKIE_ATTR_NAME,
new Cookie(
@@ -121,8 +123,8 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token)
{
- $series = base64_encode($this->secureRandom->nextBytes(64));
- $tokenValue = base64_encode($this->secureRandom->nextBytes(64));
+ $series = base64_encode(random_bytes(64));
+ $tokenValue = base64_encode(random_bytes(64));
$this->tokenProvider->createNewToken(
new PersistentToken(
diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php
index d68ada5..a443702 100644
--- a/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -17,7 +17,6 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
-use Symfony\Component\Security\Core\Util\StringUtils;
/**
* Concrete implementation of the RememberMeServicesInterface providing
@@ -54,7 +53,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_class($user)));
}
- if (true !== StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
+ if (true !== hash_equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
throw new AuthenticationException('The cookie\'s hash is invalid.');
}
@@ -121,6 +120,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function generateCookieHash($class, $username, $expires, $password)
{
- return hash_hmac('sha256', $class.$username.$expires.$password, $this->getKey());
+ return hash_hmac('sha256', $class.$username.$expires.$password, $this->getSecret());
}
}
diff --git a/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php b/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
index 252b124..c97ee69 100644
--- a/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
+++ b/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
@@ -18,17 +18,12 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCase
{
- private $httpKernel = null;
-
- private $httpUtils = null;
-
- private $logger = null;
-
- private $request = null;
-
- private $session = null;
-
- private $exception = null;
+ private $httpKernel;
+ private $httpUtils;
+ private $logger;
+ private $request;
+ private $session;
+ private $exception;
protected function setUp()
{
@@ -146,7 +141,7 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
public function testFailurePathCanBeOverwrittenWithRequest()
{
$this->request->expects($this->once())
- ->method('get')->with('_failure_path', null, true)
+ ->method('get')->with('_failure_path')
->will($this->returnValue('/auth/login'));
$this->httpUtils->expects($this->once())
@@ -156,12 +151,25 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
$handler->onAuthenticationFailure($this->request, $this->exception);
}
+ public function testFailurePathCanBeOverwrittenWithNestedAttributeInRequest()
+ {
+ $this->request->expects($this->once())
+ ->method('get')->with('_failure_path')
+ ->will($this->returnValue(array('value' => '/auth/login')));
+
+ $this->httpUtils->expects($this->once())
+ ->method('createRedirectResponse')->with($this->request, '/auth/login');
+
+ $handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array('failure_path_parameter' => '_failure_path[value]'), $this->logger);
+ $handler->onAuthenticationFailure($this->request, $this->exception);
+ }
+
public function testFailurePathParameterCanBeOverwritten()
{
$options = array('failure_path_parameter' => '_my_failure_path');
$this->request->expects($this->once())
- ->method('get')->with('_my_failure_path', null, true)
+ ->method('get')->with('_my_failure_path')
->will($this->returnValue('/auth/login'));
$this->httpUtils->expects($this->once())
diff --git a/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php b/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
index ae9f02b..5372993 100644
--- a/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
+++ b/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
@@ -69,6 +69,20 @@ class DefaultAuthenticationSuccessHandlerTest extends \PHPUnit_Framework_TestCas
$this->assertSame($response, $result);
}
+ public function testTargetPathIsPassedAsNestedParameterWithRequest()
+ {
+ $this->request->expects($this->once())
+ ->method('get')->with('_target_path')
+ ->will($this->returnValue(array('value' => '/dashboard')));
+
+ $response = $this->expectRedirectResponse('/dashboard');
+
+ $handler = new DefaultAuthenticationSuccessHandler($this->httpUtils, array('target_path_parameter' => '_target_path[value]'));
+ $result = $handler->onAuthenticationSuccess($this->request, $this->token);
+
+ $this->assertSame($response, $result);
+ }
+
public function testTargetPathParameterIsCustomised()
{
$options = array('target_path_parameter' => '_my_target_path');
diff --git a/Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php b/Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php
index 181e340..4082986 100644
--- a/Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php
+++ b/Http/Tests/EntryPoint/DigestAuthenticationEntryPointTest.php
@@ -23,7 +23,7 @@ class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$authenticationException = new AuthenticationException('TheAuthenticationExceptionMessage');
- $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheKey');
+ $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheSecret');
$response = $entryPoint->start($request, $authenticationException);
$this->assertEquals(401, $response->getStatusCode());
@@ -34,7 +34,7 @@ class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
{
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
- $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheKey');
+ $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheSecret');
$response = $entryPoint->start($request);
$this->assertEquals(401, $response->getStatusCode());
@@ -47,7 +47,7 @@ class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$nonceExpiredException = new NonceExpiredException('TheNonceExpiredExceptionMessage');
- $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheKey');
+ $entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheSecret');
$response = $entryPoint->start($request, $nonceExpiredException);
$this->assertEquals(401, $response->getStatusCode());
diff --git a/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php b/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php
index 3450c1e..d99b562 100644
--- a/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php
+++ b/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php
@@ -35,7 +35,7 @@ class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
->method('authenticate')
;
- $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', null, $authenticationManager);
+ $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', null, $authenticationManager);
$listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
}
@@ -48,14 +48,14 @@ class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(null))
;
- $anonymousToken = new AnonymousToken('TheKey', 'anon.', array());
+ $anonymousToken = new AnonymousToken('TheSecret', 'anon.', array());
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->callback(function ($token) {
- return 'TheKey' === $token->getKey();
+ return 'TheSecret' === $token->getSecret();
}))
->will($this->returnValue($anonymousToken))
;
@@ -66,7 +66,7 @@ class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
->with($anonymousToken)
;
- $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', null, $authenticationManager);
+ $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', null, $authenticationManager);
$listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
}
@@ -81,7 +81,7 @@ class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface');
- $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', $logger, $authenticationManager);
+ $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', $logger, $authenticationManager);
$listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false));
}
}
diff --git a/Http/Tests/Firewall/DigestAuthenticationListenerTest.php b/Http/Tests/Firewall/DigestAuthenticationListenerTest.php
new file mode 100644
index 0000000..80b2dc4
--- /dev/null
+++ b/Http/Tests/Firewall/DigestAuthenticationListenerTest.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Symfony\Component\Security\Http\Tests\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
+use Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener;
+
+class DigestAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testHandleWithValidDigest()
+ {
+ $time = microtime(true) + 1000;
+ $secret = 'ThisIsASecret';
+ $nonce = base64_encode($time.':'.md5($time.':'.$secret));
+ $username = 'user';
+ $password = 'password';
+ $realm = 'Welcome, robot!';
+ $cnonce = 'MDIwODkz';
+ $nc = '00000001';
+ $qop = 'auth';
+ $uri = '/path/info?p1=5&p2=5';
+
+ $serverDigest = $this->calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, 'GET', $uri);
+
+ $digestData =
+ 'username="'.$username.'", realm="'.$realm.'", nonce="'.$nonce.'", '.
+ 'uri="'.$uri.'", cnonce="'.$cnonce.'", nc='.$nc.', qop="'.$qop.'", '.
+ 'response="'.$serverDigest.'"'
+ ;
+
+ $request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_DIGEST' => $digestData));
+
+ $entryPoint = new DigestAuthenticationEntryPoint($realm, $secret);
+
+ $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $user->method('getPassword')->willReturn($password);
+
+ $providerKey = 'TheProviderKey';
+
+ $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $tokenStorage
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue(null))
+ ;
+ $tokenStorage
+ ->expects($this->once())
+ ->method('setToken')
+ ->with($this->equalTo(new UsernamePasswordToken($user, $password, $providerKey)))
+ ;
+
+ $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
+ $userProvider->method('loadUserByUsername')->willReturn($user);
+
+ $listener = new DigestAuthenticationListener($tokenStorage, $userProvider, $providerKey, $entryPoint);
+
+ $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
+ $event
+ ->expects($this->any())
+ ->method('getRequest')
+ ->will($this->returnValue($request))
+ ;
+
+ $listener->handle($event);
+ }
+
+ private function calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, $method, $uri)
+ {
+ $response = md5(
+ md5($username.':'.$realm.':'.$password).':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.md5($method.':'.$uri)
+ );
+
+ return sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"',
+ $username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response
+ );
+ }
+}
diff --git a/Http/Tests/Firewall/LogoutListenerTest.php b/Http/Tests/Firewall/LogoutListenerTest.php
index 15c996e..367c810 100644
--- a/Http/Tests/Firewall/LogoutListenerTest.php
+++ b/Http/Tests/Firewall/LogoutListenerTest.php
@@ -213,7 +213,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
$successHandler ?: $this->getSuccessHandler(),
$options = array(
'csrf_parameter' => '_csrf_token',
- 'intention' => 'logout',
+ 'csrf_token_id' => 'logout',
'logout_path' => '/logout',
'target_url' => '/',
),
diff --git a/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php b/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php
index 0a1286c..adf91b1 100644
--- a/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php
+++ b/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php
@@ -42,7 +42,7 @@ class SimplePreAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($this->token))
;
- $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface');
+ $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface');
$simpleAuthenticator
->expects($this->once())
->method('createToken')
@@ -79,7 +79,7 @@ class SimplePreAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
->with($this->equalTo(null))
;
- $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface');
+ $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface');
$simpleAuthenticator
->expects($this->once())
->method('createToken')
diff --git a/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php b/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
index ddfaaeb..7495398 100644
--- a/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
@@ -25,10 +25,10 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', $service->getRememberMeParameter());
}
- public function testGetKey()
+ public function testGetSecret()
{
$service = $this->getService();
- $this->assertEquals('fookey', $service->getKey());
+ $this->assertEquals('foosecret', $service->getSecret());
}
public function testAutoLoginReturnsNullWhenNoCookie()
@@ -78,7 +78,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$returnedToken = $service->autoLogin($request);
$this->assertSame($user, $returnedToken->getUser());
- $this->assertSame('fookey', $returnedToken->getKey());
+ $this->assertSame('foosecret', $returnedToken->getSecret());
$this->assertSame('fookey', $returnedToken->getProviderKey());
}
@@ -284,7 +284,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
}
return $this->getMockForAbstractClass('Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', array(
- array($userProvider), 'fookey', 'fookey', $options, $logger,
+ array($userProvider), 'foosecret', 'fookey', $options, $logger,
));
}
diff --git a/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php b/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
index f43963e..30cf4a2 100644
--- a/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
@@ -20,7 +20,6 @@ use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices;
use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
-use Symfony\Component\Security\Core\Util\SecureRandom;
class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
{
@@ -183,7 +182,7 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $returnedToken);
$this->assertSame($user, $returnedToken->getUser());
- $this->assertEquals('fookey', $returnedToken->getKey());
+ $this->assertEquals('foosecret', $returnedToken->getSecret());
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
@@ -322,7 +321,7 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
$userProvider = $this->getProvider();
}
- return new PersistentTokenBasedRememberMeServices(array($userProvider), 'fookey', 'fookey', $options, $logger, new SecureRandom(sys_get_temp_dir().'/_sf2.seed'));
+ return new PersistentTokenBasedRememberMeServices(array($userProvider), 'foosecret', 'fookey', $options, $logger);
}
protected function getProvider()
diff --git a/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php b/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
index e3b58e9..ee8a99e 100644
--- a/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
@@ -140,7 +140,7 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $returnedToken);
$this->assertSame($user, $returnedToken->getUser());
- $this->assertEquals('fookey', $returnedToken->getKey());
+ $this->assertEquals('foosecret', $returnedToken->getSecret());
}
public function provideUsernamesForAutoLogin()
@@ -265,7 +265,7 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$userProvider = $this->getProvider();
}
- $service = new TokenBasedRememberMeServices(array($userProvider), 'fookey', 'fookey', $options, $logger);
+ $service = new TokenBasedRememberMeServices(array($userProvider), 'foosecret', 'fookey', $options, $logger);
return $service;
}
diff --git a/Http/composer.json b/Http/composer.json
index 1b36428..24708ac 100644
--- a/Http/composer.json
+++ b/Http/composer.json
@@ -17,14 +17,17 @@
],
"require": {
"php": ">=5.3.9",
- "symfony/security-core": "~2.6",
- "symfony/event-dispatcher": "~2.1",
- "symfony/http-foundation": "~2.4",
- "symfony/http-kernel": "~2.4"
+ "symfony/security-core": "~2.8",
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
+ "symfony/http-foundation": "~2.4|~3.0.0",
+ "symfony/http-kernel": "~2.4|~3.0.0",
+ "symfony/polyfill-php56": "~1.0",
+ "symfony/polyfill-php70": "~1.0",
+ "symfony/property-access": "~2.3|~3.0.0"
},
"require-dev": {
- "symfony/routing": "~2.2",
- "symfony/security-csrf": "~2.4",
+ "symfony/routing": "~2.2|~3.0.0",
+ "symfony/security-csrf": "~2.4|~3.0.0",
"psr/log": "~1.0"
},
"suggest": {
@@ -40,7 +43,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
}
}
diff --git a/composer.json b/composer.json
index b64e1b8..3eab48b 100644
--- a/composer.json
+++ b/composer.json
@@ -17,37 +17,37 @@
],
"require": {
"php": ">=5.3.9",
- "paragonie/random_compat": "~1.0",
- "symfony/event-dispatcher": "~2.2",
- "symfony/http-foundation": "~2.1",
- "symfony/http-kernel": "~2.4"
+ "symfony/security-acl": "~2.7|~3.0.0",
+ "symfony/event-dispatcher": "~2.2|~3.0.0",
+ "symfony/http-foundation": "~2.1|~3.0.0",
+ "symfony/http-kernel": "~2.4|~3.0.0",
+ "symfony/polyfill-php55": "~1.0",
+ "symfony/polyfill-php56": "~1.0",
+ "symfony/polyfill-php70": "~1.0",
+ "symfony/polyfill-util": "~1.0",
+ "symfony/property-access": "~2.3|~3.0.0"
},
"replace": {
- "symfony/security-acl": "self.version",
"symfony/security-core": "self.version",
"symfony/security-csrf": "self.version",
+ "symfony/security-guard": "self.version",
"symfony/security-http": "self.version"
},
"require-dev": {
- "symfony/finder": "~2.3",
- "symfony/intl": "~2.3",
- "symfony/routing": "~2.2",
- "symfony/validator": "~2.5,>=2.5.9",
- "doctrine/common": "~2.2",
- "doctrine/dbal": "~2.2",
+ "symfony/finder": "~2.3|~3.0.0",
+ "symfony/polyfill-intl-icu": "~1.0",
+ "symfony/routing": "~2.2|~3.0.0",
+ "symfony/validator": "~2.5,>=2.5.9|~3.0.0",
"psr/log": "~1.0",
- "ircmaxell/password-compat": "~1.0",
- "symfony/expression-language": "~2.6"
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/ldap": "~2.8|~3.0.0"
},
"suggest": {
- "symfony/class-loader": "For using the ACL generateSql script",
- "symfony/finder": "For using the ACL generateSql script",
"symfony/form": "",
"symfony/validator": "For using the user password constraint",
"symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs",
- "doctrine/dbal": "For using the built-in ACL implementation",
"symfony/expression-language": "For using the expression voter",
- "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5"
+ "symfony/ldap": "For using the LDAP user and authentication providers"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Security\\": "" },
@@ -58,7 +58,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
}
}