diff options
author | Bernhard Schussek <bernhard.schussek@symfony-project.com> | 2011-03-13 18:10:39 +0100 |
---|---|---|
committer | Bernhard Schussek <bernhard.schussek@symfony-project.com> | 2011-03-13 19:15:25 +0100 |
commit | 263ba4d42870ef5f991540c8b039c2472ba8b204 (patch) | |
tree | 90a84bb2a178be744ef3815c6a2bb7268baa9f34 | |
parent | 4a5d6729bc8c7f4adc89c153606617390bb24ca4 (diff) | |
parent | 5a06947e48c33dc57e21e4316c8b7c6e8f5827b0 (diff) | |
download | symfony-security-263ba4d42870ef5f991540c8b039c2472ba8b204.zip symfony-security-263ba4d42870ef5f991540c8b039c2472ba8b204.tar.gz symfony-security-263ba4d42870ef5f991540c8b039c2472ba8b204.tar.bz2 |
Merge remote branch 'symfony/master' into event-manager
Conflicts:
src/Symfony/Bundle/FrameworkBundle/Debug/TraceableEventManager.php
src/Symfony/Bundle/WebProfilerBundle/WebDebugToolbarListener.php
src/Symfony/Component/Security/Http/Firewall.php
src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php
src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php
src/Symfony/Component/Security/Http/Firewall/AccessListener.php
src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php
src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php
src/Symfony/Component/Security/Http/Firewall/ChannelListener.php
src/Symfony/Component/Security/Http/Firewall/ContextListener.php
src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php
src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
src/Symfony/Component/Security/Http/Firewall/ListenerInterface.php
src/Symfony/Component/Security/Http/Firewall/LogoutListener.php
src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php
src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
tests/Symfony/Tests/Component/Security/Http/Firewall/RememberMeListenerTest.php
86 files changed, 1113 insertions, 1453 deletions
diff --git a/Acl/Dbal/AclProvider.php b/Acl/Dbal/AclProvider.php index 2335f69..2ef711d 100644 --- a/Acl/Dbal/AclProvider.php +++ b/Acl/Dbal/AclProvider.php @@ -38,12 +38,12 @@ class AclProvider implements AclProviderInterface { const MAX_BATCH_SIZE = 30; - protected $aclCache; + protected $cache; protected $connection; protected $loadedAces; protected $loadedAcls; protected $options; - protected $permissionGrantingStrategy; + private $permissionGrantingStrategy; /** * Constructor @@ -51,11 +51,11 @@ class AclProvider implements AclProviderInterface * @param Connection $connection * @param PermissionGrantingStrategyInterface $permissionGrantingStrategy * @param array $options - * @param AclCacheInterface $aclCache + * @param AclCacheInterface $cache */ - public function __construct(Connection $connection, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $options, AclCacheInterface $aclCache = null) + public function __construct(Connection $connection, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $options, AclCacheInterface $cache = null) { - $this->aclCache = $aclCache; + $this->cache = $cache; $this->connection = $connection; $this->loadedAces = array(); $this->loadedAcls = array(); @@ -122,8 +122,8 @@ class AclProvider implements AclProviderInterface } // check if we can locate the ACL in the cache - if (!$aclFound && null !== $this->aclCache) { - $acl = $this->aclCache->getFromCacheByIdentity($oid); + if (!$aclFound && null !== $this->cache) { + $acl = $this->cache->getFromCacheByIdentity($oid); if (null !== $acl) { if ($acl->isSidLoaded($sids)) { @@ -149,10 +149,10 @@ class AclProvider implements AclProviderInterface $result->attach($oid, $acl); $aclFound = true; } else { - $this->aclCache->evictFromCacheByIdentity($oid); + $this->cache->evictFromCacheByIdentity($oid); foreach ($this->findChildren($oid) as $childOid) { - $this->aclCache->evictFromCacheByIdentity($childOid); + $this->cache->evictFromCacheByIdentity($childOid); } } } @@ -170,8 +170,8 @@ class AclProvider implements AclProviderInterface foreach ($loadedBatch as $loadedOid) { $loadedAcl = $loadedBatch->offsetGet($loadedOid); - if (null !== $this->aclCache) { - $this->aclCache->putInCache($loadedAcl); + if (null !== $this->cache) { + $this->cache->putInCache($loadedAcl); } if (isset($oidLookup[$loadedOid->getIdentifier().$loadedOid->getType()])) { @@ -201,12 +201,156 @@ class AclProvider implements AclProviderInterface } /** + * 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 acl_object_identities o + INNER JOIN acl_classes c ON c.id = o.class_id + INNER JOIN acl_object_identity_ancestors a ON a.object_identity_id = o.id + WHERE ( +SELECTCLAUSE; + + $where = '(o.object_identifier = %s AND c.class_type = %s)'; + for ($i=0,$c=count($batch); $i<$c; $i++) { + $sql .= sprintf( + $where, + $this->connection->quote($batch[$i]->getIdentifier()), + $this->connection->quote($batch[$i]->getType()) + ); + + if ($i+1 < $c) { + $sql .= ' OR '; + } + } + + $sql .= ')'; + + return $sql; + } + + /** + * Constructs the SQL for retrieving child object identities for the given + * object identities. + * + * @param ObjectIdentityInterface $oid + * @param Boolean $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']} as o + INNER JOIN {$this->options['class_table_name']} as c ON c.id = o.class_id + INNER JOIN {$this->options['oid_ancestors_table_name']} as 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']} as o + INNER JOIN {$this->options['class_table_name']} as 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 + LIMIT 1 +QUERY; + + return sprintf( + $query, + $this->options['oid_table_name'], + $this->options['class_table_name'], + $this->connection->quote($oid->getIdentifier()), + $this->connection->quote($oid->getType()) + ); + } + + /** + * Returns the primary key of the passed object identity. + * + * @param ObjectIdentityInterface $oid + * @return integer + */ + protected final 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 * @return void */ - protected function updateAceIdentityMap(AclInterface $acl) + private function updateAceIdentityMap(AclInterface $acl) { foreach (array('classAces', 'classFieldAces', 'objectAces', 'objectFieldAces') as $property) { $reflection = new \ReflectionProperty($acl, $property); @@ -227,13 +371,34 @@ class AclProvider implements AclProviderInterface } /** + * 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 + + $ancestorIds[] = $data['ancestor_id']; + } + + 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 * @return void */ - protected function doUpdateAceIdentityMap(array &$aces) + private function doUpdateAceIdentityMap(array &$aces) { foreach ($aces as $index => $ace) { if (isset($this->loadedAces[$ace->getId()])) { @@ -254,9 +419,14 @@ class AclProvider implements AclProviderInterface * * @return \SplObjectStorage mapping object identities to ACL instances */ - protected function lookupObjectIdentities(array $batch, array $sids, array $oidLookup) + private function lookupObjectIdentities(array $batch, array $sids, array $oidLookup) { - $sql = $this->getLookupSql($batch, $sids); + $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); @@ -277,7 +447,7 @@ class AclProvider implements AclProviderInterface * @throws \RuntimeException * @return \SplObjectStorage */ - protected function hydrateObjectIdentities(Statement $stmt, array $oidLookup, array $sids) { + private function hydrateObjectIdentities(Statement $stmt, array $oidLookup, array $sids) { $parentIdToFill = new \SplObjectStorage(); $acls = $aces = $emptyArray = array(); $oidCache = $oidLookup; @@ -464,169 +634,4 @@ class AclProvider implements AclProviderInterface return $result; } - - /** - * Constructs the query used for looking up object identities and associated - * ACEs, and security identities. - * - * @param array $batch - * @param array $sids - * @throws AclNotFoundException - * @return string - */ - protected function getLookupSql(array $batch, array $sids) - { - // FIXME: add support for filtering by sids (right now we select all sids) - - $ancestorIds = $this->getAncestorIds($batch); - if (0 === count($ancestorIds)) { - throw new AclNotFoundException('There is no ACL for the given object identity.'); - } - - $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; - } - - /** - * Retrieves all the ids which need to be queried from the database - * including the ids of parent ACLs. - * - * @param array $batch - * @return array - */ - protected function getAncestorIds(array &$batch) - { - $sql = <<<SELECTCLAUSE - SELECT a.ancestor_id - FROM acl_object_identities o - INNER JOIN acl_classes c ON c.id = o.class_id - INNER JOIN acl_object_identity_ancestors a ON a.object_identity_id = o.id - WHERE ( -SELECTCLAUSE; - - $where = '(o.object_identifier = %s AND c.class_type = %s)'; - for ($i=0,$c=count($batch); $i<$c; $i++) { - $sql .= sprintf( - $where, - $this->connection->quote($batch[$i]->getIdentifier()), - $this->connection->quote($batch[$i]->getType()) - ); - - if ($i+1 < $c) { - $sql .= ' OR '; - } - } - - $sql .= ')'; - - $ancestorIds = array(); - foreach ($this->connection->executeQuery($sql)->fetchAll() as $data) { - // FIXME: skip ancestors which are cached - - $ancestorIds[] = $data['ancestor_id']; - } - - return $ancestorIds; - } - - /** - * Constructs the SQL for retrieving child object identities for the given - * object identities. - * - * @param ObjectIdentityInterface $oid - * @param Boolean $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']} as o - INNER JOIN {$this->options['class_table_name']} as c ON c.id = o.class_id - INNER JOIN {$this->options['oid_ancestors_table_name']} as 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']} as o - INNER JOIN {$this->options['class_table_name']} as 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 - LIMIT 1 -QUERY; - - return sprintf( - $query, - $this->options['oid_table_name'], - $this->options['class_table_name'], - $this->connection->quote($oid->getIdentifier()), - $this->connection->quote($oid->getType()) - ); - } - - /** - * Returns the primary key of the passed object identity. - * - * @param ObjectIdentityInterface $oid - * @return integer - */ - protected function retrieveObjectIdentityPrimaryKey(ObjectIdentityInterface $oid) - { - return $this->connection->executeQuery($this->getSelectObjectIdentityIdSql($oid))->fetchColumn(); - } } diff --git a/Acl/Dbal/MutableAclProvider.php b/Acl/Dbal/MutableAclProvider.php index 9b36d6a..52d1a9b 100644 --- a/Acl/Dbal/MutableAclProvider.php +++ b/Acl/Dbal/MutableAclProvider.php @@ -34,14 +34,14 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; */ class MutableAclProvider extends AclProvider implements MutableAclProviderInterface, PropertyChangedListener { - protected $propertyChanges; + private $propertyChanges; /** * {@inheritDoc} */ - public function __construct(Connection $connection, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $options, AclCacheInterface $aclCache = null) + public function __construct(Connection $connection, PermissionGrantingStrategyInterface $permissionGrantingStrategy, array $options, AclCacheInterface $cache = null) { - parent::__construct($connection, $permissionGrantingStrategy, $options, $aclCache); + parent::__construct($connection, $permissionGrantingStrategy, $options, $cache); $this->propertyChanges = new \SplObjectStorage(); } @@ -104,8 +104,8 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf } // evict the ACL from any caches - if (null !== $this->aclCache) { - $this->aclCache->evictFromCacheByIdentity($oid); + if (null !== $this->cache) { + $this->cache->evictFromCacheByIdentity($oid); } } @@ -312,111 +312,26 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf $this->propertyChanges->offsetSet($acl, array()); - if (null !== $this->aclCache) { + 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->aclCache->clearCache(); + $this->cache->clearCache(); } else { // if there are no shared property changes, it's sufficient to just delete // the cache for this ACL - $this->aclCache->evictFromCacheByIdentity($acl->getObjectIdentity()); + $this->cache->evictFromCacheByIdentity($acl->getObjectIdentity()); foreach ($this->findChildren($acl->getObjectIdentity()) as $childOid) { - $this->aclCache->evictFromCacheByIdentity($childOid); + $this->cache->evictFromCacheByIdentity($childOid); } } } } /** - * Creates the ACL for the passed object identity - * - * @param ObjectIdentityInterface $oid - * @return void - */ - protected 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 integer - */ - protected 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 integer - */ - protected 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 integer $oidPK - * @return void - */ - protected function deleteAccessControlEntries($oidPK) - { - $this->connection->executeQuery($this->getDeleteAccessControlEntriesSql($oidPK)); - } - - /** - * Deletes the object identity from the database. - * - * @param integer $pk - * @return void - */ - protected function deleteObjectIdentity($pk) - { - $this->connection->executeQuery($this->getDeleteObjectIdentitySql($pk)); - } - - /** - * Deletes all entries from the relations table from the database. - * - * @param integer $pk - * @return void - */ - protected function deleteObjectIdentityRelations($pk) - { - $this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk)); - } - - /** * Constructs the SQL for deleting access control entries. * * @param integer $oidPK @@ -721,12 +636,97 @@ QUERY; } /** + * Creates the ACL for the passed object identity + * + * @param ObjectIdentityInterface $oid + * @return void + */ + 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 integer + */ + 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 integer + */ + 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 integer $oidPK + * @return void + */ + private function deleteAccessControlEntries($oidPK) + { + $this->connection->executeQuery($this->getDeleteAccessControlEntriesSql($oidPK)); + } + + /** + * Deletes the object identity from the database. + * + * @param integer $pk + * @return void + */ + private function deleteObjectIdentity($pk) + { + $this->connection->executeQuery($this->getDeleteObjectIdentitySql($pk)); + } + + /** + * Deletes all entries from the relations table from the database. + * + * @param integer $pk + * @return void + */ + 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 * @return void */ - protected function regenerateAncestorRelations(AclInterface $acl) + private function regenerateAncestorRelations(AclInterface $acl) { $pk = $acl->getId(); $this->connection->executeQuery($this->getDeleteObjectIdentityRelationsSql($pk)); @@ -747,7 +747,7 @@ QUERY; * @param array $changes * @return void */ - protected function updateFieldAceProperty($name, array $changes) + private function updateFieldAceProperty($name, array $changes) { $sids = new \SplObjectStorage(); $classIds = new \SplObjectStorage(); @@ -804,7 +804,7 @@ QUERY; * @param array $changes * @return void */ - protected function updateAceProperty($name, array $changes) + private function updateAceProperty($name, array $changes) { list($old, $new) = $changes; @@ -858,7 +858,7 @@ QUERY; * @param \SplObjectStorage $aces * @return void */ - protected function updateAces(\SplObjectStorage $aces) + private function updateAces(\SplObjectStorage $aces) { foreach ($aces as $ace) { $propertyChanges = $aces->offsetGet($ace); diff --git a/Acl/Dbal/Schema.php b/Acl/Dbal/Schema.php index 29907b4..09d60aa 100644 --- a/Acl/Dbal/Schema.php +++ b/Acl/Dbal/Schema.php @@ -18,7 +18,7 @@ use Doctrine\DBAL\Schema\Schema as BaseSchema; * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -class Schema extends BaseSchema +final class Schema extends BaseSchema { protected $options; diff --git a/Acl/Domain/Acl.php b/Acl/Domain/Acl.php index 6769617..20f300b 100644 --- a/Acl/Domain/Acl.php +++ b/Acl/Domain/Acl.php @@ -35,17 +35,17 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; */ class Acl implements AuditableAclInterface { - protected $parentAcl; - protected $permissionGrantingStrategy; - protected $objectIdentity; - protected $classAces; - protected $classFieldAces; - protected $objectAces; - protected $objectFieldAces; - protected $id; - protected $loadedSids; - protected $entriesInheriting; - protected $listeners; + private $parentAcl; + private $permissionGrantingStrategy; + private $objectIdentity; + private $classAces; + private $classFieldAces; + private $objectAces; + private $objectFieldAces; + private $id; + private $loadedSids; + private $entriesInheriting; + private $listeners; /** * Constructor @@ -406,7 +406,7 @@ class Acl implements AuditableAclInterface * @throws \OutOfBoundsException * @return void */ - protected function deleteAce($property, $index) + private function deleteAce($property, $index) { $aces =& $this->$property; if (!isset($aces[$index])) { @@ -432,7 +432,7 @@ class Acl implements AuditableAclInterface * @throws \OutOfBoundsException * @return void */ - protected function deleteFieldAce($property, $index, $field) + private function deleteFieldAce($property, $index, $field) { $aces =& $this->$property; if (!isset($aces[$field][$index])) { @@ -462,7 +462,7 @@ class Acl implements AuditableAclInterface * @throws \InvalidArgumentException * @return void */ - protected function insertAce($property, $index, $mask, SecurityIdentityInterface $sid, $granting, $strategy = null) + 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))); @@ -512,7 +512,7 @@ class Acl implements AuditableAclInterface * @throws \OutOfBoundsException * @return void */ - protected function insertFieldAce($property, $index, $field, $mask, SecurityIdentityInterface $sid, $granting, $strategy = null) + private function insertFieldAce($property, $index, $field, $mask, SecurityIdentityInterface $sid, $granting, $strategy = null) { if (0 === strlen($field)) { throw new \InvalidArgumentException('$field cannot be empty.'); @@ -557,37 +557,6 @@ class Acl implements AuditableAclInterface } /** - * Called when a property of the ACL changes - * - * @param string $name - * @param mixed $oldValue - * @param mixed $newValue - * @return void - */ - protected 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 - * @return void - */ - protected function onEntryPropertyChanged(EntryInterface $entry, $name, $oldValue, $newValue) - { - foreach ($this->listeners as $listener) { - $listener->propertyChanged($entry, $name, $oldValue, $newValue); - } - } - - /** * Updates an ACE * * @param string $property @@ -597,7 +566,7 @@ class Acl implements AuditableAclInterface * @throws \OutOfBoundsException * @return void */ - protected function updateAce($property, $index, $mask, $strategy = null) + private function updateAce($property, $index, $mask, $strategy = null) { $aces =& $this->$property; if (!isset($aces[$index])) { @@ -625,7 +594,7 @@ class Acl implements AuditableAclInterface * @throws \OutOfBoundsException * @return void */ - protected function updateAuditing(array &$aces, $index, $auditSuccess, $auditFailure) + private function updateAuditing(array &$aces, $index, $auditSuccess, $auditFailure) { if (!isset($aces[$index])) { throw new \OutOfBoundsException(sprintf('The index "%d" does not exist.', $index)); @@ -654,7 +623,7 @@ class Acl implements AuditableAclInterface * @throws \OutOfBoundsException * @return void */ - protected function updateFieldAce($property, $index, $field, $mask, $strategy = null) + private function updateFieldAce($property, $index, $field, $mask, $strategy = null) { if (0 === strlen($field)) { throw new \InvalidArgumentException('$field cannot be empty.'); @@ -675,4 +644,35 @@ class Acl implements AuditableAclInterface $ace->setStrategy($strategy); } } + + /** + * Called when a property of the ACL changes + * + * @param string $name + * @param mixed $oldValue + * @param mixed $newValue + * @return void + */ + 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 + * @return void + */ + 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 index 81c88fe..f3fe6f0 100644 --- a/Acl/Domain/AclCollectionCache.php +++ b/Acl/Domain/AclCollectionCache.php @@ -22,9 +22,9 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterf */ class AclCollectionCache { - protected $aclProvider; - protected $objectIdentityRetrievalStrategy; - protected $securityIdentityRetrievalStrategy; + private $aclProvider; + private $objectIdentityRetrievalStrategy; + private $securityIdentityRetrievalStrategy; /** * Constructor diff --git a/Acl/Domain/DoctrineAclCache.php b/Acl/Domain/DoctrineAclCache.php index 3aae00f..eb18986 100644 --- a/Acl/Domain/DoctrineAclCache.php +++ b/Acl/Domain/DoctrineAclCache.php @@ -26,9 +26,9 @@ class DoctrineAclCache implements AclCacheInterface { const PREFIX = 'sf2_acl_'; - protected $cache; - protected $prefix; - protected $permissionGrantingStrategy; + private $cache; + private $prefix; + private $permissionGrantingStrategy; /** * Constructor @@ -145,7 +145,7 @@ class DoctrineAclCache implements AclCacheInterface * @param string $serialized * @return AclInterface */ - protected function unserializeAcl($serialized) + private function unserializeAcl($serialized) { $acl = unserialize($serialized); @@ -203,7 +203,7 @@ class DoctrineAclCache implements AclCacheInterface * @param ObjectIdentityInterface $oid * @return string */ - protected function getDataKeyByIdentity(ObjectIdentityInterface $oid) + private function getDataKeyByIdentity(ObjectIdentityInterface $oid) { return $this->prefix.md5($oid->getType()).sha1($oid->getType()) .'_'.md5($oid->getIdentifier()).sha1($oid->getIdentifier()); @@ -215,7 +215,7 @@ class DoctrineAclCache implements AclCacheInterface * @param string $aclId * @return string */ - protected function getAliasKeyForIdentity($aclId) + private function getAliasKeyForIdentity($aclId) { return $this->prefix.$aclId; } diff --git a/Acl/Domain/Entry.php b/Acl/Domain/Entry.php index 67e76ad..7498b03 100644 --- a/Acl/Domain/Entry.php +++ b/Acl/Domain/Entry.php @@ -23,14 +23,14 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; */ class Entry implements AuditableEntryInterface { - protected $acl; - protected $mask; - protected $id; - protected $securityIdentity; - protected $strategy; - protected $auditFailure; - protected $auditSuccess; - protected $granting; + private $acl; + private $mask; + private $id; + private $securityIdentity; + private $strategy; + private $auditFailure; + private $auditSuccess; + private $granting; /** * Constructor @@ -122,10 +122,10 @@ class Entry implements AuditableEntryInterface /** * Turns on/off auditing on permissions denials. - * + * * Do never call this method directly. Use the respective methods on the * AclInterface instead. - * + * * @param Boolean $boolean * @return void */ @@ -136,10 +136,10 @@ class Entry implements AuditableEntryInterface /** * Turns on/off auditing on permission grants. - * + * * Do never call this method directly. Use the respective methods on the * AclInterface instead. - * + * * @param Boolean $boolean * @return void */ @@ -153,7 +153,7 @@ class Entry implements AuditableEntryInterface * * Do never call this method directly. Use the respective methods on the * AclInterface instead. - * + * * @param integer $mask * @return void */ @@ -167,7 +167,7 @@ class Entry implements AuditableEntryInterface * * Do never call this method directly. Use the respective methods on the * AclInterface instead. - * + * * @param string $strategy * @return void */ diff --git a/Acl/Domain/FieldEntry.php b/Acl/Domain/FieldEntry.php index 430f013..0f71237 100644 --- a/Acl/Domain/FieldEntry.php +++ b/Acl/Domain/FieldEntry.php @@ -22,7 +22,7 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; */ class FieldEntry extends Entry implements FieldAwareEntryInterface { - protected $field; + private $field; /** * Constructor @@ -60,13 +60,7 @@ class FieldEntry extends Entry implements FieldAwareEntryInterface { return serialize(array( $this->field, - $this->mask, - $this->id, - $this->securityIdentity, - $this->strategy, - $this->auditFailure, - $this->auditSuccess, - $this->granting, + parent::serialize(), )); } @@ -75,14 +69,7 @@ class FieldEntry extends Entry implements FieldAwareEntryInterface */ public function unserialize($serialized) { - list($this->field, - $this->mask, - $this->id, - $this->securityIdentity, - $this->strategy, - $this->auditFailure, - $this->auditSuccess, - $this->granting - ) = unserialize($serialized); + list($this->field, $parentStr) = unserialize($serialized); + parent::unserialize($parentStr); } }
\ No newline at end of file diff --git a/Acl/Domain/ObjectIdentity.php b/Acl/Domain/ObjectIdentity.php index 8fc099b..2cb1352 100644 --- a/Acl/Domain/ObjectIdentity.php +++ b/Acl/Domain/ObjectIdentity.php @@ -22,8 +22,8 @@ use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface; */ class ObjectIdentity implements ObjectIdentityInterface { - protected $identifier; - protected $type; + private $identifier; + private $type; /** * Constructor diff --git a/Acl/Domain/PermissionGrantingStrategy.php b/Acl/Domain/PermissionGrantingStrategy.php index 9b44177..8bee157 100644 --- a/Acl/Domain/PermissionGrantingStrategy.php +++ b/Acl/Domain/PermissionGrantingStrategy.php @@ -30,8 +30,8 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface const ALL = 'all'; const ANY = 'any'; - protected static $noAceException; - protected $auditLogger; + private static $noAceException; + private $auditLogger; public function __construct() { @@ -52,16 +52,6 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface } /** - * Returns the audit logger - * - * @return AuditLoggerInterface - */ - public function getAuditLogger() - { - return $this->auditLogger; - } - - /** * {@inheritDoc} */ public function isGranted(AclInterface $acl, array $masks, array $sids, $administrativeMode = false) @@ -153,7 +143,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface * @param Boolean $administrativeMode true turns off audit logging * @return Boolean true, or false; either granting, or denying access respectively. */ - protected function hasSufficientPermissions(AclInterface $acl, array $aces, array $masks, array $sids, $administrativeMode) + private function hasSufficientPermissions(AclInterface $acl, array $aces, array $masks, array $sids, $administrativeMode) { $firstRejectedAce = null; @@ -211,7 +201,7 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface * @param EntryInterface $ace * @return Boolean */ - protected function isAceApplicable($requiredMask, EntryInterface $ace) + private function isAceApplicable($requiredMask, EntryInterface $ace) { $strategy = $ace->getStrategy(); if (self::ALL === $strategy) { diff --git a/Acl/Domain/RoleSecurityIdentity.php b/Acl/Domain/RoleSecurityIdentity.php index a824032..d3694e6 100644 --- a/Acl/Domain/RoleSecurityIdentity.php +++ b/Acl/Domain/RoleSecurityIdentity.php @@ -21,7 +21,7 @@ use Symfony\Component\Security\Core\Role\Role; */ class RoleSecurityIdentity implements SecurityIdentityInterface { - protected $role; + private $role; /** * Constructor diff --git a/Acl/Domain/SecurityIdentityRetrievalStrategy.php b/Acl/Domain/SecurityIdentityRetrievalStrategy.php index c810e38..1252a0f 100644 --- a/Acl/Domain/SecurityIdentityRetrievalStrategy.php +++ b/Acl/Domain/SecurityIdentityRetrievalStrategy.php @@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Acl\Domain; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; @@ -27,8 +27,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; */ class SecurityIdentityRetrievalStrategy implements SecurityIdentityRetrievalStrategyInterface { - protected $roleHierarchy; - protected $authenticationTrustResolver; + private $roleHierarchy; + private $authenticationTrustResolver; /** * Constructor diff --git a/Acl/Domain/UserSecurityIdentity.php b/Acl/Domain/UserSecurityIdentity.php index 4073bb4..ac63080 100644 --- a/Acl/Domain/UserSecurityIdentity.php +++ b/Acl/Domain/UserSecurityIdentity.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Security\Acl\Domain; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; /** @@ -22,8 +22,8 @@ use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; */ class UserSecurityIdentity implements SecurityIdentityInterface { - protected $username; - protected $class; + private $username; + private $class; /** * Constructor @@ -45,12 +45,12 @@ class UserSecurityIdentity implements SecurityIdentityInterface } /** - * Creates a user security identity from an AccountInterface + * Creates a user security identity from an UserInterface * - * @param AccountInterface $user + * @param UserInterface $user * @return UserSecurityIdentity */ - public static function fromAccount(AccountInterface $user) + public static function fromAccount(UserInterface $user) { return new self($user->getUsername(), get_class($user)); } @@ -65,7 +65,7 @@ class UserSecurityIdentity implements SecurityIdentityInterface { $user = $token->getUser(); - if ($user instanceof AccountInterface) { + if ($user instanceof UserInterface) { return self::fromAccount($user); } diff --git a/Acl/Exception/NotAllAclsFoundException.php b/Acl/Exception/NotAllAclsFoundException.php index 7db9b21..820d933 100644 --- a/Acl/Exception/NotAllAclsFoundException.php +++ b/Acl/Exception/NotAllAclsFoundException.php @@ -22,7 +22,7 @@ namespace Symfony\Component\Security\Acl\Exception; */ class NotAllAclsFoundException extends AclNotFoundException { - protected $partialResult; + private $partialResult; /** * Sets the partial result diff --git a/Acl/Permission/BasicPermissionMap.php b/Acl/Permission/BasicPermissionMap.php index 4818e0c..18006ff 100644 --- a/Acl/Permission/BasicPermissionMap.php +++ b/Acl/Permission/BasicPermissionMap.php @@ -28,7 +28,7 @@ class BasicPermissionMap implements PermissionMapInterface const PERMISSION_MASTER = 'MASTER'; const PERMISSION_OWNER = 'OWNER'; - protected $map = array( + private $map = array( self::PERMISSION_VIEW => array( MaskBuilder::MASK_VIEW, MaskBuilder::MASK_EDIT, diff --git a/Acl/Permission/MaskBuilder.php b/Acl/Permission/MaskBuilder.php index b1c283a..9965228 100644 --- a/Acl/Permission/MaskBuilder.php +++ b/Acl/Permission/MaskBuilder.php @@ -67,7 +67,7 @@ class MaskBuilder const OFF = '.'; const ON = '*'; - protected $mask; + private $mask; /** * Constructor diff --git a/Acl/Voter/AclVoter.php b/Acl/Voter/AclVoter.php index bc70c59..e7811ed 100644 --- a/Acl/Voter/AclVoter.php +++ b/Acl/Voter/AclVoter.php @@ -32,12 +32,12 @@ use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; */ class AclVoter implements VoterInterface { - protected $aclProvider; - protected $permissionMap; - protected $objectIdentityRetrievalStrategy; - protected $securityIdentityRetrievalStrategy; - protected $allowIfObjectIdentityUnavailable; - protected $logger; + 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) { diff --git a/Acl/Voter/FieldVote.php b/Acl/Voter/FieldVote.php index 7b7f39a..01f0c20 100644 --- a/Acl/Voter/FieldVote.php +++ b/Acl/Voter/FieldVote.php @@ -19,8 +19,8 @@ namespace Symfony\Component\Security\Acl\Voter; */ class FieldVote { - protected $domainObject; - protected $field; + private $domainObject; + private $field; public function __construct($domainObject, $field) { diff --git a/Core/Authentication/AuthenticationManagerInterface.php b/Core/Authentication/AuthenticationManagerInterface.php index 5f407f2..36cdc92 100644 --- a/Core/Authentication/AuthenticationManagerInterface.php +++ b/Core/Authentication/AuthenticationManagerInterface.php @@ -27,7 +27,7 @@ interface AuthenticationManagerInterface * * @param TokenInterface $token The TokenInterface instance to authenticate * - * @return TokenInterface An authenticated TokenInterface instance + * @return TokenInterface An authenticated TokenInterface instance, never null * * @throws AuthenticationException if the authentication fails */ diff --git a/Core/Authentication/AuthenticationProviderManager.php b/Core/Authentication/AuthenticationProviderManager.php index ac1e36d..1d85e87 100644 --- a/Core/Authentication/AuthenticationProviderManager.php +++ b/Core/Authentication/AuthenticationProviderManager.php @@ -25,8 +25,8 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class AuthenticationProviderManager implements AuthenticationManagerInterface { - protected $providers; - protected $eraseCredentials; + private $providers; + private $eraseCredentials; /** * Constructor. @@ -34,9 +34,13 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface * @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances * @param Boolean $eraseCredentials Whether to erase credentials after authentication or not */ - public function __construct(array $providers = array(), $eraseCredentials = true) + public function __construct(array $providers, $eraseCredentials = true) { - $this->setProviders($providers); + if (!$providers) { + throw new \InvalidArgumentException('You must at least add one authentication provider.'); + } + + $this->providers = $providers; $this->eraseCredentials = (Boolean) $eraseCredentials; } @@ -45,10 +49,6 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface */ public function authenticate(TokenInterface $token) { - if (!count($this->providers)) { - throw new \LogicException('You must add at least one provider.'); - } - $lastException = null; $result = null; @@ -84,37 +84,4 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface throw $lastException; } - - /** - * Returns the list of current providers. - * - * @return AuthenticationProviderInterface[] An array of AuthenticationProviderInterface instances - */ - public function all() - { - return $this->providers; - } - - /** - * Sets the providers instances. - * - * @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances - */ - public function setProviders(array $providers) - { - $this->providers = array(); - foreach ($providers as $provider) { - $this->add($provider); - } - } - - /** - * Adds a provider. - * - * @param AuthenticationProviderInterface $provider A AuthenticationProviderInterface instance - */ - public function add(AuthenticationProviderInterface $provider) - { - $this->providers[] = $provider; - } } diff --git a/Core/Authentication/AuthenticationTrustResolver.php b/Core/Authentication/AuthenticationTrustResolver.php index f2e00cc..8ca28fb 100644 --- a/Core/Authentication/AuthenticationTrustResolver.php +++ b/Core/Authentication/AuthenticationTrustResolver.php @@ -20,8 +20,8 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterface { - protected $anonymousClass; - protected $rememberMeClass; + private $anonymousClass; + private $rememberMeClass; /** * Constructor diff --git a/Core/Authentication/Provider/AnonymousAuthenticationProvider.php b/Core/Authentication/Provider/AnonymousAuthenticationProvider.php index ad1ad60..c48a27e 100644 --- a/Core/Authentication/Provider/AnonymousAuthenticationProvider.php +++ b/Core/Authentication/Provider/AnonymousAuthenticationProvider.php @@ -22,7 +22,7 @@ use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; */ class AnonymousAuthenticationProvider implements AuthenticationProviderInterface { - protected $key; + private $key; /** * Constructor. diff --git a/Core/Authentication/Provider/DaoAuthenticationProvider.php b/Core/Authentication/Provider/DaoAuthenticationProvider.php index ce0d220..21bec82 100644 --- a/Core/Authentication/Provider/DaoAuthenticationProvider.php +++ b/Core/Authentication/Provider/DaoAuthenticationProvider.php @@ -14,8 +14,8 @@ namespace Symfony\Component\Security\Core\Authentication\Provider; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Core\User\AccountCheckerInterface; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserCheckerInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; use Symfony\Component\Security\Core\Exception\BadCredentialsException; @@ -29,19 +29,19 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; */ class DaoAuthenticationProvider extends UserAuthenticationProvider { - protected $encoderFactory; - protected $userProvider; + private $encoderFactory; + private $userProvider; /** * Constructor. * * @param UserProviderInterface $userProvider A UserProviderInterface instance - * @param AccountCheckerInterface $accountChecker An AccountCheckerInterface instance + * @param UserCheckerInterface $userChecker An UserCheckerInterface instance * @param EncoderFactoryInterface $encoderFactory A EncoderFactoryInterface instance */ - public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker, $providerKey, EncoderFactoryInterface $encoderFactory, $hideUserNotFoundExceptions = true) + public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, $providerKey, EncoderFactoryInterface $encoderFactory, $hideUserNotFoundExceptions = true) { - parent::__construct($accountChecker, $providerKey, $hideUserNotFoundExceptions); + parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions); $this->encoderFactory = $encoderFactory; $this->userProvider = $userProvider; @@ -50,19 +50,19 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider /** * {@inheritdoc} */ - protected function checkAuthentication(AccountInterface $account, UsernamePasswordToken $token) + protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token) { - $user = $token->getUser(); - if ($user instanceof AccountInterface) { - if ($account->getPassword() !== $user->getPassword()) { + $currentUser = $token->getUser(); + if ($currentUser instanceof UserInterface) { + if ($currentUser->getPassword() !== $user->getPassword()) { throw new BadCredentialsException('The credentials were changed from another session.'); } } else { - if (!$presentedPassword = (string) $token->getCredentials()) { + if (!$presentedPassword = $token->getCredentials()) { throw new BadCredentialsException('Bad credentials'); } - if (!$this->encoderFactory->getEncoder($account)->isPasswordValid($account->getPassword(), $presentedPassword, $account->getSalt())) { + if (!$this->encoderFactory->getEncoder($user)->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) { throw new BadCredentialsException('Bad credentials'); } } @@ -74,15 +74,15 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider protected function retrieveUser($username, UsernamePasswordToken $token) { $user = $token->getUser(); - if ($user instanceof AccountInterface) { + if ($user instanceof UserInterface) { return $user; } try { $user = $this->userProvider->loadUserByUsername($username); - if (!$user instanceof AccountInterface) { - throw new AuthenticationServiceException('The user provider must return an AccountInterface object.'); + if (!$user instanceof UserInterface) { + throw new AuthenticationServiceException('The user provider must return an UserInterface object.'); } return $user; diff --git a/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php b/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php index cca52fc..bf2df86 100644 --- a/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php +++ b/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php @@ -11,9 +11,9 @@ namespace Symfony\Component\Security\Core\Authentication\Provider; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Core\User\AccountCheckerInterface; +use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -30,20 +30,20 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderInterface { - protected $userProvider; - protected $accountChecker; - protected $providerKey; + private $userProvider; + private $userChecker; + private $providerKey; /** * Constructor. * * @param UserProviderInterface $userProvider A UserProviderInterface instance - * @param AccountCheckerInterface $accountChecker An AccountCheckerInterface instance + * @param UserCheckerInterface $userChecker An UserCheckerInterface instance */ - public function __construct(UserProviderInterface $userProvider, AccountCheckerInterface $accountChecker, $providerKey) + public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, $providerKey) { $this->userProvider = $userProvider; - $this->accountChecker = $accountChecker; + $this->userChecker = $userChecker; $this->providerKey = $providerKey; } @@ -66,7 +66,7 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn */ $user = $this->userProvider->loadUserByUsername($user); - $this->accountChecker->checkPostAuth($user); + $this->userChecker->checkPostAuth($user); $authenticatedToken = new PreAuthenticatedToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles()); $authenticatedToken->setAttributes($token->getAttributes()); diff --git a/Core/Authentication/Provider/RememberMeAuthenticationProvider.php b/Core/Authentication/Provider/RememberMeAuthenticationProvider.php index 95ee588..940288b 100644 --- a/Core/Authentication/Provider/RememberMeAuthenticationProvider.php +++ b/Core/Authentication/Provider/RememberMeAuthenticationProvider.php @@ -1,21 +1,21 @@ <?php namespace Symfony\Component\Security\Core\Authentication\Provider; -use Symfony\Component\Security\Core\User\AccountCheckerInterface; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserCheckerInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Exception\BadCredentialsException; class RememberMeAuthenticationProvider implements AuthenticationProviderInterface { - protected $accountChecker; - protected $key; - protected $providerKey; + private $userChecker; + private $key; + private $providerKey; - public function __construct(AccountCheckerInterface $accountChecker, $key, $providerKey) + public function __construct(UserCheckerInterface $userChecker, $key, $providerKey) { - $this->accountChecker = $accountChecker; + $this->userChecker = $userChecker; $this->key = $key; $this->providerKey = $providerKey; } @@ -31,11 +31,12 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac } $user = $token->getUser(); - $this->accountChecker->checkPreAuth($user); - $this->accountChecker->checkPostAuth($user); - $token->setAuthenticated(true); + $this->userChecker->checkPostAuth($user); - return $token; + $authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->key); + $authenticatedToken->setAttributes($token->getAttributes()); + + return $authenticatedToken; } public function supports(TokenInterface $token) diff --git a/Core/Authentication/Provider/UserAuthenticationProvider.php b/Core/Authentication/Provider/UserAuthenticationProvider.php index 14a6fdf..7b6079d 100644 --- a/Core/Authentication/Provider/UserAuthenticationProvider.php +++ b/Core/Authentication/Provider/UserAuthenticationProvider.php @@ -11,8 +11,8 @@ namespace Symfony\Component\Security\Core\Authentication\Provider; -use Symfony\Component\Security\Core\User\AccountInterface; -use Symfony\Component\Security\Core\User\AccountCheckerInterface; +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\BadCredentialsException; @@ -27,23 +27,23 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ abstract class UserAuthenticationProvider implements AuthenticationProviderInterface { - protected $hideUserNotFoundExceptions; - protected $accountChecker; - protected $providerKey; + private $hideUserNotFoundExceptions; + private $userChecker; + private $providerKey; /** * Constructor. * - * @param AccountCheckerInterface $accountChecker An AccountCheckerInterface interface + * @param UserCheckerInterface $userChecker An UserCheckerInterface interface * @param Boolean $hideUserNotFoundExceptions Whether to hide user not found exception or not */ - public function __construct(AccountCheckerInterface $accountChecker, $providerKey, $hideUserNotFoundExceptions = true) + public function __construct(UserCheckerInterface $userChecker, $providerKey, $hideUserNotFoundExceptions = true) { if (empty($providerKey)) { throw new \InvalidArgumentException('$providerKey must not be empty.'); } - $this->accountChecker = $accountChecker; + $this->userChecker = $userChecker; $this->providerKey = $providerKey; $this->hideUserNotFoundExceptions = $hideUserNotFoundExceptions; } @@ -57,18 +57,21 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter return null; } - $username = null === $token->getUser() ? 'NONE_PROVIDED' : (string) $token; + $username = $token->getUsername(); + if (empty($username)) { + $username = 'NONE_PROVIDED'; + } try { $user = $this->retrieveUser($username, $token); - if (!$user instanceof AccountInterface) { - throw new AuthenticationServiceException('retrieveUser() must return an AccountInterface.'); + if (!$user instanceof UserInterface) { + throw new AuthenticationServiceException('retrieveUser() must return an UserInterface.'); } - $this->accountChecker->checkPreAuth($user); + $this->userChecker->checkPreAuth($user); $this->checkAuthentication($user, $token); - $this->accountChecker->checkPostAuth($user); + $this->userChecker->checkPostAuth($user); $authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles()); $authenticatedToken->setAttributes($token->getAttributes()); @@ -107,10 +110,10 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter * Does additional checks on the user and token (like validating the * credentials). * - * @param AccountInterface $account The retrieved AccountInterface instance + * @param UserInterface $user The retrieved UserInterface instance * @param UsernamePasswordToken $token The UsernamePasswordToken token to be authenticated * * @throws AuthenticationException if the credentials could not be validated */ - abstract protected function checkAuthentication(AccountInterface $account, UsernamePasswordToken $token); + abstract protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token); } diff --git a/Core/Authentication/RememberMe/InMemoryTokenProvider.php b/Core/Authentication/RememberMe/InMemoryTokenProvider.php index 80c10d1..c432b0e 100644 --- a/Core/Authentication/RememberMe/InMemoryTokenProvider.php +++ b/Core/Authentication/RememberMe/InMemoryTokenProvider.php @@ -11,7 +11,7 @@ use Symfony\Component\Security\Core\Exception\TokenNotFoundException; */ class InMemoryTokenProvider implements TokenProviderInterface { - protected $tokens = array(); + private $tokens = array(); public function loadTokenBySeries($series) { diff --git a/Core/Authentication/Token/Token.php b/Core/Authentication/Token/AbstractToken.php index ac0879f..ee6b207 100644 --- a/Core/Authentication/Token/Token.php +++ b/Core/Authentication/Token/AbstractToken.php @@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Core\Authentication\Token; use Symfony\Component\Security\Core\Role\RoleInterface; use Symfony\Component\Security\Core\Role\Role; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * Base class for Token instances. @@ -21,15 +21,12 @@ use Symfony\Component\Security\Core\User\AccountInterface; * @author Fabien Potencier <fabien@symfony.com> * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -abstract class Token implements TokenInterface +abstract class AbstractToken implements TokenInterface { - protected $roles; - protected $authenticated; - protected $user; - protected $credentials; - protected $immutable; - protected $providerKey; - protected $attributes; + private $user; + private $roles; + private $authenticated; + private $attributes; /** * Constructor. @@ -38,156 +35,97 @@ abstract class Token implements TokenInterface */ public function __construct(array $roles = array()) { - $this->setRoles($roles); $this->authenticated = false; - $this->immutable = false; $this->attributes = array(); - } - /** - * Adds a Role to the token. - * - * @param RoleInterface $role A RoleInterface instance - */ - public function addRole(RoleInterface $role) - { - if ($this->immutable) { - throw new \LogicException('This token is considered immutable.'); - } - - $this->roles[] = $role; - } - - /** - * {@inheritdoc} - */ - public function getRoles() - { - return $this->roles; - } - - /** - * {@inheritDoc} - */ - public function setRoles(array $roles) - { $this->roles = array(); - foreach ($roles as $role) { if (is_string($role)) { $role = new Role($role); + } else if (!$role instanceof RoleInterface) { + throw new \InvalidArgumentException(sprintf('$roles must be an array of strings, or RoleInterface instances, but got %s.', gettype($role))); } - $this->addRole($role); + $this->roles[] = $role; } } /** * {@inheritdoc} */ - public function __toString() - { - if ($this->user instanceof AccountInterface) { - return $this->user->getUsername(); - } - - return (string) $this->user; - } - - /** - * {@inheritdoc} - */ - public function isAuthenticated() + public function getRoles() { - return $this->authenticated; + return $this->roles; } /** * {@inheritdoc} */ - public function setAuthenticated($authenticated) + public function getUsername() { - if ($this->immutable) { - throw new \LogicException('This token is considered immutable.'); + if ($this->user instanceof UserInterface) { + return $this->user->getUsername(); } - $this->authenticated = (Boolean) $authenticated; - } - - /** - * {@inheritdoc} - */ - public function getCredentials() - { - return $this->credentials; + return (string) $this->user; } - /** - * {@inheritdoc} - */ public function getUser() { return $this->user; } - /** - * {@inheritDoc} - */ public function setUser($user) { - if ($this->immutable) { - throw new \LogicException('This token is considered immutable.'); + if (!($user instanceof UserInterface || (is_object($user) && method_exists($user, '__toString')) || is_string($user))) { + throw new \InvalidArgumentException('$user must be an instanceof of UserInterface, an object implementing a __toString method, or a primitive string.'); } - if (!is_string($user) && !is_object($user)) { - throw new \InvalidArgumentException('$user must be an object, or a primitive string.'); - } else if (is_object($user) && !$user instanceof AccountInterface && !method_exists($user, '__toString')) { - throw new \InvalidArgumentException('If $user is an object, it must implement __toString().'); - } - - $this->user = $user; - } - - /** - * {@inheritdoc} - */ - public function eraseCredentials() - { - if ($this->immutable) { - throw new \LogicException('This token is considered immutable.'); + if (null === $this->user) { + $changed = false; + } else if ($this->user instanceof UserInterface) { + if (!$user instanceof UserInterface) { + $changed = true; + } else { + $changed = !$this->user->equals($user); + } + } else if ($user instanceof UserInterface) { + $changed = true; + } else { + $changed = (string) $this->user !== (string) $user; } - if ($this->getCredentials() instanceof AccountInterface) { - $this->getCredentials()->eraseCredentials(); + if ($changed) { + $this->setAuthenticated(false); } - if ($this->getUser() instanceof AccountInterface) { - $this->getUser()->eraseCredentials(); - } + $this->user = $user; } /** * {@inheritdoc} */ - public function isImmutable() + public function isAuthenticated() { - return $this->immutable; + return $this->authenticated; } /** * {@inheritdoc} */ - public function setImmutable() + public function setAuthenticated($authenticated) { - $this->immutable = true; + $this->authenticated = (Boolean) $authenticated; } /** * {@inheritdoc} */ - public function getProviderKey() + public function eraseCredentials() { - return $this->providerKey; + if ($this->getUser() instanceof UserInterface) { + $this->getUser()->eraseCredentials(); + } } /** @@ -195,7 +133,7 @@ abstract class Token implements TokenInterface */ public function serialize() { - return serialize(array($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes)); + return serialize(array($this->user, $this->authenticated, $this->roles, $this->attributes)); } /** @@ -203,7 +141,7 @@ abstract class Token implements TokenInterface */ public function unserialize($serialized) { - list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes) = unserialize($serialized); + list($this->user, $this->authenticated, $this->roles, $this->attributes) = unserialize($serialized); } /** @@ -266,4 +204,20 @@ abstract class Token implements TokenInterface { $this->attributes[$name] = $value; } + + /** + * {@inheritDoc} + */ + public function __toString() + { + $class = get_class($this); + $class = substr($class, strrpos($class, '\\')+1); + + $roles = array(); + foreach ($this->roles as $role) { + $roles[] = $role->getRole(); + } + + return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUsername(), json_encode($this->authenticated), implode(', ', $roles)); + } } diff --git a/Core/Authentication/Token/AnonymousToken.php b/Core/Authentication/Token/AnonymousToken.php index a22460f..92d95de 100644 --- a/Core/Authentication/Token/AnonymousToken.php +++ b/Core/Authentication/Token/AnonymousToken.php @@ -16,10 +16,11 @@ namespace Symfony\Component\Security\Core\Authentication\Token; * * @author Fabien Potencier <fabien@symfony.com> */ -class AnonymousToken extends Token +use Symfony\Component\Security\Core\User\UserInterface; + +class AnonymousToken extends AbstractToken { - protected $user; - protected $key; + private $key; /** * Constructor. @@ -33,9 +34,8 @@ class AnonymousToken extends Token parent::__construct($roles); $this->key = $key; - $this->user = $user; - - parent::setAuthenticated(true); + $this->setUser($user); + $this->setAuthenticated(true); } /** @@ -55,4 +55,21 @@ class AnonymousToken extends Token { return $this->key; } + + /** + * {@inheritDoc} + */ + public function serialize() + { + return serialize(array($this->key, parent::serialize())); + } + + /** + * {@inheritDoc} + */ + public function unserialize($str) + { + list($this->key, $parentStr) = unserialize($str); + parent::unserialize($parentStr); + } } diff --git a/Core/Authentication/Token/PreAuthenticatedToken.php b/Core/Authentication/Token/PreAuthenticatedToken.php index 0db56bd..ff0572f 100644 --- a/Core/Authentication/Token/PreAuthenticatedToken.php +++ b/Core/Authentication/Token/PreAuthenticatedToken.php @@ -16,21 +16,39 @@ namespace Symfony\Component\Security\Core\Authentication\Token; * * @author Fabien Potencier <fabien@symfony.com> */ -class PreAuthenticatedToken extends Token +class PreAuthenticatedToken extends AbstractToken { + private $credentials; + private $providerKey; + /** * Constructor. */ - public function __construct($user, $credentials, $providerKey, array $roles = null) + public function __construct($user, $credentials, $providerKey, array $roles = array()) { - parent::__construct(null === $roles ? array() : $roles); - if (null !== $roles) { - $this->setAuthenticated(true); + parent::__construct($roles); + + if (empty($providerKey)) { + throw new \InvalidArgumentException('$providerKey must not be empty.'); } - $this->user = $user; + $this->setUser($user); $this->credentials = $credentials; $this->providerKey = $providerKey; + + if ($roles) { + $this->setAuthenticated(true); + } + } + + public function getProviderKey() + { + return $this->providerKey; + } + + public function getCredentials() + { + return $this->credentials; } /** @@ -42,4 +60,15 @@ class PreAuthenticatedToken extends Token $this->credentials = null; } + + public function serialize() + { + return serialize(array($this->credentials, $this->providerKey, parent::serialize())); + } + + public function unserialize($str) + { + list($this->credentials, $this->providerKey, $parentStr) = unserialize($str); + parent::unserialize($parentStr); + } } diff --git a/Core/Authentication/Token/RememberMeToken.php b/Core/Authentication/Token/RememberMeToken.php index ce1ed5d..7978427 100644 --- a/Core/Authentication/Token/RememberMeToken.php +++ b/Core/Authentication/Token/RememberMeToken.php @@ -11,69 +11,77 @@ namespace Symfony\Component\Security\Core\Authentication\Token; -use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** - * Base class for "Remember Me" tokens + * Authentication Token for "Remember-Me". * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -class RememberMeToken extends Token +class RememberMeToken extends AbstractToken { - protected $key; - - /** - * The persistent token which resulted in this authentication token. - * - * @var PersistentTokenInterface - */ - protected $persistentToken; + private $key; + private $providerKey; /** * Constructor. * - * @param string $username + * @param UserInterface $user + * @param string $providerKey * @param string $key */ - public function __construct(AccountInterface $user, $providerKey, $key) { + public function __construct(UserInterface $user, $providerKey, $key) { parent::__construct($user->getRoles()); if (empty($key)) { throw new \InvalidArgumentException('$key must not be empty.'); } + if (empty($providerKey)) { throw new \InvalidArgumentException('$providerKey must not be empty.'); } - $this->setUser($user); $this->providerKey = $providerKey; $this->key = $key; - $this->setAuthenticated(true); + + $this->setUser($user); + parent::setAuthenticated(true); } - public function getKey() + public function setAuthenticated($authenticated) { - return $this->key; + if ($authenticated) { + throw new \RuntimeException('You cannot set this token to authenticated after creation.'); + } + + parent::setAuthenticated(false); } - public function getPersistentToken() + public function getProviderKey() { - return $this->persistentToken; + return $this->providerKey; } - public function setPersistentToken(PersistentTokenInterface $persistentToken) + public function getKey() { - $this->persistentToken = $persistentToken; + return $this->key; } + public function getCredentials() + { + return ''; + } /** * {@inheritdoc} */ public function serialize() { - return serialize(array($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes, $this->key)); + return serialize(array( + $this->key, + $this->providerKey, + parent::serialize(), + )); } /** @@ -81,6 +89,7 @@ class RememberMeToken extends Token */ public function unserialize($serialized) { - list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes, $this->key) = unserialize($serialized); + list($this->key, $this->providerKey, $parentStr) = unserialize($serialized); + parent::unserialize($parentStr); } }
\ No newline at end of file diff --git a/Core/Authentication/Token/TokenInterface.php b/Core/Authentication/Token/TokenInterface.php index f3947dd..63e2243 100644 --- a/Core/Authentication/Token/TokenInterface.php +++ b/Core/Authentication/Token/TokenInterface.php @@ -11,19 +11,22 @@ namespace Symfony\Component\Security\Core\Authentication\Token; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * TokenInterface is the interface for the user authentication information. * * @author Fabien Potencier <fabien@symfony.com> + * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ interface TokenInterface extends \Serializable { /** - * Returns a string representation of the token. + * Returns a string representation ofthe Token. * - * @return string A string representation + * This is only to be used for debugging purposes. + * + * @return string */ function __toString(); @@ -35,14 +38,6 @@ interface TokenInterface extends \Serializable function getRoles(); /** - * Sets the user's roles - * - * @param array $roles - * @return void - */ - function setRoles(array $roles); - - /** * Returns the user credentials. * * @return mixed The user credentials @@ -58,14 +53,20 @@ interface TokenInterface extends \Serializable function getUser(); /** - * Sets the user. + * Sets a user. * - * @param mixed $user can either be an object which implements __toString(), or - * only a primitive string + * @param mixed $user */ function setUser($user); /** + * Returns the username. + * + * @return string + */ + function getUsername(); + + /** * Checks if the user is authenticated or not. * * @return Boolean true if the token has been authenticated, false otherwise @@ -80,22 +81,6 @@ interface TokenInterface extends \Serializable function setAuthenticated($isAuthenticated); /** - * Whether this token is considered immutable - * - * @return Boolean - */ - function isImmutable(); - - /** - * Marks this token as immutable. This change cannot be reversed. - * - * You'll need to create a new token if you want a mutable token again. - * - * @return void - */ - function setImmutable(); - - /** * Removes sensitive information from the token. */ function eraseCredentials(); diff --git a/Core/Authentication/Token/UsernamePasswordToken.php b/Core/Authentication/Token/UsernamePasswordToken.php index 58b2b5b..67311db 100644 --- a/Core/Authentication/Token/UsernamePasswordToken.php +++ b/Core/Authentication/Token/UsernamePasswordToken.php @@ -16,8 +16,11 @@ namespace Symfony\Component\Security\Core\Authentication\Token; * * @author Fabien Potencier <fabien@symfony.com> */ -class UsernamePasswordToken extends Token +class UsernamePasswordToken extends AbstractToken { + private $credentials; + private $providerKey; + /** * Constructor. * @@ -28,11 +31,15 @@ class UsernamePasswordToken extends Token { parent::__construct($roles); + if (empty($providerKey)) { + throw new \InvalidArgumentException('$providerKey must not be empty.'); + } + $this->setUser($user); $this->credentials = $credentials; $this->providerKey = $providerKey; - parent::setAuthenticated((Boolean) count($roles)); + parent::setAuthenticated(count($roles) > 0); } /** @@ -47,6 +54,16 @@ class UsernamePasswordToken extends Token parent::setAuthenticated(false); } + public function getCredentials() + { + return $this->credentials; + } + + public function getProviderKey() + { + return $this->providerKey; + } + /** * {@inheritdoc} */ @@ -56,4 +73,15 @@ class UsernamePasswordToken extends Token $this->credentials = null; } + + public function serialize() + { + return serialize(array($this->credentials, $this->providerKey, parent::serialize())); + } + + public function unserialize($str) + { + list($this->credentials, $this->providerKey, $parentStr) = unserialize($str); + parent::unserialize($parentStr); + } } diff --git a/Core/Authorization/AccessDecisionManager.php b/Core/Authorization/AccessDecisionManager.php index 7ae5378..c1b643e 100644 --- a/Core/Authorization/AccessDecisionManager.php +++ b/Core/Authorization/AccessDecisionManager.php @@ -22,10 +22,10 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class AccessDecisionManager implements AccessDecisionManagerInterface { - protected $voters; - protected $strategy; - protected $allowIfAllAbstainDecisions; - protected $allowIfEqualGrantedDeniedDecisions; + private $voters; + private $strategy; + private $allowIfAllAbstainDecisions; + private $allowIfEqualGrantedDeniedDecisions; /** * Constructor. @@ -34,8 +34,12 @@ class AccessDecisionManager implements AccessDecisionManagerInterface * @param string $strategy The vote strategy * @param Boolean $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not */ - public function __construct(array $voters = array(), $strategy = 'affirmative', $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true) + public function __construct(array $voters, $strategy = 'affirmative', $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true) { + if (!$voters) { + throw new \InvalidArgumentException('You must at least add one voter.'); + } + $this->voters = $voters; $this->strategy = 'decide'.ucfirst($strategy); $this->allowIfAllAbstainDecisions = (Boolean) $allowIfAllAbstainDecisions; @@ -51,43 +55,6 @@ class AccessDecisionManager implements AccessDecisionManagerInterface } /** - * Returns all voters. - * - * @return VoterInterface[] $voters An array of VoterInterface instances - */ - public function getVoters() - { - return $this->voters; - } - - /** - * Sets voters. - * - * @param VoterInterface[] $voters An array of VoterInterface instances - */ - public function setVoters(array $voters) - { - if (!count($voters)) { - throw new \LogicException('You must have at least one voter.'); - } - - $this->voters = array(); - foreach ($voters as $voter) { - $this->addVoter($voter); - } - } - - /** - * Adds a voter. - * - * @param VoterInterface $voter A VoterInterface instance - */ - public function addVoter(VoterInterface $voter) - { - $this->voters[] = $voter; - } - - /** * {@inheritdoc} */ public function supportsAttribute($attribute) @@ -121,7 +88,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface * If all voters abstained from voting, the decision will be based on the * allowIfAllAbstainDecisions property value (defaults to false). */ - protected function decideAffirmative(TokenInterface $token, array $attributes, $object = null) + private function decideAffirmative(TokenInterface $token, array $attributes, $object = null) { $deny = 0; foreach ($this->voters as $voter) { @@ -161,7 +128,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface * If all voters abstained from voting, the decision will be based on the * allowIfAllAbstainDecisions property value (defaults to false). */ - protected function decideConsensus(TokenInterface $token, array $attributes, $object = null) + private function decideConsensus(TokenInterface $token, array $attributes, $object = null) { $grant = 0; $deny = 0; @@ -208,7 +175,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface * If all voters abstained from voting, the decision will be based on the * allowIfAllAbstainDecisions property value (defaults to false). */ - protected function decideUnanimous(TokenInterface $token, array $attributes, $object = null) + private function decideUnanimous(TokenInterface $token, array $attributes, $object = null) { $grant = 0; foreach ($attributes as $attribute) { diff --git a/Core/Authorization/Voter/AuthenticatedVoter.php b/Core/Authorization/Voter/AuthenticatedVoter.php index 3b5ca97..d750e33 100644 --- a/Core/Authorization/Voter/AuthenticatedVoter.php +++ b/Core/Authorization/Voter/AuthenticatedVoter.php @@ -29,7 +29,7 @@ class AuthenticatedVoter implements VoterInterface const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED'; const IS_AUTHENTICATED_ANONYMOUSLY = 'IS_AUTHENTICATED_ANONYMOUSLY'; - protected $authenticationTrustResolver; + private $authenticationTrustResolver; /** * Constructor. diff --git a/Core/Authorization/Voter/RoleHierarchyVoter.php b/Core/Authorization/Voter/RoleHierarchyVoter.php index 5c1e11e..c8f9b7e 100644 --- a/Core/Authorization/Voter/RoleHierarchyVoter.php +++ b/Core/Authorization/Voter/RoleHierarchyVoter.php @@ -22,7 +22,7 @@ use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; */ class RoleHierarchyVoter extends RoleVoter { - protected $roleHierarchy; + private $roleHierarchy; public function __construct(RoleHierarchyInterface $roleHierarchy, $prefix = 'ROLE_') { diff --git a/Core/Authorization/Voter/RoleVoter.php b/Core/Authorization/Voter/RoleVoter.php index 3a1aa2d..722675d 100644 --- a/Core/Authorization/Voter/RoleVoter.php +++ b/Core/Authorization/Voter/RoleVoter.php @@ -20,7 +20,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class RoleVoter implements VoterInterface { - protected $prefix; + private $prefix; /** * Constructor. diff --git a/Core/Encoder/EncoderFactory.php b/Core/Encoder/EncoderFactory.php index 80a7a61..d6441d9 100644 --- a/Core/Encoder/EncoderFactory.php +++ b/Core/Encoder/EncoderFactory.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Security\Core\Encoder; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * A generic encoder factory implementation @@ -20,7 +20,7 @@ use Symfony\Component\Security\Core\User\AccountInterface; */ class EncoderFactory implements EncoderFactoryInterface { - protected $encoders; + private $encoders; public function __construct(array $encoders) { @@ -30,10 +30,10 @@ class EncoderFactory implements EncoderFactoryInterface /** * {@inheritDoc} */ - public function getEncoder(AccountInterface $account) + public function getEncoder(UserInterface $user) { foreach ($this->encoders as $class => $encoder) { - if (!$account instanceof $class) { + if (!$user instanceof $class) { continue; } @@ -44,7 +44,7 @@ class EncoderFactory implements EncoderFactoryInterface return $this->encoders[$class]; } - throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', get_class($account))); + throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', get_class($user))); } /** @@ -53,7 +53,7 @@ class EncoderFactory implements EncoderFactoryInterface * @param array $config * @return PasswordEncoderInterface */ - protected function createEncoder(array $config) + private function createEncoder(array $config) { if (!isset($config['class'])) { throw new \InvalidArgumentException(sprintf('"class" must be set in %s.', json_encode($config))); diff --git a/Core/Encoder/EncoderFactoryInterface.php b/Core/Encoder/EncoderFactoryInterface.php index a4b7d3b..62cc9aa 100644 --- a/Core/Encoder/EncoderFactoryInterface.php +++ b/Core/Encoder/EncoderFactoryInterface.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Security\Core\Encoder; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * EncoderFactoryInterface to support different encoders for different accounts. @@ -23,8 +23,8 @@ interface EncoderFactoryInterface /** * Returns the password encoder to use for the given account * - * @param AccountInterface $account + * @param UserInterface $user * @return PasswordEncoderInterface never null */ - function getEncoder(AccountInterface $account); + function getEncoder(UserInterface $user); }
\ No newline at end of file diff --git a/Core/Encoder/MessageDigestPasswordEncoder.php b/Core/Encoder/MessageDigestPasswordEncoder.php index b69cf6e..a5b2c81 100644 --- a/Core/Encoder/MessageDigestPasswordEncoder.php +++ b/Core/Encoder/MessageDigestPasswordEncoder.php @@ -18,8 +18,8 @@ namespace Symfony\Component\Security\Core\Encoder; */ class MessageDigestPasswordEncoder extends BasePasswordEncoder { - protected $algorithm; - protected $encodeHashAsBase64; + private $algorithm; + private $encodeHashAsBase64; /** * Constructor. diff --git a/Core/Encoder/PlaintextPasswordEncoder.php b/Core/Encoder/PlaintextPasswordEncoder.php index 48c19fb..21a9a97 100644 --- a/Core/Encoder/PlaintextPasswordEncoder.php +++ b/Core/Encoder/PlaintextPasswordEncoder.php @@ -18,7 +18,7 @@ namespace Symfony\Component\Security\Core\Encoder; */ class PlaintextPasswordEncoder extends BasePasswordEncoder { - protected $ignorePasswordCase; + private $ignorePasswordCase; public function __construct($ignorePasswordCase = false) { diff --git a/Core/Exception/AuthenticationException.php b/Core/Exception/AuthenticationException.php index a01d6b8..074dad0 100644 --- a/Core/Exception/AuthenticationException.php +++ b/Core/Exception/AuthenticationException.php @@ -18,7 +18,7 @@ namespace Symfony\Component\Security\Core\Exception; */ class AuthenticationException extends \RuntimeException implements \Serializable { - protected $extraInformation; + private $extraInformation; public function __construct($message, $extraInformation = null, $code = 0, \Exception $previous = null) { diff --git a/Core/Exception/UnsupportedAccountException.php b/Core/Exception/UnsupportedUserException.php index 9859c1d..5be9bc4 100644 --- a/Core/Exception/UnsupportedAccountException.php +++ b/Core/Exception/UnsupportedUserException.php @@ -13,10 +13,10 @@ namespace Symfony\Component\Security\Core\Exception; /** * This exception is thrown when an account is reloaded from a provider which - * doesn't support the passed implementation of AccountInterface. + * doesn't support the passed implementation of UserInterface. * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -class UnsupportedAccountException extends AuthenticationServiceException +class UnsupportedUserException extends AuthenticationServiceException { }
\ No newline at end of file diff --git a/Core/Role/Role.php b/Core/Role/Role.php index 4e22340..5b50981 100644 --- a/Core/Role/Role.php +++ b/Core/Role/Role.php @@ -19,7 +19,7 @@ namespace Symfony\Component\Security\Core\Role; */ class Role implements RoleInterface { - protected $role; + private $role; /** * Constructor. diff --git a/Core/Role/RoleHierarchy.php b/Core/Role/RoleHierarchy.php index 5217b53..a368a44 100644 --- a/Core/Role/RoleHierarchy.php +++ b/Core/Role/RoleHierarchy.php @@ -18,8 +18,8 @@ namespace Symfony\Component\Security\Core\Role; */ class RoleHierarchy implements RoleHierarchyInterface { - protected $hierarchy; - protected $map; + private $hierarchy; + private $map; /** * Constructor. @@ -56,7 +56,7 @@ class RoleHierarchy implements RoleHierarchyInterface return $reachableRoles; } - protected function buildRoleMap() + private function buildRoleMap() { $this->map = array(); foreach ($this->hierarchy as $main => $roles) { diff --git a/Core/Role/SwitchUserRole.php b/Core/Role/SwitchUserRole.php index 1305841..c679584 100644 --- a/Core/Role/SwitchUserRole.php +++ b/Core/Role/SwitchUserRole.php @@ -21,7 +21,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class SwitchUserRole extends Role { - protected $source; + private $source; /** * Constructor. diff --git a/Core/SecurityContext.php b/Core/SecurityContext.php index 68ee2e0..76ec4c1 100644 --- a/Core/SecurityContext.php +++ b/Core/SecurityContext.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Security\Core; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; @@ -28,10 +28,10 @@ use Symfony\Component\Security\Acl\Voter\FieldVote; */ class SecurityContext implements SecurityContextInterface { - protected $token; - protected $accessDecisionManager; - protected $authenticationManager; - protected $alwaysAuthenticate; + private $token; + private $accessDecisionManager; + private $authenticationManager; + private $alwaysAuthenticate; /** * Constructor. @@ -45,7 +45,7 @@ class SecurityContext implements SecurityContextInterface $this->alwaysAuthenticate = $alwaysAuthenticate; } - public final function vote($attributes, $object = null) + public final function isGranted($attributes, $object = null) { if (null === $this->token) { throw new AuthenticationCredentialsNotFoundException('The security context contains no authentication token.'); diff --git a/Core/SecurityContextInterface.php b/Core/SecurityContextInterface.php index fd205d6..a811557 100644 --- a/Core/SecurityContextInterface.php +++ b/Core/SecurityContextInterface.php @@ -16,6 +16,6 @@ interface SecurityContextInterface const LAST_USERNAME = '_security.last_username'; function getToken(); - function setToken(TokenInterface $account); - function vote($attributes, $object = null); + function setToken(TokenInterface $token); + function isGranted($attributes, $object = null); }
\ No newline at end of file diff --git a/Core/User/AdvancedAccountInterface.php b/Core/User/AdvancedUserInterface.php index 2c615b2..ba528a1 100644 --- a/Core/User/AdvancedAccountInterface.php +++ b/Core/User/AdvancedUserInterface.php @@ -12,11 +12,11 @@ namespace Symfony\Component\Security\Core\User; /** - * AdvancedAccountInterface adds status flags to a regular account. + * AdvancedUserInterface adds status flags to a regular account. * * @author Fabien Potencier <fabien@symfony.com> */ -interface AdvancedAccountInterface extends AccountInterface +interface AdvancedUserInterface extends UserInterface { /** * Checks whether the user's account has expired. diff --git a/Core/User/ChainUserProvider.php b/Core/User/ChainUserProvider.php index 296d099..6417f99 100644 --- a/Core/User/ChainUserProvider.php +++ b/Core/User/ChainUserProvider.php @@ -2,7 +2,7 @@ namespace Symfony\Component\Security\Core\User; -use Symfony\Component\Security\Core\Exception\UnsupportedAccountException; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; /** @@ -15,7 +15,7 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; */ class ChainUserProvider implements UserProviderInterface { - protected $providers; + private $providers; public function __construct(array $providers) { @@ -41,17 +41,17 @@ class ChainUserProvider implements UserProviderInterface /** * {@inheritDoc} */ - public function loadUserByAccount(AccountInterface $account) + public function loadUser(UserInterface $user) { foreach ($this->providers as $provider) { try { - return $provider->loadUserByAccount($account); - } catch (UnsupportedAccountException $unsupported) { + return $provider->loadUser($user); + } catch (UnsupportedUserException $unsupported) { // try next one } } - throw new UnsupportedAccountException(sprintf('The account "%s" is not supported.', get_class($account))); + throw new UnsupportedUserException(sprintf('The account "%s" is not supported.', get_class($user))); } /** diff --git a/Core/User/EntityUserProvider.php b/Core/User/EntityUserProvider.php index 58bcc45..61dd708 100644 --- a/Core/User/EntityUserProvider.php +++ b/Core/User/EntityUserProvider.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Security\Core\User; use Doctrine\ORM\EntityManager; -use Symfony\Component\Security\Core\Exception\UnsupportedAccountException; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; /** @@ -25,9 +25,9 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; */ class EntityUserProvider implements UserProviderInterface { - protected $class; - protected $repository; - protected $property; + private $class; + private $repository; + private $property; public function __construct(EntityManager $em, $class, $property = null) { @@ -66,13 +66,13 @@ class EntityUserProvider implements UserProviderInterface /** * {@inheritDoc} */ - public function loadUserByAccount(AccountInterface $account) + public function loadUser(UserInterface $user) { - if (!$account instanceof $this->class) { - throw new UnsupportedAccountException(sprintf('Instances of "%s" are not supported.', get_class($account))); + if (!$user instanceof $this->class) { + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); } - return $this->loadUserByUsername($account->getUsername()); + return $this->loadUserByUsername($user->getUsername()); } /** diff --git a/Core/User/InMemoryUserProvider.php b/Core/User/InMemoryUserProvider.php index 7d4d1cc..26b4080 100644 --- a/Core/User/InMemoryUserProvider.php +++ b/Core/User/InMemoryUserProvider.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Security\Core\User; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; -use Symfony\Component\Security\Core\Exception\UnsupportedAccountException; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; /** * InMemoryUserProvider is a simple non persistent user provider. @@ -24,7 +24,7 @@ use Symfony\Component\Security\Core\Exception\UnsupportedAccountException; */ class InMemoryUserProvider implements UserProviderInterface { - protected $users; + private $users; /** * Constructor. @@ -50,9 +50,9 @@ class InMemoryUserProvider implements UserProviderInterface /** * Adds a new User to the provider. * - * @param AccountInterface $user A AccountInterface instance + * @param UserInterface $user A UserInterface instance */ - public function createUser(AccountInterface $user) + public function createUser(UserInterface $user) { if (isset($this->users[strtolower($user->getUsername())])) { throw new \LogicException('Another user with the same username already exist.'); @@ -79,13 +79,13 @@ class InMemoryUserProvider implements UserProviderInterface /** * {@inheritDoc} */ - public function loadUserByAccount(AccountInterface $account) + public function loadUser(UserInterface $user) { - if (!$account instanceof User) { - throw new UnsupportedAccountException(sprintf('Instances of "%s" are not supported.', get_class($account))); + if (!$user instanceof User) { + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); } - return $this->loadUserByUsername((string) $account); + return $this->loadUserByUsername($user->getUsername()); } /** diff --git a/Core/User/User.php b/Core/User/User.php index 02a2c06..7dcdee3 100644 --- a/Core/User/User.php +++ b/Core/User/User.php @@ -18,16 +18,16 @@ namespace Symfony\Component\Security\Core\User; * * @author Fabien Potencier <fabien@symfony.com> */ -class User implements AdvancedAccountInterface +final class User implements AdvancedUserInterface { - protected $username; - protected $password; - protected $accountNonExpired; - protected $credentialsNonExpired; - protected $accountNonLocked; - protected $roles; - - public function __construct($username, $password, array $roles = array(), $enabled = true, $accountNonExpired = true, $credentialsNonExpired = true, $accountNonLocked = true) + private $username; + private $password; + private $userNonExpired; + private $credentialsNonExpired; + private $userNonLocked; + private $roles; + + public function __construct($username, $password, array $roles = array(), $enabled = true, $userNonExpired = true, $credentialsNonExpired = true, $userNonLocked = true) { if (empty($username)) { throw new \InvalidArgumentException('The username cannot be empty.'); @@ -36,23 +36,15 @@ class User implements AdvancedAccountInterface $this->username = $username; $this->password = $password; $this->enabled = $enabled; - $this->accountNonExpired = $accountNonExpired; + $this->accountNonExpired = $userNonExpired; $this->credentialsNonExpired = $credentialsNonExpired; - $this->accountNonLocked = $accountNonLocked; + $this->accountNonLocked = $userNonLocked; $this->roles = $roles; } /** * {@inheritdoc} */ - public function __toString() - { - return $this->username; - } - - /** - * {@inheritdoc} - */ public function getRoles() { return $this->roles; @@ -124,37 +116,37 @@ class User implements AdvancedAccountInterface /** * {@inheritDoc} */ - public function equals(AccountInterface $account) + public function equals(UserInterface $user) { - if (!$account instanceof User) { + if (!$user instanceof User) { return false; } - if ($this->password !== $account->getPassword()) { + if ($this->password !== $user->getPassword()) { return false; } - if ($this->getSalt() !== $account->getSalt()) { + if ($this->getSalt() !== $user->getSalt()) { return false; } - if ($this->username !== $account->getUsername()) { + if ($this->username !== $user->getUsername()) { return false; } - if ($this->accountNonExpired !== $account->isAccountNonExpired()) { + if ($this->accountNonExpired !== $user->isAccountNonExpired()) { return false; } - if ($this->accountNonLocked !== $account->isAccountNonLocked()) { + if ($this->accountNonLocked !== $user->isAccountNonLocked()) { return false; } - if ($this->credentialsNonExpired !== $account->isCredentialsNonExpired()) { + if ($this->credentialsNonExpired !== $user->isCredentialsNonExpired()) { return false; } - if ($this->enabled !== $account->isEnabled()) { + if ($this->enabled !== $user->isEnabled()) { return false; } diff --git a/Core/User/AccountChecker.php b/Core/User/UserChecker.php index cf66f93..93897a1 100644 --- a/Core/User/AccountChecker.php +++ b/Core/User/UserChecker.php @@ -17,45 +17,45 @@ use Symfony\Component\Security\Core\Exception\DisabledException; use Symfony\Component\Security\Core\Exception\AccountExpiredException; /** - * AccountChecker checks the user account flags. + * UserChecker checks the user account flags. * * @author Fabien Potencier <fabien@symfony.com> */ -class AccountChecker implements AccountCheckerInterface +class UserChecker implements UserCheckerInterface { /** * {@inheritdoc} */ - public function checkPreAuth(AccountInterface $account) + public function checkPreAuth(UserInterface $user) { - if (!$account instanceof AdvancedAccountInterface) { + if (!$user instanceof AdvancedUserInterface) { return; } - if (!$account->isCredentialsNonExpired()) { - throw new CredentialsExpiredException('User credentials have expired.', $account); + if (!$user->isCredentialsNonExpired()) { + throw new CredentialsExpiredException('User credentials have expired.', $user); } } /** * {@inheritdoc} */ - public function checkPostAuth(AccountInterface $account) + public function checkPostAuth(UserInterface $user) { - if (!$account instanceof AdvancedAccountInterface) { + if (!$user instanceof AdvancedUserInterface) { return; } - if (!$account->isAccountNonLocked()) { - throw new LockedException('User account is locked.', $account); + if (!$user->isAccountNonLocked()) { + throw new LockedException('User account is locked.', $user); } - if (!$account->isEnabled()) { - throw new DisabledException('User account is disabled.', $account); + if (!$user->isEnabled()) { + throw new DisabledException('User account is disabled.', $user); } - if (!$account->isAccountNonExpired()) { - throw new AccountExpiredException('User account has expired.', $account); + if (!$user->isAccountNonExpired()) { + throw new AccountExpiredException('User account has expired.', $user); } } } diff --git a/Core/User/AccountCheckerInterface.php b/Core/User/UserCheckerInterface.php index 1e9abaa..25de94a 100644 --- a/Core/User/AccountCheckerInterface.php +++ b/Core/User/UserCheckerInterface.php @@ -12,25 +12,25 @@ namespace Symfony\Component\Security\Core\User; /** - * AccountCheckerInterface checks user account when authentication occurs. + * UserCheckerInterface checks user account when authentication occurs. * * This should not be used to make authentication decisions. * * @author Fabien Potencier <fabien@symfony.com> */ -interface AccountCheckerInterface +interface UserCheckerInterface { /** * Checks the user account before authentication. * - * @param AccountInterface $account An AccountInterface instance + * @param UserInterface $user An UserInterface instance */ - function checkPreAuth(AccountInterface $account); + function checkPreAuth(UserInterface $user); /** * Checks the user account after authentication. * - * @param AccountInterface $account An AccountInterface instance + * @param UserInterface $user An UserInterface instance */ - function checkPostAuth(AccountInterface $account); + function checkPostAuth(UserInterface $user); } diff --git a/Core/User/AccountInterface.php b/Core/User/UserInterface.php index 46ea6ae..9091bfc 100644 --- a/Core/User/AccountInterface.php +++ b/Core/User/UserInterface.php @@ -12,11 +12,11 @@ namespace Symfony\Component\Security\Core\User; /** - * AccountInterface is the interface that user classes must implement. + * UserInterface is the interface that user classes must implement. * * @author Fabien Potencier <fabien@symfony.com> */ -interface AccountInterface +interface UserInterface { /** * Returns the roles granted to the user. @@ -60,8 +60,8 @@ interface AccountInterface * However, you do not need to compare every attribute, but only those that * are relevant for assessing whether re-authentication is required. * - * @param AccountInterface $account + * @param UserInterface $user * @return Boolean */ - function equals(AccountInterface $account); + function equals(UserInterface $user); } diff --git a/Core/User/UserProviderInterface.php b/Core/User/UserProviderInterface.php index 6c5666f..79be191 100644 --- a/Core/User/UserProviderInterface.php +++ b/Core/User/UserProviderInterface.php @@ -28,7 +28,7 @@ interface UserProviderInterface * @throws UsernameNotFoundException if the user is not found * @param string $username The username * - * @return AccountInterface + * @return UserInterface */ function loadUserByUsername($username); @@ -39,12 +39,12 @@ interface UserProviderInterface * from the database, or if it simply merges the passed User into the * identity map of an entity manager. * - * @throws UnsupportedAccountException if the account is not supported - * @param AccountInterface $account + * @throws UnsupportedUserException if the account is not supported + * @param UserInterface $user * - * @return AccountInterface + * @return UserInterface */ - function loadUserByAccount(AccountInterface $account); + function loadUser(UserInterface $user); /** * Whether this provider supports the given user class diff --git a/Http/AccessMap.php b/Http/AccessMap.php index ef7a4f0..6d12b42 100644 --- a/Http/AccessMap.php +++ b/Http/AccessMap.php @@ -22,7 +22,7 @@ use Symfony\Component\HttpFoundation\Request; */ class AccessMap { - protected $map = array(); + private $map = array(); /** * Constructor. diff --git a/Http/EntryPoint/BasicAuthenticationEntryPoint.php b/Http/EntryPoint/BasicAuthenticationEntryPoint.php index 968986c..984fbec 100644 --- a/Http/EntryPoint/BasicAuthenticationEntryPoint.php +++ b/Http/EntryPoint/BasicAuthenticationEntryPoint.php @@ -24,7 +24,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; */ class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface { - protected $realmName; + private $realmName; public function __construct($realmName) { diff --git a/Http/EntryPoint/DigestAuthenticationEntryPoint.php b/Http/EntryPoint/DigestAuthenticationEntryPoint.php index 06799bc..578a3e8 100644 --- a/Http/EntryPoint/DigestAuthenticationEntryPoint.php +++ b/Http/EntryPoint/DigestAuthenticationEntryPoint.php @@ -26,10 +26,10 @@ use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; */ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterface { - protected $key; - protected $realmName; - protected $nonceValiditySeconds; - protected $logger; + private $key; + private $realmName; + private $nonceValiditySeconds; + private $logger; public function __construct($realmName, $key, $nonceValiditySeconds = 300, LoggerInterface $logger = null) { @@ -62,14 +62,4 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac return $response; } - - public function getKey() - { - return $this->key; - } - - public function getRealmName() - { - return $this->realmName; - } } diff --git a/Http/EntryPoint/FormAuthenticationEntryPoint.php b/Http/EntryPoint/FormAuthenticationEntryPoint.php index ddd9bb7..f45f9ea 100644 --- a/Http/EntryPoint/FormAuthenticationEntryPoint.php +++ b/Http/EntryPoint/FormAuthenticationEntryPoint.php @@ -26,8 +26,8 @@ use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; */ class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface { - protected $loginPath; - protected $useForward; + private $loginPath; + private $useForward; /** * Constructor diff --git a/Http/EntryPoint/RetryAuthenticationEntryPoint.php b/Http/EntryPoint/RetryAuthenticationEntryPoint.php index c624c54..1fb6cc1 100644 --- a/Http/EntryPoint/RetryAuthenticationEntryPoint.php +++ b/Http/EntryPoint/RetryAuthenticationEntryPoint.php @@ -27,8 +27,8 @@ use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; */ class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface { - protected $httpPort; - protected $httpsPort; + private $httpPort; + private $httpsPort; public function __construct($httpPort = 80, $httpsPort = 443) { diff --git a/Http/Event/SwitchUserEventArgs.php b/Http/Event/SwitchUserEventArgs.php index be38036..c88a500 100644 --- a/Http/Event/SwitchUserEventArgs.php +++ b/Http/Event/SwitchUserEventArgs.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Security\Http\Event; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Doctrine\Common\EventArgs; class SwitchUserEventArgs extends EventArgs @@ -21,7 +21,7 @@ class SwitchUserEventArgs extends EventArgs private $targetUser; - public function __construct(Request $request, AccountInterface $targetUser) + public function __construct(Request $request, UserInterface $targetUser) { $this->request = $request; $this->targetUser = $targetUser; diff --git a/Http/Firewall.php b/Http/Firewall.php index 8fe2bcb..bff88b9 100644 --- a/Http/Firewall.php +++ b/Http/Firewall.php @@ -29,9 +29,9 @@ use Doctrine\Common\EventManager; */ class Firewall { - protected $map; - protected $evm; - protected $currentListeners; + private $map; + private $evm; + private $currentListeners; /** * Constructor. @@ -56,38 +56,19 @@ class Firewall return; } - $request = $eventArgs->getRequest(); - - // disconnect all listeners from onCoreSecurity to avoid the overhead - // of most listeners having to do this manually - $this->evm->removeEventListeners(Events::onCoreSecurity); - - // ensure that listeners disconnect from wherever they have connected to - foreach ($this->currentListeners as $listener) { - $listener->unregister($this->evm); - } - // register listeners for this firewall - list($listeners, $exception) = $this->map->getListeners($request); + list($listeners, $exception) = $this->map->getListeners($eventArgs->getRequest()); if (null !== $exception) { $exception->register($this->evm); } - foreach ($listeners as $listener) { - $listener->register($this->evm); - } - - // save current listener instances - $this->currentListeners = $listeners; - if (null !== $exception) { - $this->currentListeners[] = $exception; - } // initiate the listener chain - $securityEventArgs = new GetResponseEventArgs($eventArgs->getKernel(), $request, $eventArgs->getRequestType()); - $this->evm->dispatchEvent($securityEventArgs); + foreach ($listeners as $listener) { + $response = $listener->handle($eventArgs); - if ($securityEventArgs->hasResponse()) { - $eventArgs->setResponse($securityEventArgs->getResponse()); + if ($eventArgs->hasResponse()) { + break; + } } } } diff --git a/Http/Firewall/AbstractAuthenticationListener.php b/Http/Firewall/AbstractAuthenticationListener.php index 9af2a1c..f00d5e8 100644 --- a/Http/Firewall/AbstractAuthenticationListener.php +++ b/Http/Firewall/AbstractAuthenticationListener.php @@ -35,8 +35,8 @@ use Doctrine\Common\EventManager; * Subclasses likely have to implement the following: * - an TokenInterface to hold authentication related data * - an AuthenticationProvider to perform the actual authentication of the - * token, retrieve the AccountInterface implementation from a database, and - * perform the specific account checks using the AccountChecker + * token, retrieve the UserInterface implementation from a database, and + * perform the specific account checks using the UserChecker * * By default, this listener only is active for a specific path, e.g. * /login_check. If you want to change this behavior, you can overwrite the @@ -47,16 +47,16 @@ use Doctrine\Common\EventManager; */ abstract class AbstractAuthenticationListener implements ListenerInterface { - protected $securityContext; - protected $authenticationManager; - protected $sessionStrategy; - protected $providerKey; - protected $evm; protected $options; - protected $successHandler; - protected $failureHandler; protected $logger; - protected $rememberMeServices; + protected $authenticationManager; + protected $providerKey; + private $securityContext; + private $sessionStrategy; + private $evm; + private $successHandler; + private $failureHandler; + private $rememberMeServices; /** * Constructor. @@ -66,7 +66,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface * @param array $options An array of options for the processing of a successful, or failed authentication attempt * @param LoggerInterface $logger A LoggerInterface instance */ - public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null) + public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, EventManager $evm = null) { if (empty($providerKey)) { throw new \InvalidArgumentException('$providerKey must not be empty.'); @@ -89,6 +89,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface 'failure_forward' => false, ), $options); $this->logger = $logger; + $this->evm = $evm; } /** @@ -102,25 +103,6 @@ abstract class AbstractAuthenticationListener implements ListenerInterface } /** - * Subscribe to the onCoreSecurity event - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(KernelEvents::onCoreSecurity, $this); - - $this->evm = $evm; - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles form based authentication. * * @param Event $event An Event instance @@ -170,7 +152,18 @@ abstract class AbstractAuthenticationListener implements ListenerInterface return $this->options['check_path'] === $request->getPathInfo(); } - protected function onFailure(GetResponseEventArgs $eventArgs, Request $request, AuthenticationException $failed) + /** + * Performs authentication. + * + * @param Request $request A Request instance + * + * @return TokenInterface The authenticated token, or null if full authentication is not possible + * + * @throws AuthenticationException if the authentication fails + */ + abstract protected function attemptAuthentication(Request $request); + + private function onFailure(GetResponseEventArgs $eventArgs, Request $request, AuthenticationException $failed) { if (null !== $this->logger) { $this->logger->debug(sprintf('Authentication request failed: %s', $failed->getMessage())); @@ -206,7 +199,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface return new RedirectResponse(0 !== strpos($this->options['failure_path'], 'http') ? $request->getUriForPath($this->options['failure_path']) : $this->options['failure_path'], 302); } - protected function onSuccess(GetResponseEventArgs $eventArgs, Request $request, TokenInterface $token) + private function onSuccess(GetResponseEventArgs $eventArgs, Request $request, TokenInterface $token) { if (null !== $this->logger) { $this->logger->debug('User has been authenticated successfully'); @@ -244,7 +237,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface * * @return string */ - protected function determineTargetUrl(Request $request) + private function determineTargetUrl(Request $request) { if ($this->options['always_use_default_target_path']) { return $this->options['default_target_path']; @@ -267,15 +260,4 @@ abstract class AbstractAuthenticationListener implements ListenerInterface return $this->options['default_target_path']; } - - /** - * Performs authentication. - * - * @param Request $request A Request instance - * - * @return TokenInterface The authenticated token, or null if full authentication is not possible - * - * @throws AuthenticationException if the authentication fails - */ - abstract protected function attemptAuthentication(Request $request); } diff --git a/Http/Firewall/AbstractPreAuthenticatedListener.php b/Http/Firewall/AbstractPreAuthenticatedListener.php index 1ed7d86..0177ab7 100644 --- a/Http/Firewall/AbstractPreAuthenticatedListener.php +++ b/Http/Firewall/AbstractPreAuthenticatedListener.php @@ -32,43 +32,25 @@ use Doctrine\Common\EventManager; */ abstract class AbstractPreAuthenticatedListener implements ListenerInterface { - protected $securityContext; - protected $authenticationManager; - protected $providerKey; protected $logger; - protected $evm; + private $securityContext; + private $authenticationManager; + private $providerKey; + private $evm; - public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, LoggerInterface $logger = null) + public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, LoggerInterface $logger = null, EventManager $evm = null) { $this->securityContext = $securityContext; $this->authenticationManager = $authenticationManager; $this->providerKey = $providerKey; $this->logger = $logger; - } - - /** - * - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(KernelEvents::onCoreSecurity, $this); - $this->evm = $evm; } /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles X509 authentication. * - * @param EventInterface $event An EventInterface instance + * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance */ public function onCoreSecurity(GetResponseEventArgs $eventArgs) { @@ -81,11 +63,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface list($user, $credentials) = $this->getPreAuthenticatedData($request); if (null !== $token = $this->securityContext->getToken()) { - if ($token->isImmutable()) { - return; - } - - if ($token instanceof PreAuthenticatedToken && $token->isAuthenticated() && (string) $token === $user) { + if ($token instanceof PreAuthenticatedToken && $token->isAuthenticated() && $token->getUsername() === $user) { return; } } diff --git a/Http/Firewall/AccessListener.php b/Http/Firewall/AccessListener.php index 7a0c926..acbb255 100644 --- a/Http/Firewall/AccessListener.php +++ b/Http/Firewall/AccessListener.php @@ -20,7 +20,6 @@ use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; use Symfony\Component\HttpKernel\Events; use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; use Symfony\Component\Security\Core\Exception\AccessDeniedException; -use Doctrine\Common\EventManager; /** * AccessListener enforces access control rules. @@ -29,11 +28,11 @@ use Doctrine\Common\EventManager; */ class AccessListener implements ListenerInterface { - protected $context; - protected $accessDecisionManager; - protected $map; - protected $authManager; - protected $logger; + private $context; + private $accessDecisionManager; + private $map; + private $authManager; + private $logger; public function __construct(SecurityContext $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMap $map, AuthenticationManagerInterface $authManager, LoggerInterface $logger = null) { @@ -45,23 +44,6 @@ class AccessListener implements ListenerInterface } /** - * Registers a onCoreSecurity listener to enforce authorization rules. - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles access authorization. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance diff --git a/Http/Firewall/AnonymousAuthenticationListener.php b/Http/Firewall/AnonymousAuthenticationListener.php index 9d23c58..bbdef5d 100644 --- a/Http/Firewall/AnonymousAuthenticationListener.php +++ b/Http/Firewall/AnonymousAuthenticationListener.php @@ -16,7 +16,6 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; use Symfony\Component\HttpKernel\Events; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Doctrine\Common\EventManager; /** * AnonymousAuthenticationListener automatically addds a Token if none is @@ -26,9 +25,9 @@ use Doctrine\Common\EventManager; */ class AnonymousAuthenticationListener implements ListenerInterface { - protected $context; - protected $key; - protected $logger; + private $context; + private $key; + private $logger; public function __construct(SecurityContextInterface $context, $key, LoggerInterface $logger = null) { @@ -38,24 +37,6 @@ class AnonymousAuthenticationListener implements ListenerInterface } /** - * Registers a onCoreSecurity listener to load the SecurityContext from the - * session. - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles anonymous authentication. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance diff --git a/Http/Firewall/BasicAuthenticationListener.php b/Http/Firewall/BasicAuthenticationListener.php index 7a4a17a..87d10b8 100644 --- a/Http/Firewall/BasicAuthenticationListener.php +++ b/Http/Firewall/BasicAuthenticationListener.php @@ -19,7 +19,6 @@ use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; use Symfony\Component\HttpKernel\Events; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Doctrine\Common\EventManager; /** * BasicAuthenticationListener implements Basic HTTP authentication. @@ -28,12 +27,12 @@ use Doctrine\Common\EventManager; */ class BasicAuthenticationListener implements ListenerInterface { - protected $securityContext; - protected $authenticationManager; - protected $providerKey; - protected $authenticationEntryPoint; - protected $logger; - protected $ignoreFailure; + private $securityContext; + private $authenticationManager; + private $providerKey; + private $authenticationEntryPoint; + private $logger; + private $ignoreFailure; public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null) { @@ -50,23 +49,6 @@ class BasicAuthenticationListener implements ListenerInterface } /** - * - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles basic authentication. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance @@ -80,11 +62,7 @@ class BasicAuthenticationListener implements ListenerInterface } if (null !== $token = $this->securityContext->getToken()) { - if ($token->isImmutable()) { - return; - } - - if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && (string) $token === $username) { + if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) { return; } } diff --git a/Http/Firewall/ChannelListener.php b/Http/Firewall/ChannelListener.php index b9416dd..e2b3423 100644 --- a/Http/Firewall/ChannelListener.php +++ b/Http/Firewall/ChannelListener.php @@ -16,7 +16,6 @@ use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; use Symfony\Component\HttpKernel\Events; -use Doctrine\Common\EventManager; /** * ChannelListener switches the HTTP protocol based on the access control @@ -26,9 +25,9 @@ use Doctrine\Common\EventManager; */ class ChannelListener implements ListenerInterface { - protected $map; - protected $authenticationEntryPoint; - protected $logger; + private $map; + private $authenticationEntryPoint; + private $logger; public function __construct(AccessMap $map, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null) { @@ -38,23 +37,6 @@ class ChannelListener implements ListenerInterface } /** - * - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles channel management. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance diff --git a/Http/Firewall/ContextListener.php b/Http/Firewall/ContextListener.php index f19d2bc..72dab1e 100644 --- a/Http/Firewall/ContextListener.php +++ b/Http/Firewall/ContextListener.php @@ -16,12 +16,13 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; use Symfony\Component\HttpKernel\Event\FilterResponseEventArgs; +use Symfony\Component\HttpKernel\Events; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; -use Symfony\Component\Security\Core\Exception\UnsupportedAccountException; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\SecurityContext; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Doctrine\Common\EventManager; /** @@ -32,12 +33,12 @@ use Doctrine\Common\EventManager; */ class ContextListener implements ListenerInterface { - protected $context; - protected $contextKey; - protected $logger; - protected $userProviders; + private $context; + private $contextKey; + private $logger; + private $userProviders; - public function __construct(SecurityContext $context, array $userProviders, $contextKey, LoggerInterface $logger = null) + public function __construct(SecurityContext $context, array $userProviders, $contextKey, LoggerInterface $logger = null, EventManager $evm = null) { if (empty($contextKey)) { throw new \InvalidArgumentException('$contextKey must not be empty.'); @@ -46,29 +47,10 @@ class ContextListener implements ListenerInterface $this->context = $context; $this->userProviders = $userProviders; $this->contextKey = $contextKey; - $this->logger = $logger; - } - - /** - * Registers a onCoreSecurity listener to load the SecurityContext from the - * session. - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener( - array(Events::onCoreSecurity, Events::filterCoreResponse), - $this - ); - } - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - $evm->removeEventListener(Events::filterCoreResponse, $this); + if (null !== $evm) { + $evm->connect(Events::onCoreResponse, $this); + } } /** @@ -91,7 +73,7 @@ class ContextListener implements ListenerInterface $token = unserialize($token); - if (null !== $token && false === $token->isImmutable()) { + if (null !== $token) { $token = $this->refreshUser($token); } @@ -102,7 +84,7 @@ class ContextListener implements ListenerInterface /** * Writes the SecurityContext to the session. * - * @param EventInterface $event An EventInterface instance + * @param FilterResponseEventArgs $eventArgs A FilterResponseEventArgs instance */ public function filterCoreResponse(FilterResponseEventArgs $eventArgs) { @@ -132,10 +114,10 @@ class ContextListener implements ListenerInterface * * @return TokenInterface|null */ - protected function refreshUser(TokenInterface $token) + private function refreshUser(TokenInterface $token) { $user = $token->getUser(); - if (!$user instanceof AccountInterface) { + if (!$user instanceof UserInterface) { return $token; } @@ -145,25 +127,18 @@ class ContextListener implements ListenerInterface foreach ($this->userProviders as $provider) { try { - $cUser = $provider->loadUserByAccount($user); - - $token->setRoles($cUser->getRoles()); - $token->setUser($cUser); - - if (false === $cUser->equals($user)) { - $token->setAuthenticated(false); - } + $token->setUser($provider->loadUser($user)); if (null !== $this->logger) { - $this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $user)); + $this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $user->getUsername())); } return $token; - } catch (UnsupportedAccountException $unsupported) { + } catch (UnsupportedUserException $unsupported) { // let's try the next user provider } catch (UsernameNotFoundException $notFound) { if (null !== $this->logger) { - $this->logger->debug(sprintf('Username "%s" could not be found.', $user)); + $this->logger->debug(sprintf('Username "%s" could not be found.', $user->getUsername())); } return null; diff --git a/Http/Firewall/DigestAuthenticationListener.php b/Http/Firewall/DigestAuthenticationListener.php index 6426fa1..70b32be 100644 --- a/Http/Firewall/DigestAuthenticationListener.php +++ b/Http/Firewall/DigestAuthenticationListener.php @@ -24,7 +24,6 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\Exception\NonceExpiredException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Doctrine\Common\EventManager; /** * DigestAuthenticationListener implements Digest HTTP authentication. @@ -33,11 +32,11 @@ use Doctrine\Common\EventManager; */ class DigestAuthenticationListener implements ListenerInterface { - protected $securityContext; - protected $provider; - protected $providerKey; - protected $authenticationEntryPoint; - protected $logger; + private $securityContext; + private $provider; + private $providerKey; + private $authenticationEntryPoint; + private $logger; public function __construct(SecurityContextInterface $securityContext, UserProviderInterface $provider, $providerKey, DigestAuthenticationEntryPoint $authenticationEntryPoint, LoggerInterface $logger = null) { @@ -53,23 +52,6 @@ class DigestAuthenticationListener implements ListenerInterface } /** - * - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles digest authentication. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance @@ -85,11 +67,7 @@ class DigestAuthenticationListener implements ListenerInterface $digestAuth = new DigestData($header); if (null !== $token = $this->securityContext->getToken()) { - if ($token->isImmutable()) { - return; - } - - if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && (string) $token === $digestAuth->getUsername()) { + if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $digestAuth->getUsername()) { return; } } @@ -101,7 +79,7 @@ class DigestAuthenticationListener implements ListenerInterface try { $digestAuth->validateAndDecode($this->authenticationEntryPoint->getKey(), $this->authenticationEntryPoint->getRealmName()); } catch (BadCredentialsException $e) { - $this->fail($event, $request, $e); + $this->fail($eventArgs, $request, $e); return; } @@ -115,7 +93,7 @@ class DigestAuthenticationListener implements ListenerInterface $serverDigestMd5 = $digestAuth->calculateServerDigest($user->getPassword(), $request->getMethod()); } catch (UsernameNotFoundException $notFound) { - $this->fail($event, $request, new BadCredentialsException(sprintf('Username %s not found.', $digestAuth->getUsername()))); + $this->fail($eventArgs, $request, new BadCredentialsException(sprintf('Username %s not found.', $digestAuth->getUsername()))); return; } @@ -125,13 +103,13 @@ class DigestAuthenticationListener implements ListenerInterface $this->logger->debug(sprintf("Expected response: '%s' but received: '%s'; is AuthenticationDao returning clear text passwords?", $serverDigestMd5, $digestAuth->getResponse())); } - $this->fail($event, $request, new BadCredentialsException('Incorrect response')); + $this->fail($eventArgs, $request, new BadCredentialsException('Incorrect response')); return; } if ($digestAuth->isNonceExpired()) { - $this->fail($event, $request, new NonceExpiredException('Nonce has expired/timed out.')); + $this->fail($eventArgs, $request, new NonceExpiredException('Nonce has expired/timed out.')); return; } @@ -143,7 +121,7 @@ class DigestAuthenticationListener implements ListenerInterface $this->securityContext->setToken(new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey)); } - protected function fail(EventInterface $event, Request $request, AuthenticationException $authException) + private function fail(GetResponseEventArgs $eventArgs, Request $request, AuthenticationException $authException) { $this->securityContext->setToken(null); @@ -151,15 +129,15 @@ class DigestAuthenticationListener implements ListenerInterface $this->logger->debug($authException); } - $this->authenticationEntryPoint->start($event, $request, $authException); + $this->authenticationEntryPoint->start($eventArgs, $request, $authException); } } class DigestData { - protected $elements; - protected $header; - protected $nonceExpiryTime; + private $elements; + private $header; + private $nonceExpiryTime; public function __construct($header) { diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php index 8885ea7..e88b84f 100644 --- a/Http/Firewall/ExceptionListener.php +++ b/Http/Firewall/ExceptionListener.php @@ -32,14 +32,14 @@ use Doctrine\Common\EventManager; * * @author Fabien Potencier <fabien@symfony.com> */ -class ExceptionListener implements ListenerInterface +class ExceptionListener { - protected $context; - protected $accessDeniedHandler; - protected $authenticationEntryPoint; - protected $authenticationTrustResolver; - protected $errorPage; - protected $logger; + private $context; + private $accessDeniedHandler; + private $authenticationEntryPoint; + private $authenticationTrustResolver; + private $errorPage; + private $logger; public function __construct(SecurityContextInterface $context, AuthenticationTrustResolverInterface $trustResolver, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null, LoggerInterface $logger = null) { @@ -62,14 +62,6 @@ class ExceptionListener implements ListenerInterface } /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - $evm->disconnect(Events::onCoreException, $this); - } - - /** * Handles security related exceptions. * * @param ExceptionEventArgs $event An ExceptionEventArgs instance @@ -145,7 +137,7 @@ class ExceptionListener implements ListenerInterface $eventArgs->setResponse($response); } - protected function startAuthentication(ExceptionEventArgs $eventArgs, Request $request, AuthenticationException $authException) + private function startAuthentication(ExceptionEventArgs $eventArgs, Request $request, AuthenticationException $authException) { $this->context->setToken(null); @@ -157,7 +149,7 @@ class ExceptionListener implements ListenerInterface $this->logger->debug('Calling Authentication entry point'); } - // session isn't required when using http basic authentification mecanism for example + // session isn't required when using http basic authentification mechanism for example if ($request->hasSession()) { $request->getSession()->set('_security.target_path', $request->getUri()); } diff --git a/Http/Firewall/ListenerInterface.php b/Http/Firewall/ListenerInterface.php index 5d7afbd..bfc7478 100644 --- a/Http/Firewall/ListenerInterface.php +++ b/Http/Firewall/ListenerInterface.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Security\Http\Firewall; +use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; use Doctrine\Common\EventManager; /** @@ -21,22 +22,9 @@ use Doctrine\Common\EventManager; interface ListenerInterface { /** - * The implementation must connect this listener to all necessary events. + * This interface must be implemented by firewall listeners. * - * Typical events are: "onCoreSecurity", and "filterCoreResponse" - * - * @param EventManager $evm - */ - function register(EventManager $evm); - - /** - * The implementation must remove this listener from any events that it had - * connected to in register(). - * - * It may remove this listener from "onCoreSecurity", but this is ensured by - * the firewall anyway. - * - * @param EventManager $evm + * @param GetResponseEventArgs $eventArgs */ - function unregister(EventManager $evm); + function onCoreSecurity(GetResponseEventArgs $eventArgs); }
\ No newline at end of file diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php index a4b6991..d2b18cf 100644 --- a/Http/Firewall/LogoutListener.php +++ b/Http/Firewall/LogoutListener.php @@ -19,7 +19,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Kernel\Event\GetResponseEventArgs; use Symfony\Component\Kernel\Events; -use Doctrine\Common\EventManager; /** * LogoutListener logout users. @@ -28,11 +27,11 @@ use Doctrine\Common\EventManager; */ class LogoutListener implements ListenerInterface { - protected $securityContext; - protected $logoutPath; - protected $targetUrl; - protected $handlers; - protected $successHandler; + private $securityContext; + private $logoutPath; + private $targetUrl; + private $handlers; + private $successHandler; /** * Constructor @@ -62,23 +61,6 @@ class LogoutListener implements ListenerInterface } /** - * Registers a onCoreSecurity listener. - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - } - - /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Performs the logout if requested * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance diff --git a/Http/Firewall/RememberMeListener.php b/Http/Firewall/RememberMeListener.php index 73514bc..af5fc83 100644 --- a/Http/Firewall/RememberMeListener.php +++ b/Http/Firewall/RememberMeListener.php @@ -34,12 +34,11 @@ use Doctrine\Common\EventManager; */ class RememberMeListener implements ListenerInterface { - protected $securityContext; - protected $rememberMeServices; - protected $authenticationManager; - protected $logger; - protected $lastState; - protected $evm; + private $securityContext; + private $rememberMeServices; + private $authenticationManager; + private $logger; + private $evm; /** * Constructor @@ -49,111 +48,53 @@ class RememberMeListener implements ListenerInterface * @param AuthenticationManagerInterface $authenticationManager * @param LoggerInterface $logger */ - public function __construct(SecurityContext $securityContext, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null) + public function __construct(SecurityContext $securityContext, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventManager $evm = null) { $this->securityContext = $securityContext; $this->rememberMeServices = $rememberMeServices; $this->authenticationManager = $authenticationManager; $this->logger = $logger; - } - - /** - * Listen to onCoreSecurity and filterCoreResponse event - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener( - array(KernelEvents::onCoreSecurity, KernelEvents::filterCoreResponse), - $this - ); - $this->evm = $evm; } /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - $evm->removeEventListener(KernelEvents::onCoreSecurity, $this); - } - - /** * Handles remember-me cookie based authentication. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance */ public function onCoreSecurity(GetResponseEventArgs $eventArgs) { - $this->lastState = null; - if (null !== $this->securityContext->getToken()) { return; } - try { - if (null === $token = $this->rememberMeServices->autoLogin($eventArgs->getRequest())) { - return; - } - - try { - if (null === $token = $this->authenticationManager->authenticate($token)) { - return; - } - - $this->securityContext->setToken($token); - - if (null !== $this->evm) { - $loginEventArgs = new InteractiveLoginEventArgs($eventArgs->getRequest(), $token); - $this->evm->dispatchEvent(Events::onSecurityInteractiveLogin, $loginEventArgs); - } - - if (null !== $this->logger) { - $this->logger->debug('SecurityContext populated with remember-me token.'); - } + $request = $eventArgs->getRequest(); + if (null === $token = $this->rememberMeServices->autoLogin($request)) { + return; + } - $this->lastState = $token; - } catch (AuthenticationException $failed) { - if (null !== $this->logger) { - $this->logger->debug( - 'SecurityContext not populated with remember-me token as the' - .' AuthenticationManager rejected the AuthenticationToken returned' - .' by the RememberMeServices: '.$failed->getMessage() - ); - } + try { + $token = $this->authenticationManager->authenticate($token); + $this->securityContext->setToken($token); - $this->lastState = $failed; + if (null !== $this->evm) { + $loginEventArgs = new InteractiveLoginEventArgs($request, $token); + $this->evm->dispatchEvent(Events::onSecurityInteractiveLogin, $loginEventArgs); } - } catch (AuthenticationException $cookieInvalid) { - $this->lastState = $cookieInvalid; if (null !== $this->logger) { - $this->logger->debug('The presented cookie was invalid: '.$cookieInvalid->getMessage()); + $this->logger->debug('SecurityContext populated with remember-me token.'); } - - // silently ignore everything except a cookie theft exception - if ($cookieInvalid instanceof CookieTheftException) { - throw $cookieInvalid; + } catch (AuthenticationException $failed) { + if (null !== $this->logger) { + $this->logger->debug( + 'SecurityContext not populated with remember-me token as the' + .' AuthenticationManager rejected the AuthenticationToken returned' + .' by the RememberMeServices: '.$failed->getMessage() + ); } - } - } - - /** - * Update cookies - * @param Event $event - */ - public function filterCoreResponse(FilterResponseEventArgs $eventArgs) - { - if (HttpKernelInterface::MASTER_REQUEST !== $eventArgs->getRequestType()) { - return; - } - if ($this->lastState instanceof TokenInterface) { - $this->rememberMeServices->loginSuccess($eventArgs->getRequest(), $eventArgs->getResponse(), $this->lastState); - } else if ($this->lastState instanceof AuthenticationException) { - $this->rememberMeServices->loginFail($eventArgs->getRequest(), $eventArgs->getResponse()); + $this->rememberMeServices->loginFail($request); } } }
\ No newline at end of file diff --git a/Http/Firewall/SwitchUserListener.php b/Http/Firewall/SwitchUserListener.php index 5e352b9..11671ef 100644 --- a/Http/Firewall/SwitchUserListener.php +++ b/Http/Firewall/SwitchUserListener.php @@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Core\User\AccountCheckerInterface; +use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEventArgs; @@ -38,20 +38,20 @@ use Doctrine\Common\EventManager; */ class SwitchUserListener implements ListenerInterface { - protected $securityContext; - protected $provider; - protected $accountChecker; - protected $providerKey; - protected $accessDecisionManager; - protected $usernameParameter; - protected $role; - protected $logger; - protected $evm; + private $securityContext; + private $provider; + private $userChecker; + private $providerKey; + private $accessDecisionManager; + private $usernameParameter; + private $role; + private $logger; + private $evm; /** * Constructor. */ - public function __construct(SecurityContextInterface $securityContext, UserProviderInterface $provider, AccountCheckerInterface $accountChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH') + public function __construct(SecurityContextInterface $securityContext, UserProviderInterface $provider, UserCheckerInterface $userChecker, $providerKey, AccessDecisionManagerInterface $accessDecisionManager, LoggerInterface $logger = null, $usernameParameter = '_switch_user', $role = 'ROLE_ALLOWED_TO_SWITCH', EventManager $evm = null) { if (empty($providerKey)) { throw new \InvalidArgumentException('$providerKey must not be empty.'); @@ -59,34 +59,16 @@ class SwitchUserListener implements ListenerInterface $this->securityContext = $securityContext; $this->provider = $provider; - $this->accountChecker = $accountChecker; + $this->userChecker = $userChecker; $this->providerKey = $providerKey; $this->accessDecisionManager = $accessDecisionManager; $this->usernameParameter = $usernameParameter; $this->role = $role; $this->logger = $logger; - } - - /** - * - * - * @param EventManager $evm An EventManager instance - */ - public function register(EventManager $evm) - { - $evm->addEventListener(Events::onCoreSecurity, $this); - $this->evm = $evm; } /** - * {@inheritDoc} - */ - public function unregister(EventManager $evm) - { - } - - /** * Handles digest authentication. * * @param GetResponseEventArgs $eventArgs A GetResponseEventArgs instance @@ -124,11 +106,11 @@ class SwitchUserListener implements ListenerInterface * * @return TokenInterface|null The new TokenInterface if successfully switched, null otherwise */ - protected function attemptSwitchUser(Request $request) + private function attemptSwitchUser(Request $request) { $token = $this->securityContext->getToken(); if (false !== $this->getOriginalToken($token)) { - throw new \LogicException(sprintf('You are already switched to "%s" user.', (string) $token)); + throw new \LogicException(sprintf('You are already switched to "%s" user.', $token->getUsername())); } $this->accessDecisionManager->decide($token, array($this->role)); @@ -140,13 +122,12 @@ class SwitchUserListener implements ListenerInterface } $user = $this->provider->loadUserByUsername($username); - $this->accountChecker->checkPostAuth($user); + $this->userChecker->checkPostAuth($user); $roles = $user->getRoles(); $roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->securityContext->getToken()); $token = new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey, $roles); - $token->setImmutable(true); if (null !== $this->evm) { $switchEventArgs = new SwitchUserEventArgs($request, $token->getUser()); @@ -163,7 +144,7 @@ class SwitchUserListener implements ListenerInterface * * @return TokenInterface The original TokenInterface instance */ - protected function attemptExitUser(Request $request) + private function attemptExitUser(Request $request) { if (false === $original = $this->getOriginalToken($this->securityContext->getToken())) { throw new AuthenticationCredentialsNotFoundException(sprintf('Could not find original Token object.')); @@ -184,7 +165,7 @@ class SwitchUserListener implements ListenerInterface * * @return TokenInterface|false The original TokenInterface instance, false if the current TokenInterface is not switched */ - protected function getOriginalToken(TokenInterface $token) + private function getOriginalToken(TokenInterface $token) { foreach ($token->getRoles() as $role) { if ($role instanceof SwitchUserRole) { diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php index 126ef41..7f60daa 100644 --- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php @@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; use Symfony\Component\Security\Core\SecurityContextInterface; +use Doctrine\Common\EventManager; /** * UsernamePasswordFormAuthenticationListener is the default implementation of @@ -30,12 +31,12 @@ use Symfony\Component\Security\Core\SecurityContextInterface; */ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationListener { - protected $csrfProvider; + private $csrfProvider; /** * {@inheritdoc} */ - public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, CsrfProviderInterface $csrfProvider = null) + public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, EventManager $evm = null, CsrfProviderInterface $csrfProvider = null) { parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $providerKey, array_merge(array( 'username_parameter' => '_username', @@ -43,7 +44,7 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL 'csrf_parameter' => '_csrf_token', 'csrf_page_id' => 'form_login', 'post_only' => true, - ), $options), $successHandler, $failureHandler, $logger); + ), $options), $successHandler, $failureHandler, $logger, $evm); $this->csrfProvider = $csrfProvider; } @@ -76,5 +77,4 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey)); } -} - +}
\ No newline at end of file diff --git a/Http/Firewall/X509AuthenticationListener.php b/Http/Firewall/X509AuthenticationListener.php index 3505b99..509f541 100644 --- a/Http/Firewall/X509AuthenticationListener.php +++ b/Http/Firewall/X509AuthenticationListener.php @@ -16,6 +16,7 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterfac use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Exception\BadCredentialsException; +use Doctrine\Common\EventManager; /** * X509 authentication listener. @@ -27,9 +28,9 @@ class X509AuthenticationListener extends AbstractPreAuthenticatedListener protected $userKey; protected $credentialKey; - public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, $userKey = 'SSL_CLIENT_S_DN_Email', $credentialKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null) + public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, $providerKey, $userKey = 'SSL_CLIENT_S_DN_Email', $credentialKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null, EventManager $evm = null) { - parent::__construct($securityContext, $authenticationManager, $providerKey, $logger); + parent::__construct($securityContext, $authenticationManager, $providerKey, $logger, $evm); $this->userKey = $userKey; $this->credentialKey = $credentialKey; diff --git a/Http/FirewallMap.php b/Http/FirewallMap.php index c7a57f2..d5fc331 100644 --- a/Http/FirewallMap.php +++ b/Http/FirewallMap.php @@ -23,7 +23,7 @@ use Symfony\Component\Security\Http\Firewall\ExceptionListener; */ class FirewallMap implements FirewallMapInterface { - protected $map = array(); + private $map = array(); public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = array(), ExceptionListener $exceptionListener = null) { diff --git a/Http/Logout/CookieClearingLogoutHandler.php b/Http/Logout/CookieClearingLogoutHandler.php index 8ca284d..ebdcbed 100644 --- a/Http/Logout/CookieClearingLogoutHandler.php +++ b/Http/Logout/CookieClearingLogoutHandler.php @@ -22,7 +22,7 @@ use Symfony\Component\HttpFoundation\Request; */ class CookieClearingLogoutHandler implements LogoutHandlerInterface { - protected $cookies; + private $cookies; /** * Constructor diff --git a/Http/RememberMe/RememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php index 4370d92..b090e24 100644 --- a/Http/RememberMe/RememberMeServices.php +++ b/Http/RememberMe/AbstractRememberMeServices.php @@ -2,14 +2,19 @@ namespace Symfony\Component\Security\Http\RememberMe; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; +use Symfony\Component\Security\Core\Exception\CookieTheftException; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpKernel\Log\LoggerInterface; /* @@ -26,15 +31,15 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface; * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -abstract class RememberMeServices implements RememberMeServicesInterface, LogoutHandlerInterface +abstract class AbstractRememberMeServices implements RememberMeServicesInterface, LogoutHandlerInterface { const COOKIE_DELIMITER = ':'; - protected $userProviders; - protected $options; protected $logger; - protected $key; - protected $providerKey; + protected $options; + private $providerKey; + private $key; + private $userProviders; /** * Constructor @@ -73,6 +78,11 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout return $this->options['remember_me_parameter']; } + public function getKey() + { + return $this->key; + } + /** * Implementation of RememberMeServicesInterface. Detects whether a remember-me * cookie was set, decodes it, and hands it to subclasses for further processing. @@ -80,7 +90,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout * @param Request $request * @return TokenInterface */ - public function autoLogin(Request $request) + public final function autoLogin(Request $request) { if (null === $cookie = $request->cookies->get($this->options['name'])) { return; @@ -91,17 +101,40 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout } $cookieParts = $this->decodeCookie($cookie); - $token = $this->processAutoLoginCookie($cookieParts, $request); - if (!$token instanceof TokenInterface) { - throw new \RuntimeException('processAutoLoginCookie() must return a TokenInterface implementation.'); - } + try { + $user = $this->processAutoLoginCookie($cookieParts, $request); - if (null !== $this->logger) { - $this->logger->debug('Remember-me cookie accepted.'); + if (!$user instanceof UserInterface) { + throw new \RuntimeException('processAutoLoginCookie() must return a UserInterface implementation.'); + } + + if (null !== $this->logger) { + $this->logger->debug('Remember-me cookie accepted.'); + } + + return new RememberMeToken($user, $this->providerKey, $this->key); + } catch (CookieTheftException $theft) { + $this->cancelCookie($request); + + throw $theft; + } catch (UsernameNotFoundException $notFound) { + if (null !== $this->logger) { + $this->logger->debug('User for remember-me cookie not found.'); + } + } catch (UnsupportedUserException $unSupported) { + if (null !== $this->logger) { + $this->logger->debug('User class for remember-me cookie not supported.'); + } + } catch (AuthenticationException $invalid) { + if (null !== $this->logger) { + $this->logger->debug('Remember-Me authentication failed: '.$invalid->getMessage()); + } } - return $token; + $this->cancelCookie($request); + + return null; } /** @@ -114,7 +147,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout */ public function logout(Request $request, Response $response, TokenInterface $token) { - $this->cancelCookie($response); + $this->cancelCookie($request); } /** @@ -122,12 +155,12 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout * an attempted authentication fails. * * @param Request $request - * @param Response $response * @return void */ - public function loginFail(Request $request, Response $response) + public final function loginFail(Request $request) { - $this->cancelCookie($response); + $this->cancelCookie($request); + $this->onLoginFail($request); } /** @@ -139,30 +172,26 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout * @param TokenInterface $token The token that resulted in a successful authentication * @return void */ - public function loginSuccess(Request $request, Response $response, TokenInterface $token) + public final function loginSuccess(Request $request, Response $response, TokenInterface $token) { - if (!$token instanceof RememberMeToken) { - if (!$token->getUser() instanceof AccountInterface) { - if (null !== $this->logger) { - $this->logger->debug('Remember-me ignores token since it does not contain an AccountInterface implementation.'); - } - - return; + if (!$token->getUser() instanceof UserInterface) { + if (null !== $this->logger) { + $this->logger->debug('Remember-me ignores token since it does not contain an UserInterface implementation.'); } - if (!$this->isRememberMeRequested($request)) { - if (null !== $this->logger) { - $this->logger->debug('Remember-me was not requested.'); - } - - return; - } + return; + } + if (!$this->isRememberMeRequested($request)) { if (null !== $this->logger) { - $this->logger->debug('Remember-me was requested; setting cookie.'); + $this->logger->debug('Remember-me was not requested.'); } - } else if (null !== $this->logger) { - $this->logger->debug('Re-newing remember-me token; setting cookie.'); + + return; + } + + if (null !== $this->logger) { + $this->logger->debug('Remember-me was requested; setting cookie.'); } $this->onLoginSuccess($request, $response, $token); @@ -178,6 +207,10 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout */ abstract protected function processAutoLoginCookie(array $cookieParts, Request $request); + protected function onLoginFail(Request $request) + { + } + /** * This is called after a user has been logged in successfully, and has * requested remember-me capabilities. The implementation usually sets a @@ -190,7 +223,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout */ abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token); - protected function getUserProvider($class) + protected final function getUserProvider($class) { foreach ($this->userProviders as $provider) { if ($provider->supportsClass($class)) { @@ -198,7 +231,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout } } - throw new \RuntimeException(sprintf('There is no user provider that supports class "%s".', $class)); + throw new UnsupportedUserException(sprintf('There is no user provider that supports class "%s".', $class)); } /** @@ -226,16 +259,16 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout /** * Deletes the remember-me cookie * - * @param Response $response + * @param Request $request * @return void */ - protected function cancelCookie(Response $response) + protected function cancelCookie(Request $request) { if (null !== $this->logger) { $this->logger->debug(sprintf('Clearing remember-me cookie "%s"', $this->options['name'])); } - $response->headers->clearCookie($this->options['name'], $this->options['path'], $this->options['domain']); + $request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'])); } /** diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php index ff3306e..f2a0249 100644 --- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php @@ -28,9 +28,9 @@ use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -class PersistentTokenBasedRememberMeServices extends RememberMeServices +class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices { - protected $tokenProvider; + private $tokenProvider; /** * Sets the token provider @@ -46,6 +46,21 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices /** * {@inheritDoc} */ + public function logout(Request $request, Response $response, TokenInterface $token) + { + parent::logout($request, $response, $token); + + if (null !== ($cookie = $request->cookies->get($this->options['name'])) + && count($parts = $this->decodeCookie($cookie)) === 2 + ) { + list($series, $tokenValue) = $parts; + $this->tokenProvider->deleteTokenBySeries($series); + } + } + + /** + * {@inheritDoc} + */ protected function processAutoLoginCookie(array $cookieParts, Request $request) { if (count($cookieParts) !== 2) { @@ -65,11 +80,22 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices throw new AuthenticationException('The cookie has expired.'); } - $user = $this->getUserProvider($persistentToken->getClass())->loadUserByUsername($persistentToken->getUsername()); - $authenticationToken = new RememberMeToken($user, $this->providerKey, $this->key); - $authenticationToken->setPersistentToken($persistentToken); + $series = $persistentToken->getSeries(); + $tokenValue = $this->generateRandomValue(); + $this->tokenProvider->updateToken($series, $tokenValue, new \DateTime()); + $request->attributes->set(self::COOKIE_ATTR_NAME, + new Cookie( + $this->options['name'], + $this->encodeCookie(array($series, $tokenValue)), + time() + $this->options['lifetime'], + $this->options['path'], + $this->options['domain'], + $this->options['secure'], + $this->options['httponly'] + ) + ); - return $authenticationToken; + return $this->getUserProvider($persistentToken->getClass())->loadUserByUsername($persistentToken->getUsername()); } /** @@ -77,34 +103,23 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices */ protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token) { - if ($token instanceof RememberMeToken) { - if (null === $persistentToken = $token->getPersistentToken()) { - throw new \RuntimeException('RememberMeToken must contain a PersistentTokenInterface implementation when used as login.'); - } - - $series = $persistentToken->getSeries(); - $tokenValue = $this->generateRandomValue(); - - $this->tokenProvider->updateToken($series, $tokenValue, new \DateTime()); - } else { - $series = $this->generateRandomValue(); - $tokenValue = $this->generateRandomValue(); - - $this->tokenProvider->createNewToken( - new PersistentToken( - get_class($user = $token->getUser()), - $user->getUsername(), - $series, - $tokenValue, - new \DateTime() - ) - ); - } + $series = $this->generateRandomValue(); + $tokenValue = $this->generateRandomValue(); + + $this->tokenProvider->createNewToken( + new PersistentToken( + get_class($user = $token->getUser()), + $user->getUsername(), + $series, + $tokenValue, + new \DateTime() + ) + ); $response->headers->setCookie( new Cookie( $this->options['name'], - $this->generateCookieValue($series, $tokenValue), + $this->encodeCookie(array($series, $tokenValue)), time() + $this->options['lifetime'], $this->options['path'], $this->options['domain'], @@ -115,33 +130,6 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices } /** - * {@inheritDoc} - */ - public function logout(Request $request, Response $response, TokenInterface $token) - { - parent::logout($request, $response, $token); - - if (null !== ($cookie = $request->cookies->get($this->options['name'])) - && count($parts = $this->decodeCookie($cookie)) === 2 - ) { - list($series, $tokenValue) = $parts; - $this->tokenProvider->deleteTokenBySeries($series); - } - } - - /** - * Generates the value for the cookie - * - * @param string $series - * @param string $tokenValue - * @return string - */ - protected function generateCookieValue($series, $tokenValue) - { - return $this->encodeCookie(array($series, $tokenValue)); - } - - /** * Generates a cryptographically strong random value * * @return string @@ -149,7 +137,7 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices protected function generateRandomValue() { if (function_exists('openssl_random_pseudo_bytes')) { - $bytes = openssl_random_pseudo_bytes(32, $strong); + $bytes = openssl_random_pseudo_bytes(64, $strong); if (true === $strong && false !== $bytes) { return base64_encode($bytes); @@ -160,6 +148,6 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices $this->logger->warn('Could not produce a cryptographically strong random value. Please install/update the OpenSSL extension.'); } - return base64_encode(hash('sha256', uniqid(mt_rand(), true), true)); + return base64_encode(hash('sha512', uniqid(mt_rand(), true), true)); } -} +}
\ No newline at end of file diff --git a/Http/RememberMe/RememberMeServicesInterface.php b/Http/RememberMe/RememberMeServicesInterface.php index b038a0d..c740d28 100644 --- a/Http/RememberMe/RememberMeServicesInterface.php +++ b/Http/RememberMe/RememberMeServicesInterface.php @@ -17,50 +17,67 @@ use Symfony\Component\HttpFoundation\Request; /** * Interface that needs to be implemented by classes which provide remember-me * capabilities. - * + * * We provide two implementations out-of-the-box: * - TokenBasedRememberMeServices (does not require a TokenProvider) * - PersistentTokenBasedRememberMeServices (requires a TokenProvider) - * + * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ interface RememberMeServicesInterface { /** - * This method will be called whenever the SecurityContext does not contain - * an TokenInterface object and the framework wishes to provide an implementation - * with an opportunity to authenticate the request using remember-me capabilities. - * + * This attribute name can be used by the implementation if it needs to set + * a cookie on the Request when there is no actual Response, yet. + * + * @var string + */ + const COOKIE_ATTR_NAME = '_security_remember_me_cookie'; + + /** + * This method will be called whenever the SecurityContext does not contain + * an TokenInterface object and the framework wishes to provide an implementation + * with an opportunity to authenticate the request using remember-me capabilities. + * * No attempt whatsoever is made to determine whether the browser has requested * remember-me services or presented a valid cookie. Any and all such determinations - * are left to the implementation of this method. - * + * are left to the implementation of this method. + * * If a browser has presented an unauthorised cookie for whatever reason, - * make sure to throw an AuthenticationException as this will consequentially + * make sure to throw an AuthenticationException as this will consequentially * result in a call to loginFail() and therefore an invalidation of the cookie. - * + * * @param Request $request * @return TokenInterface */ function autoLogin(Request $request); - + /** - * Called whenever an authentication attempt was made, but the credentials - * supplied by the user were missing or otherwise invalid. - * + * Called whenever an interactive authentication attempt was made, but the + * credentials supplied by the user were missing or otherwise invalid. + * * This method needs to take care of invalidating the cookie. + * + * @param Request $request + * @return void */ - function loginFail(Request $request, Response $response); + function loginFail(Request $request); /** - * Called whenever authentication attempt is successful (e.g. a form login). - * - * An implementation may always set a remember-me cookie in the Response, - * although this is not recommended. - * - * Instead, implementations should typically look for a request parameter + * Called whenever an interactive authentication attempt is successful + * (e.g. a form login). + * + * An implementation may always set a remember-me cookie in the Response, + * although this is not recommended. + * + * Instead, implementations should typically look for a request parameter * (such as a HTTP POST parameter) that indicates the browser has explicitly * requested for the authentication to be remembered. + * + * @param Request $request + * @param Response $response + * @param TokenInterface $token + * @return void */ function loginSuccess(Request $request, Response $response, TokenInterface $token); }
\ No newline at end of file diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php index 40757f4..0fd5c41 100644 --- a/Http/RememberMe/TokenBasedRememberMeServices.php +++ b/Http/RememberMe/TokenBasedRememberMeServices.php @@ -8,7 +8,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\AccountInterface; +use Symfony\Component\Security\Core\User\UserInterface; /* * This file is part of the Symfony package. @@ -25,7 +25,7 @@ use Symfony\Component\Security\Core\User\AccountInterface; * * @author Johannes M. Schmitt <schmittjoh@gmail.com> */ -class TokenBasedRememberMeServices extends RememberMeServices +class TokenBasedRememberMeServices extends AbstractRememberMeServices { /** * {@inheritDoc} @@ -50,8 +50,8 @@ class TokenBasedRememberMeServices extends RememberMeServices throw $ex; } - if (!$user instanceof AccountInterface) { - throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of AccountInterface, but returned "%s".', get_class($user))); + if (!$user instanceof UserInterface) { + throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_class($user))); } if (true !== $this->compareHashes($hash, $this->generateCookieHash($class, $username, $expires, $user->getPassword()))) { @@ -62,7 +62,7 @@ class TokenBasedRememberMeServices extends RememberMeServices throw new AuthenticationException('The cookie has expired.'); } - return new RememberMeToken($user, $this->providerKey, $this->key); + return $user; } /** @@ -76,7 +76,7 @@ class TokenBasedRememberMeServices extends RememberMeServices * * @return Boolean true if the two hashes are the same, false otherwise */ - protected function compareHashes($hash1, $hash2) + private function compareHashes($hash1, $hash2) { if (strlen($hash1) !== $c = strlen($hash2)) { return false; @@ -95,10 +95,6 @@ class TokenBasedRememberMeServices extends RememberMeServices */ protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token) { - if ($token instanceof RememberMeToken) { - return; - } - $user = $token->getUser(); $expires = time() + $this->options['lifetime']; $value = $this->generateCookieValue(get_class($user), $user->getUsername(), $expires, $user->getPassword()); @@ -150,6 +146,6 @@ class TokenBasedRememberMeServices extends RememberMeServices */ protected function generateCookieHash($class, $username, $expires, $password) { - return hash('sha256', $class.$username.$expires.$password.$this->key); + return hash('sha256', $class.$username.$expires.$password.$this->getKey()); } } diff --git a/Http/Session/SessionAuthenticationStrategy.php b/Http/Session/SessionAuthenticationStrategy.php index 1d25bd9..dea34be 100644 --- a/Http/Session/SessionAuthenticationStrategy.php +++ b/Http/Session/SessionAuthenticationStrategy.php @@ -21,7 +21,7 @@ class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInte const MIGRATE = 'migrate'; const INVALIDATE = 'invalidate'; - protected $strategy; + private $strategy; public function __construct($strategy) { |