diff options
Diffstat (limited to 'Core/User')
-rw-r--r-- | Core/User/AccountChecker.php | 61 | ||||
-rw-r--r-- | Core/User/AccountCheckerInterface.php | 36 | ||||
-rw-r--r-- | Core/User/AccountInterface.php | 74 | ||||
-rw-r--r-- | Core/User/AdvancedAccountInterface.php | 48 | ||||
-rw-r--r-- | Core/User/InMemoryUserProvider.php | 98 | ||||
-rw-r--r-- | Core/User/User.php | 163 | ||||
-rw-r--r-- | Core/User/UserProviderInterface.php | 57 |
7 files changed, 537 insertions, 0 deletions
diff --git a/Core/User/AccountChecker.php b/Core/User/AccountChecker.php new file mode 100644 index 0000000..76befa6 --- /dev/null +++ b/Core/User/AccountChecker.php @@ -0,0 +1,61 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +use Symfony\Component\Security\Core\Exception\CredentialsExpiredException; +use Symfony\Component\Security\Core\Exception\LockedException; +use Symfony\Component\Security\Core\Exception\DisabledException; +use Symfony\Component\Security\Core\Exception\AccountExpiredException; + +/** + * AccountChecker checks the user account flags. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +class AccountChecker implements AccountCheckerInterface +{ + /** + * {@inheritdoc} + */ + public function checkPreAuth(AccountInterface $account) + { + if (!$account instanceof AdvancedAccountInterface) { + return; + } + + if (!$account->isCredentialsNonExpired()) { + throw new CredentialsExpiredException('User credentials have expired.', $account); + } + } + + /** + * {@inheritdoc} + */ + public function checkPostAuth(AccountInterface $account) + { + if (!$account instanceof AdvancedAccountInterface) { + return; + } + + if (!$account->isAccountNonLocked()) { + throw new LockedException('User account is locked.', $account); + } + + if (!$account->isEnabled()) { + throw new DisabledException('User account is disabled.', $account); + } + + if (!$account->isAccountNonExpired()) { + throw new AccountExpiredException('User account has expired.', $account); + } + } +} diff --git a/Core/User/AccountCheckerInterface.php b/Core/User/AccountCheckerInterface.php new file mode 100644 index 0000000..cf0d68b --- /dev/null +++ b/Core/User/AccountCheckerInterface.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +/** + * AccountCheckerInterface checks user account when authentication occurs. + * + * This should not be used to make authentication decisions. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +interface AccountCheckerInterface +{ + /** + * Checks the user account before authentication. + * + * @param AccountInterface $account An AccountInterface instance + */ + function checkPreAuth(AccountInterface $account); + + /** + * Checks the user account after authentication. + * + * @param AccountInterface $account An AccountInterface instance + */ + function checkPostAuth(AccountInterface $account); +} diff --git a/Core/User/AccountInterface.php b/Core/User/AccountInterface.php new file mode 100644 index 0000000..1863302 --- /dev/null +++ b/Core/User/AccountInterface.php @@ -0,0 +1,74 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +/** + * AccountInterface is the interface that user classes must implement. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +interface AccountInterface +{ + /** + * Returns a string representation of the User. + * + * @return string A string return of the User + */ + function __toString(); + + /** + * Returns the roles granted to the user. + * + * @return Role[] The user roles + */ + function getRoles(); + + /** + * Returns the password used to authenticate the user. + * + * @return string The password + */ + function getPassword(); + + /** + * Returns the salt. + * + * @return string The salt + */ + function getSalt(); + + /** + * Returns the username used to authenticate the user. + * + * @return string The username + */ + function getUsername(); + + /** + * Removes sensitive data from the user. + * + * @return void + */ + function eraseCredentials(); + + /** + * The equality comparison should neither be done by referential equality + * nor by comparing identities (i.e. getId() === getId()). + * + * 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 + * @return Boolean + */ + function equals(AccountInterface $account); +} diff --git a/Core/User/AdvancedAccountInterface.php b/Core/User/AdvancedAccountInterface.php new file mode 100644 index 0000000..654ccaf --- /dev/null +++ b/Core/User/AdvancedAccountInterface.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +/** + * AdvancedAccountInterface adds status flags to a regular account. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +interface AdvancedAccountInterface extends AccountInterface +{ + /** + * Checks whether the user's account has expired. + * + * @return Boolean true if the user's account is non expired, false otherwise + */ + function isAccountNonExpired(); + + /** + * Checks whether the user is locked. + * + * @return Boolean true if the user is not locked, false otherwise + */ + function isAccountNonLocked(); + + /** + * Checks whether the user's credentials (password) has expired. + * + * @return Boolean true if the user's credentials are non expired, false otherwise + */ + function isCredentialsNonExpired(); + + /** + * Checks whether the user is enabled. + * + * @return Boolean true if the user is enabled, false otherwise + */ + function isEnabled(); +} diff --git a/Core/User/InMemoryUserProvider.php b/Core/User/InMemoryUserProvider.php new file mode 100644 index 0000000..cc15463 --- /dev/null +++ b/Core/User/InMemoryUserProvider.php @@ -0,0 +1,98 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; +use Symfony\Component\Security\Core\Exception\UnsupportedAccountException; + +/** + * InMemoryUserProvider is a simple non persistent user provider. + * + * Useful for testing, demonstration, prototyping, and for simple needs + * (a backend with a unique admin for instance) + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +class InMemoryUserProvider implements UserProviderInterface +{ + protected $users; + + /** + * Constructor. + * + * The user array is a hash where the keys are usernames and the values are + * an array of attributes: 'password', 'enabled', and 'roles'. + * + * @param array $users An array of users + * @param string $name + */ + public function __construct(array $users = array()) + { + foreach ($users as $username => $attributes) { + $password = isset($attributes['password']) ? $attributes['password'] : null; + $enabled = isset($attributes['enabled']) ? $attributes['enabled'] : true; + $roles = isset($attributes['roles']) ? $attributes['roles'] : array(); + $user = new User($username, $password, $roles, $enabled, true, true, true); + + $this->createUser($user); + } + } + + /** + * Adds a new User to the provider. + * + * @param AccountInterface $user A AccountInterface instance + */ + public function createUser(AccountInterface $user) + { + if (isset($this->users[strtolower($user->getUsername())])) { + throw new \LogicException('Another user with the same username already exist.'); + } + + $this->users[strtolower($user->getUsername())] = $user; + } + + /** + * {@inheritdoc} + */ + public function loadUserByUsername($username) + { + if (!isset($this->users[strtolower($username)])) { + throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username)); + } + + $user = $this->users[strtolower($username)]; + + return new User($user->getUsername(), $user->getPassword(), $user->getRoles(), $user->isEnabled(), $user->isAccountNonExpired(), + $user->isCredentialsNonExpired(), $user->isAccountNonLocked()); + } + + /** + * {@inheritDoc} + */ + public function loadUserByAccount(AccountInterface $account) + { + if (!$account instanceof User) { + throw new UnsupportedAccountException(sprintf('Instances of "%s" are not supported.', get_class($account))); + } + + return $this->loadUserByUsername((string) $account); + } + + /** + * {@inheritDoc} + */ + public function supportsClass($class) + { + return $class === 'Symfony\Component\Security\Core\User\User'; + } +} diff --git a/Core/User/User.php b/Core/User/User.php new file mode 100644 index 0000000..49f7042 --- /dev/null +++ b/Core/User/User.php @@ -0,0 +1,163 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +/** + * User is the user implementation used by the in-memory user provider. + * + * This should not be used for anything else. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +class User implements AdvancedAccountInterface +{ + 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) + { + if (empty($username)) { + throw new \InvalidArgumentException('The username cannot be empty.'); + } + + $this->username = $username; + $this->password = $password; + $this->enabled = $enabled; + $this->accountNonExpired = $accountNonExpired; + $this->credentialsNonExpired = $credentialsNonExpired; + $this->accountNonLocked = $accountNonLocked; + $this->roles = $roles; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->username; + } + + /** + * {@inheritdoc} + */ + public function getRoles() + { + return $this->roles; + } + + /** + * {@inheritdoc} + */ + public function getPassword() + { + return $this->password; + } + + /** + * {@inheritdoc} + */ + public function getSalt() + { + return null; + } + + /** + * {@inheritdoc} + */ + public function getUsername() + { + return $this->username; + } + + /** + * {@inheritdoc} + */ + public function isAccountNonExpired() + { + return $this->accountNonExpired; + } + + /** + * {@inheritdoc} + */ + public function isAccountNonLocked() + { + return $this->accountNonLocked; + } + + /** + * {@inheritdoc} + */ + public function isCredentialsNonExpired() + { + return $this->credentialsNonExpired; + } + + /** + * {@inheritdoc} + */ + public function isEnabled() + { + return $this->enabled; + } + + /** + * {@inheritdoc} + */ + public function eraseCredentials() + { + } + + /** + * {@inheritDoc} + */ + public function equals(AccountInterface $account) + { + if (!$account instanceof User) { + return false; + } + + if ($this->password !== $account->getPassword()) { + return false; + } + + if ($this->getSalt() !== $account->getSalt()) { + return false; + } + + if ($this->username !== $account->getUsername()) { + return false; + } + + if ($this->accountNonExpired !== $account->isAccountNonExpired()) { + return false; + } + + if ($this->accountNonLocked !== $account->isAccountNonLocked()) { + return false; + } + + if ($this->credentialsNonExpired !== $account->isCredentialsNonExpired()) { + return false; + } + + if ($this->enabled !== $account->isEnabled()) { + return false; + } + + return true; + } +} diff --git a/Core/User/UserProviderInterface.php b/Core/User/UserProviderInterface.php new file mode 100644 index 0000000..70ba0d0 --- /dev/null +++ b/Core/User/UserProviderInterface.php @@ -0,0 +1,57 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\User; + +/** + * UserProviderInterface is the implementation that all user provider must + * implement. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +interface UserProviderInterface +{ + /** + * Loads the user for the given username. + * + * This method must throw UsernameNotFoundException if the user is not + * found. + * + * @throws UsernameNotFoundException if the user is not found + * @param string $username The username + * + * @return AccountInterface + */ + function loadUserByUsername($username); + + /** + * Loads the user for the account interface. + * + * It is up to the implementation if it decides to reload the user data + * 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 + * + * @return AccountInterface + */ + function loadUserByAccount(AccountInterface $account); + + /** + * Whether this provider supports the given user class + * + * @param string $class + * + * @return Boolean + */ + function supportsClass($class); +}
\ No newline at end of file |