diff --git a/Module.php b/Module.php index c3537950..6a6bef79 100644 --- a/Module.php +++ b/Module.php @@ -63,15 +63,12 @@ public function getServiceConfig() { return array( 'invokables' => array( - 'ZfcUser\Authentication\Adapter\Db' => 'ZfcUser\Authentication\Adapter\Db', - 'ZfcUser\Authentication\Storage\Db' => 'ZfcUser\Authentication\Storage\Db', 'ZfcUser\Form\Login' => 'ZfcUser\Form\Login', 'zfcuser_user_service' => 'ZfcUser\Service\User', ), 'factories' => array( 'zfcuser_module_options' => 'ZfcUser\Factory\ModuleOptionsFactory', 'zfcuser_auth_service' => 'ZfcUser\Factory\AuthenticationServiceFactory', - 'ZfcUser\Authentication\Adapter\AdapterChain' => 'ZfcUser\Authentication\Adapter\AdapterChainServiceFactory', 'zfcuser_login_form' => 'ZfcUser\Factory\Form\LoginFormFactory', 'zfcuser_register_form' => 'ZfcUser\Factory\Form\RegisterFormFactory', 'zfcuser_user_mapper' => 'ZfcUser\Factory\UserMapperFactory', diff --git a/config/module.config.php b/config/module.config.php index 8263fa3c..aba08f59 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -39,15 +39,18 @@ ), 'service_manager' => array( 'invokables' => array( - 'ZfcUser\Authentication\Adapter\Db' => 'ZfcUser\Authentication\Adapter\Db', - 'ZfcUser\Authentication\Storage\Db' => 'ZfcUser\Authentication\Storage\Db', 'ZfcUser\Form\Login' => 'ZfcUser\Form\Login', 'zfcuser_user_service' => 'ZfcUser\Service\User', + 'zfcuser_authentication_storage_backend_session' => 'Zend\Authentication\Storage\Session', ), 'factories' => array( 'zfcuser_module_options' => 'ZfcUser\Factory\ModuleOptionsFactory', 'zfcuser_auth_service' => 'ZfcUser\Factory\AuthenticationServiceFactory', - 'ZfcUser\Authentication\Adapter\AdapterChain' => 'ZfcUser\Authentication\Adapter\AdapterChainServiceFactory', + 'ZfcUser\Authentication\Adapter\AdapterChain' => 'ZfcUser\Factory\Authentication\Adapter\AdapterChainFactory', + 'ZfcUser\Authentication\Adapter\MapperUsername' => 'ZfcUser\Factory\Authentication\Adapter\MapperUsernameFactory', + 'ZfcUser\Authentication\Adapter\MapperEmail' => 'ZfcUser\Factory\Authentication\Adapter\MapperEmailFactory', + 'zfcuser_authentication_credentialprocessor_bcrypt' => 'ZfcUser\Factory\Authentication\CredentialProcessor\BcryptFactory', + 'ZfcUser\Authentication\Storage\Mapper' => 'ZfcUser\Factory\Authentication\Storage\MapperFactory', 'zfcuser_login_form' => 'ZfcUser\Factory\Form\LoginFormFactory', 'zfcuser_register_form' => 'ZfcUser\Factory\Form\RegisterFormFactory', 'zfcuser_change_password_form' => 'ZfcUser\Factory\Form\ChangePasswordFormFactory', @@ -55,9 +58,17 @@ 'zfcuser_user_mapper' => 'ZfcUser\Factory\UserMapperFactory', 'zfcuser_user_hydrator' => 'ZfcUser\Factory\Mapper\UserHydratorFactory', ), + 'delegators' => array( + 'zfcuser_authentication_storage_backend_session' => array( + 'ZfcUser\Factory\Authentication\Listener\RegenerateSessionIdentifierFactory' + ), + ), 'aliases' => array( 'zfcuser_register_form_hydrator' => 'zfcuser_user_hydrator', 'zfcuser_zend_db_adapter' => 'Zend\Db\Adapter\Adapter', + 'zfcuser_authentication_credentialprocessor' => 'zfcuser_authentication_credentialprocessor_bcrypt', + 'zfcuser_authentication_storage' => 'ZfcUser\Authentication\Storage\Mapper', + 'zfcuser_authentication_storage_backend' => 'zfcuser_authentication_storage_backend_session', ), ), 'controller_plugins' => array( diff --git a/config/zfcuser.global.php.dist b/config/zfcuser.global.php.dist index f0f007c9..44ba551f 100644 --- a/config/zfcuser.global.php.dist +++ b/config/zfcuser.global.php.dist @@ -50,7 +50,7 @@ $settings = array( * Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100 * Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter' */ - 'auth_adapters' => array( 100 => 'ZfcUser\Authentication\Adapter\Db' ), + 'auth_adapters' => array( 100 => 'ZfcUser\Authentication\Adapter\MapperEmail' ), /** * Enable Display Name diff --git a/src/ZfcUser/Authentication/Adapter/AbstractAdapter.php b/src/ZfcUser/Authentication/Adapter/AbstractAdapter.php deleted file mode 100644 index 56924cc4..00000000 --- a/src/ZfcUser/Authentication/Adapter/AbstractAdapter.php +++ /dev/null @@ -1,70 +0,0 @@ -storage) { - $this->setStorage(new SessionStorage(get_class($this))); - } - - return $this->storage; - } - - /** - * Sets the persistent storage handler - * - * @param StorageInterface $storage - * @return AbstractAdapter Provides a fluent interface - */ - public function setStorage(StorageInterface $storage) - { - $this->storage = $storage; - return $this; - } - - /** - * Check if this adapter is satisfied or not - * - * @return bool - */ - public function isSatisfied() - { - $storage = $this->getStorage()->read(); - return (isset($storage['is_satisfied']) && true === $storage['is_satisfied']); - } - - /** - * Set if this adapter is satisfied or not - * - * @param bool $bool - * @return AbstractAdapter - */ - public function setSatisfied($bool = true) - { - $storage = $this->getStorage(); - $data = $storage->read() ?: array(); - - $data['is_satisfied'] = (bool) $bool; - $storage->write($data); - - return $this; - } -} diff --git a/src/ZfcUser/Authentication/Adapter/AdapterChain.php b/src/ZfcUser/Authentication/Adapter/AdapterChain.php index be74abce..e3a93e90 100644 --- a/src/ZfcUser/Authentication/Adapter/AdapterChain.php +++ b/src/ZfcUser/Authentication/Adapter/AdapterChain.php @@ -2,139 +2,85 @@ namespace ZfcUser\Authentication\Adapter; -use Zend\Authentication\Adapter\AdapterInterface; -use Zend\Authentication\Result as AuthenticationResult; -use Zend\EventManager\Event; -use Zend\Stdlib\RequestInterface as Request; -use Zend\Stdlib\ResponseInterface as Response; -use ZfcBase\EventManager\EventProvider; -use ZfcUser\Exception; - -class AdapterChain extends EventProvider implements AdapterInterface +use Zend\Authentication\Adapter\AbstractAdapter; +use Zend\Stdlib\PriorityList; +use Zend\Authentication\Result; +use Zend\EventManager\EventManagerAwareTrait; + +/** + * Chainable authentication adapter for Zend\Authentication + * + * Allows multiple authentication adapters to be tried in succession, + * breaking the chain on the first adapter to return a successful result + */ +class AdapterChain extends AbstractAdapter { + use EventManagerAwareTrait; + /** - * @var AdapterChainEvent - */ - protected $event; - - /** - * Returns the authentication result - * - * @return AuthenticationResult + * @var PriorityList */ - public function authenticate() + protected $adapters; + + public function __construct() { - $e = $this->getEvent(); - - $result = new AuthenticationResult( - $e->getCode(), - $e->getIdentity(), - $e->getMessages() - ); - - $this->resetAdapters(); - - return $result; + $this->adapters = new PriorityList(); + $this->adapters->isLIFO(false); } /** - * prepareForAuthentication - * - * @param Request $request - * @return Response|bool - * @throws Exception\AuthenticationEventException + * Attach an authentication adapter to the chain at the specified priority + * + * @param type $name + * @param AbstractAdapter $adapter + * @param type $priority + * @return \ZfcUser\Authentication\Adapter\AdapterChain */ - public function prepareForAuthentication(Request $request) + public function attach($name, AbstractAdapter $adapter, $priority = 1) { - $e = $this->getEvent(); - $e->setRequest($request); - - $this->getEventManager()->trigger('authenticate.pre', $e); - - $result = $this->getEventManager()->trigger('authenticate', $e, function ($test) { - return ($test instanceof Response); - }); - - if ($result->stopped()) { - if ($result->last() instanceof Response) { - return $result->last(); - } - - throw new Exception\AuthenticationEventException( - sprintf( - 'Auth event was stopped without a response. Got "%s" instead', - is_object($result->last()) ? get_class($result->last()) : gettype($result->last()) - ) - ); - } - - if ($e->getIdentity()) { - $this->getEventManager()->trigger('authenticate.success', $e); - return true; - } - - $this->getEventManager()->trigger('authenticate.fail', $e); - return false; - } - - /** - * resetAdapters - * - * @return AdapterChain - */ - public function resetAdapters() - { - $listeners = $this->getEventManager()->getListeners('authenticate'); - foreach ($listeners as $listener) { - $listener = $listener->getCallback(); - if (is_array($listener) && $listener[0] instanceof ChainableAdapter) { - $listener[0]->getStorage()->clear(); - } - } + $argv = compact('name', 'adapter', 'priority'); + $this->getEventManager()->trigger(__FUNCTION__, $this, $argv); + + $this->adapters->insert($name, $adapter, $priority); return $this; } - - /** - * logoutAdapters - * - * @return AdapterChain - */ - public function logoutAdapters() - { - //Adapters might need to perform additional cleanup after logout - $this->getEventManager()->trigger('logout', $this->getEvent()); - } - + /** - * Get the auth event + * Cycles through the attached adapters, short-circuiting when a + * successful authentication result is returned. Adapters are executed + * in descending priority order, with adapters at the same priority level + * executed in order of registration (FIFO) * - * @return AdapterChainEvent + * @return Result */ - public function getEvent() + public function authenticate() { - if (null === $this->event) { - $this->setEvent(new AdapterChainEvent); - $this->event->setTarget($this); + $response = $this->getEventManager()->trigger(__FUNCTION__ . '.pre', $this); + if ($response->stopped()) { + return $response->last(); } - return $this->event; - } - - /** - * Set an event to use during dispatch - * - * By default, will re-cast to AdapterChainEvent if another event type is provided. - * - * @param Event $e - * @return AdapterChain - */ - public function setEvent(Event $e) - { - if (!$e instanceof AdapterChainEvent) { - $eventParams = $e->getParams(); - $e = new AdapterChainEvent(); - $e->setParams($eventParams); + + foreach ($this->adapters as $adapter) { + $adapter->setIdentity($this->getIdentity()); + $adapter->setCredential($this->getCredential()); + + $result = $adapter->authenticate(); + if ($result->isValid()) { + $argv = compact('adapter', 'result'); + $this->getEventManager()->trigger(__FUNCTION__ . '.success', $this, $argv); + return $result; + } } - $this->event = $e; - return $this; + + //@TODO throw an exception if no result? (no adapters tried) + + if (!isset($result) || ! $result instanceof Result) { + $result = new Result(Result::FAILURE_UNCATEGORIZED, null); + } + + $argv = compact('result'); + $this->getEventManager()->trigger(__FUNCTION__ . '.failure', $this, $argv); + + return $result; } } diff --git a/src/ZfcUser/Authentication/Adapter/AdapterChainEvent.php b/src/ZfcUser/Authentication/Adapter/AdapterChainEvent.php deleted file mode 100644 index 232e4f33..00000000 --- a/src/ZfcUser/Authentication/Adapter/AdapterChainEvent.php +++ /dev/null @@ -1,108 +0,0 @@ -getParam('identity'); - } - - /** - * setIdentity - * - * @param mixed $identity - * @return AdapterChainEvent - */ - public function setIdentity($identity = null) - { - if (null === $identity) { - // Setting the identity to null resets the code and messages. - $this->setCode(); - $this->setMessages(); - } - $this->setParam('identity', $identity); - return $this; - } - - /** - * getCode - * - * @return int - */ - public function getCode() - { - return $this->getParam('code'); - } - - /** - * setCode - * - * @param int $code - * @return AdapterChainEvent - */ - public function setCode($code = null) - { - $this->setParam('code', $code); - return $this; - } - - /** - * getMessages - * - * @return array - */ - public function getMessages() - { - return $this->getParam('messages') ?: array(); - } - - /** - * setMessages - * - * @param array $messages - * @return AdapterChainEvent - */ - public function setMessages($messages = array()) - { - $this->setParam('messages', $messages); - return $this; - } - - /** - * getRequest - * - * @return Request - */ - public function getRequest() - { - return $this->getParam('request'); - } - - /** - * setRequest - * - * @param Request $request - * @return AdapterChainEvent - */ - public function setRequest(Request $request) - { - $this->setParam('request', $request); - $this->request = $request; - return $this; - } -} diff --git a/src/ZfcUser/Authentication/Adapter/AdapterChainServiceFactory.php b/src/ZfcUser/Authentication/Adapter/AdapterChainServiceFactory.php deleted file mode 100644 index cc29a558..00000000 --- a/src/ZfcUser/Authentication/Adapter/AdapterChainServiceFactory.php +++ /dev/null @@ -1,74 +0,0 @@ -getOptions($serviceLocator); - - //iterate and attach multiple adapters and events if offered - foreach ($options->getAuthAdapters() as $priority => $adapterName) { - $adapter = $serviceLocator->get($adapterName); - - if (is_callable(array($adapter, 'authenticate'))) { - $chain->getEventManager()->attach('authenticate', array($adapter, 'authenticate'), $priority); - } - - if (is_callable(array($adapter, 'logout'))) { - $chain->getEventManager()->attach('logout', array($adapter, 'logout'), $priority); - } - } - - return $chain; - } - - - /** - * set options - * - * @param ModuleOptions $options - * @return AdapterChainServiceFactory - */ - public function setOptions(ModuleOptions $options) - { - $this->options = $options; - return $this; - } - - /** - * get options - * - * @param ServiceLocatorInterface $serviceLocator (optional) Service Locator - * @return ModuleOptions $options - * @throws OptionsNotFoundException If options tried to retrieve without being set but no SL was provided - */ - public function getOptions(ServiceLocatorInterface $serviceLocator = null) - { - if (!$this->options) { - if (!$serviceLocator) { - throw new OptionsNotFoundException( - 'Options were tried to retrieve but not set ' . - 'and no service locator was provided' - ); - } - - $this->setOptions($serviceLocator->get('zfcuser_module_options')); - } - - return $this->options; - } -} diff --git a/src/ZfcUser/Authentication/Adapter/ChainableAdapter.php b/src/ZfcUser/Authentication/Adapter/ChainableAdapter.php deleted file mode 100644 index aa8a383f..00000000 --- a/src/ZfcUser/Authentication/Adapter/ChainableAdapter.php +++ /dev/null @@ -1,8 +0,0 @@ -getStorage()->clear(); - } - - public function authenticate(AuthenticationEvent $event) - { - if ($this->isSatisfied()) { - $storage = $this->getStorage()->read(); - $event->setIdentity($storage['identity']) - ->setCode(AuthenticationResult::SUCCESS) - ->setMessages(array('Authentication successful.')); - return; - } - - $identity = $event->getRequest()->getPost()->get('identity'); - $credential = $event->getRequest()->getPost()->get('credential'); - $credential = $this->preProcessCredential($credential); - $userObject = null; - - // Cycle through the configured identity sources and test each - $fields = $this->getOptions()->getAuthIdentityFields(); - while (!is_object($userObject) && count($fields) > 0) { - $mode = array_shift($fields); - switch ($mode) { - case 'username': - $userObject = $this->getMapper()->findByUsername($identity); - break; - case 'email': - $userObject = $this->getMapper()->findByEmail($identity); - break; - } - } - - if (!$userObject) { - $event->setCode(AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND) - ->setMessages(array('A record with the supplied identity could not be found.')); - $this->setSatisfied(false); - return false; - } - - if ($this->getOptions()->getEnableUserState()) { - // Don't allow user to login if state is not in allowed list - if (!in_array($userObject->getState(), $this->getOptions()->getAllowedLoginStates())) { - $event->setCode(AuthenticationResult::FAILURE_UNCATEGORIZED) - ->setMessages(array('A record with the supplied identity is not active.')); - $this->setSatisfied(false); - return false; - } - } - - $cryptoService = $this->getHydrator()->getCryptoService(); - if (!$cryptoService->verify($credential, $userObject->getPassword())) { - // Password does not match - $event->setCode(AuthenticationResult::FAILURE_CREDENTIAL_INVALID) - ->setMessages(array('Supplied credential is invalid.')); - $this->setSatisfied(false); - return false; - } elseif ($cryptoService instanceof Bcrypt) { - // Update user's password hash if the cost parameter has changed - $this->updateUserPasswordHash($userObject, $credential, $cryptoService); - } - - // regen the id - SessionContainer::getDefaultManager()->regenerateId(); - - // Success! - $event->setIdentity($userObject->getId()); - - $this->setSatisfied(true); - $storage = $this->getStorage()->read(); - $storage['identity'] = $event->getIdentity(); - $this->getStorage()->write($storage); - $event->setCode(AuthenticationResult::SUCCESS) - ->setMessages(array('Authentication successful.')); - } - - protected function updateUserPasswordHash(UserEntity $user, $password, Bcrypt $bcrypt) - { - $hash = explode('$', $user->getPassword()); - if ($hash[2] === $bcrypt->getCost()) { - return; - } - $user = $this->getHydrator()->hydrate(compact('password'), $user); - $this->getMapper()->update($user); - } - - public function preprocessCredential($credential) - { - if (is_callable($this->credentialPreprocessor)) { - return call_user_func($this->credentialPreprocessor, $credential); - } - return $credential; - } - - /** - * getMapper - * - * @return UserMapper - */ - public function getMapper() - { - if (!$this->mapper instanceof UserMapper) { - $this->setMapper($this->serviceManager->get('zfcuser_user_mapper')); - } - return $this->mapper; - } - - /** - * setMapper - * - * @param UserMapper $mapper - * @return Db - */ - public function setMapper(UserMapper $mapper) - { - $this->mapper = $mapper; - return $this; - } - - /** - * Lazy-loads a hydrator from the service manager - * - * @return Hydrator - */ - public function getHydrator() - { - if (!$this->hydrator instanceof Hydrator) { - $this->setHydrator($this->serviceManager->get('zfcuser_user_hydrator')); - } - return $this->hydrator; - } - - /** - * Set the hydrator - * - * @param Hydrator $hydrator - */ - public function setHydrator(Hydrator $hydrator) - { - $this->hydrator = $hydrator; - } - - /** - * Get credentialPreprocessor. - * - * @return callable - */ - public function getCredentialPreprocessor() - { - return $this->credentialPreprocessor; - } - - /** - * Set credentialPreprocessor. - * - * @param callable $credentialPreprocessor the value to be set - * @throws InvalidArgumentException when argument is not callable - */ - public function setCredentialPreprocessor($credentialPreprocessor) - { - if (!is_callable($credentialPreprocessor)) { - $message = sprintf( - "Credential Preprocessor must be callable, [%s] given", - gettype($credentialPreprocessor) - ); - throw new InvalidArgumentException($message); - } - $this->credentialPreprocessor = $credentialPreprocessor; - } - - /** - * Retrieve service manager instance - * - * @return ServiceManager - */ - public function getServiceManager() - { - return $this->serviceManager; - } - - /** - * Set service manager instance - * - * @param ServiceManager $locator - * @return void - */ - public function setServiceManager(ServiceManager $serviceManager) - { - $this->serviceManager = $serviceManager; - } - - /** - * @param AuthenticationOptions $options - */ - public function setOptions(AuthenticationOptions $options) - { - $this->options = $options; - } - - /** - * @return AuthenticationOptions - */ - public function getOptions() - { - if (!$this->options instanceof AuthenticationOptions) { - $this->setOptions($this->serviceManager->get('zfcuser_module_options')); - } - return $this->options; - } -} diff --git a/src/ZfcUser/Authentication/Adapter/Exception/OptionsNotFoundException.php b/src/ZfcUser/Authentication/Adapter/Exception/OptionsNotFoundException.php deleted file mode 100644 index 685d053a..00000000 --- a/src/ZfcUser/Authentication/Adapter/Exception/OptionsNotFoundException.php +++ /dev/null @@ -1,10 +0,0 @@ -mapper = $mapper; + $this->mapperMethod = $mapperMethod; + $this->credentialProcessor = $validator; + } + + /** + * @return Result + */ + public function authenticate() + { + $userObject = call_user_func(array($this->mapper, $this->mapperMethod), $this->getIdentity()); + + if (!$userObject instanceof UserEntity) { + return new Result( + Result::FAILURE_IDENTITY_NOT_FOUND, + null, + array('A record with the supplied identity could not be found.') + ); + } + + if (!$this->credentialProcessor->verify($this->getCredential(), $userObject->getPassword())) { + // Password does not match + return new Result( + Result::FAILURE_CREDENTIAL_INVALID, + null, + array('Supplied credential is invalid.') + ); + } + + return new Result( + Result::SUCCESS, + $userObject, + array('Authentication successful.') + ); + } +} diff --git a/src/ZfcUser/Authentication/Listener/RegenerateSessionIdentifier.php b/src/ZfcUser/Authentication/Listener/RegenerateSessionIdentifier.php new file mode 100644 index 00000000..50304188 --- /dev/null +++ b/src/ZfcUser/Authentication/Listener/RegenerateSessionIdentifier.php @@ -0,0 +1,33 @@ +session = $session; + } + + /** + * Regenerate the SID of the session being managed by the + * provided Session Manager + */ + public function __invoke() + { + $this->session->regenerateId(); + } +} diff --git a/src/ZfcUser/Authentication/Storage/Db.php b/src/ZfcUser/Authentication/Storage/Db.php deleted file mode 100644 index 3a5b1d36..00000000 --- a/src/ZfcUser/Authentication/Storage/Db.php +++ /dev/null @@ -1,179 +0,0 @@ -getStorage()->isEmpty()) { - return true; - } - $identity = $this->read(); - if ($identity === null) { - $this->clear(); - return true; - } - - return false; - } - - /** - * Returns the contents of storage - * - * Behavior is undefined when storage is empty. - * - * @throws \Zend\Authentication\Exception\InvalidArgumentException If reading contents from storage is impossible - * @return mixed - */ - public function read() - { - if (null !== $this->resolvedIdentity) { - return $this->resolvedIdentity; - } - - $identity = $this->getStorage()->read(); - - if (is_int($identity) || is_scalar($identity)) { - $identity = $this->getMapper()->findById($identity); - } - - if ($identity) { - $this->resolvedIdentity = $identity; - } else { - $this->resolvedIdentity = null; - } - - return $this->resolvedIdentity; - } - - /** - * Writes $contents to storage - * - * @param mixed $contents - * @throws \Zend\Authentication\Exception\InvalidArgumentException If writing $contents to storage is impossible - * @return void - */ - public function write($contents) - { - $this->resolvedIdentity = null; - $this->getStorage()->write($contents); - } - - /** - * Clears contents from storage - * - * @throws \Zend\Authentication\Exception\InvalidArgumentException If clearing contents from storage is impossible - * @return void - */ - public function clear() - { - $this->resolvedIdentity = null; - $this->getStorage()->clear(); - } - - /** - * getStorage - * - * @return Storage\StorageInterface - */ - public function getStorage() - { - if (null === $this->storage) { - $this->setStorage(new Storage\Session); - } - return $this->storage; - } - - /** - * setStorage - * - * @param Storage\StorageInterface $storage - * @access public - * @return Db - */ - public function setStorage(Storage\StorageInterface $storage) - { - $this->storage = $storage; - return $this; - } - - /** - * getMapper - * - * @return UserMapper - */ - public function getMapper() - { - if (null === $this->mapper) { - $this->mapper = $this->getServiceManager()->get('zfcuser_user_mapper'); - } - return $this->mapper; - } - - /** - * setMapper - * - * @param UserMapper $mapper - * @return Db - */ - public function setMapper(UserMapper $mapper) - { - $this->mapper = $mapper; - return $this; - } - - /** - * Retrieve service manager instance - * - * @return ServiceManager - */ - public function getServiceManager() - { - return $this->serviceManager; - } - - /** - * Set service manager instance - * - * @param ServiceManager $locator - * @return void - */ - public function setServiceManager(ServiceManager $serviceManager) - { - $this->serviceManager = $serviceManager; - } -} diff --git a/src/ZfcUser/Authentication/Storage/Mapper.php b/src/ZfcUser/Authentication/Storage/Mapper.php new file mode 100644 index 00000000..81d22a5d --- /dev/null +++ b/src/ZfcUser/Authentication/Storage/Mapper.php @@ -0,0 +1,111 @@ +mapper = $mapper; + $this->storage = $storage; + } + + /** + * Returns true if and only if storage is empty + * + * @throws \Zend\Authentication\Exception\InvalidArgumentException If it is impossible to determine whether + * storage is empty or not + * @return boolean + */ + public function isEmpty() + { + if ($this->storage->isEmpty()) { + return true; + } + $identity = $this->read(); + if ($identity === null) { + $this->clear(); + return true; + } + + return false; + } + + /** + * Returns the contents of storage as a User entity or null if the + * identifier in storage does not map to an existing user account. + * + * @throws \Zend\Authentication\Exception\InvalidArgumentException If reading contents from storage is impossible + * @return UserEntity|null + */ + public function read() + { + if (null !== $this->resolvedIdentity) { + return $this->resolvedIdentity; + } + + $identity = $this->storage->read(); + + if (is_int($identity) || is_scalar($identity)) { + $identity = $this->mapper->findById($identity); + } + + $this->resolvedIdentity = $identity instanceof UserEntity + ? $identity + : null; + + return $this->resolvedIdentity; + } + + /** + * Writes $contents to storage + * + * @param mixed $contents + * @throws \Zend\Authentication\Exception\InvalidArgumentException If writing $contents to storage is impossible + * @return void + */ + public function write($contents) + { + $this->resolvedIdentity = null; + $this->storage->write($contents); + } + + /** + * Clears contents from storage + * + * @throws \Zend\Authentication\Exception\InvalidArgumentException If clearing contents from storage is impossible + * @return void + */ + public function clear() + { + $this->resolvedIdentity = null; + $this->storage->clear(); + } +} diff --git a/src/ZfcUser/Controller/UserController.php b/src/ZfcUser/Controller/UserController.php index c7811feb..3cd655a1 100644 --- a/src/ZfcUser/Controller/UserController.php +++ b/src/ZfcUser/Controller/UserController.php @@ -124,8 +124,6 @@ public function loginAction() return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_LOGIN).($redirect ? '?redirect='. rawurlencode($redirect) : '')); } - // clear adapters - $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters(); $this->zfcUserAuthentication()->getAuthService()->clearIdentity(); return $this->forward()->dispatch(static::CONTROLLER_NAME, array('action' => 'authenticate')); @@ -136,8 +134,6 @@ public function loginAction() */ public function logoutAction() { - $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters(); - $this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters(); $this->zfcUserAuthentication()->getAuthService()->clearIdentity(); $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false)); @@ -158,21 +154,15 @@ public function authenticateAction() return $this->redirect()->toRoute($this->options->getLoginRedirectRoute()); } - $adapter = $this->zfcUserAuthentication()->getAuthAdapter(); $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false)); - - $result = $adapter->prepareForAuthentication($this->getRequest()); - - // Return early if an adapter returned a response - if ($result instanceof Response) { - return $result; - } + + $adapter = $this->zfcUserAuthentication()->getAuthAdapter(); + $adapter->setIdentity($this->params()->fromPost('identity')); + $adapter->setCredential($this->params()->fromPost('credential')); $auth = $this->zfcUserAuthentication()->getAuthService()->authenticate($adapter); - if (!$auth->isValid()) { $this->flashMessenger()->setNamespace($this->loginNamespace)->addMessage($this->failedLoginMessage); - $adapter->resetAdapters(); return $this->redirect()->toUrl( $this->url()->fromRoute(static::ROUTE_LOGIN) . ($redirect ? '?redirect='. rawurlencode($redirect) : '') diff --git a/src/ZfcUser/Factory/Authentication/Adapter/AdapterChainFactory.php b/src/ZfcUser/Factory/Authentication/Adapter/AdapterChainFactory.php new file mode 100644 index 00000000..3fc13769 --- /dev/null +++ b/src/ZfcUser/Factory/Authentication/Adapter/AdapterChainFactory.php @@ -0,0 +1,21 @@ +get('zfcuser_module_options'); + + $chain = new AdapterChain(); + foreach ($options->getAuthAdapters() as $priority => $adapterName) { + $chain->attach($adapterName, $serviceLocator->get($adapterName), $priority); + } + + return $chain; + } +} diff --git a/src/ZfcUser/Factory/Authentication/Adapter/MapperEmailFactory.php b/src/ZfcUser/Factory/Authentication/Adapter/MapperEmailFactory.php new file mode 100644 index 00000000..f431892f --- /dev/null +++ b/src/ZfcUser/Factory/Authentication/Adapter/MapperEmailFactory.php @@ -0,0 +1,21 @@ +get('zfcuser_user_mapper'), + 'findByEmail', + $serviceLocator->get('zfcuser_authentication_credentialprocessor') + ); + } +} diff --git a/src/ZfcUser/Factory/Authentication/Adapter/MapperUsernameFactory.php b/src/ZfcUser/Factory/Authentication/Adapter/MapperUsernameFactory.php new file mode 100644 index 00000000..acb01473 --- /dev/null +++ b/src/ZfcUser/Factory/Authentication/Adapter/MapperUsernameFactory.php @@ -0,0 +1,21 @@ +get('zfcuser_user_mapper'), + 'findByUsername', + $serviceLocator->get('zfcuser_authentication_credentialprocessor') + ); + } +} diff --git a/src/ZfcUser/Factory/Authentication/CredentialProcessor/BcryptFactory.php b/src/ZfcUser/Factory/Authentication/CredentialProcessor/BcryptFactory.php new file mode 100644 index 00000000..7b9340e0 --- /dev/null +++ b/src/ZfcUser/Factory/Authentication/CredentialProcessor/BcryptFactory.php @@ -0,0 +1,21 @@ +get('zfcuser_module_options'); + + return new Bcrypt(array( + 'cost' => $options->getPasswordCost() + )); + } +} diff --git a/src/ZfcUser/Factory/Authentication/Listener/RegenerateSessionIdentifierFactory.php b/src/ZfcUser/Factory/Authentication/Listener/RegenerateSessionIdentifierFactory.php new file mode 100644 index 00000000..97957182 --- /dev/null +++ b/src/ZfcUser/Factory/Authentication/Listener/RegenerateSessionIdentifierFactory.php @@ -0,0 +1,33 @@ +get('SharedEventManager'); + + $manager = $serviceLocator->has('Zend\Session\ManagerInterface') + ? $serviceLocator->get('Zend\Session\ManagerInterface') + : Container::getDefaultManager(); + + // Attach listener to regenerate SID before authentication occurs + $sem->attach( + 'ZfcUser\Authentication\Adapter\AdapterChain', + 'authenticate.pre', + new RegenerateSessionIdentifier($manager) + ); + + return $sessionStorage; + } +} diff --git a/src/ZfcUser/Factory/Authentication/Storage/MapperFactory.php b/src/ZfcUser/Factory/Authentication/Storage/MapperFactory.php new file mode 100644 index 00000000..1e278450 --- /dev/null +++ b/src/ZfcUser/Factory/Authentication/Storage/MapperFactory.php @@ -0,0 +1,20 @@ +get('zfcuser_user_mapper'), + $serviceLocator->get('zfcuser_authentication_storage_backend') + ); + } +} diff --git a/src/ZfcUser/Factory/AuthenticationServiceFactory.php b/src/ZfcUser/Factory/AuthenticationServiceFactory.php index a38afcf5..a50d046a 100644 --- a/src/ZfcUser/Factory/AuthenticationServiceFactory.php +++ b/src/ZfcUser/Factory/AuthenticationServiceFactory.php @@ -15,7 +15,7 @@ class AuthenticationServiceFactory implements FactoryInterface public function createService(ServiceLocatorInterface $serviceLocator) { /* @var $authStorage Storage\StorageInterface */ - $authStorage = $serviceLocator->get('ZfcUser\Authentication\Storage\Db'); + $authStorage = $serviceLocator->get('zfcuser_authentication_storage'); /* @var $authAdapter Adapter\AdapterInterface */ $authAdapter = $serviceLocator->get('ZfcUser\Authentication\Adapter\AdapterChain'); diff --git a/src/ZfcUser/Options/ModuleOptions.php b/src/ZfcUser/Options/ModuleOptions.php index 5643ddf9..78ec1f3b 100644 --- a/src/ZfcUser/Options/ModuleOptions.php +++ b/src/ZfcUser/Options/ModuleOptions.php @@ -59,7 +59,7 @@ class ModuleOptions extends AbstractOptions implements UserControllerOptionsInte /** * @var array */ - protected $authAdapters = array( 100 => 'ZfcUser\Authentication\Adapter\Db' ); + protected $authAdapters = array( 100 => 'ZfcUser\Authentication\Adapter\Mapper' ); /** * @var array diff --git a/tests/ZfcUserTest/Authentication/Adapter/AbstractAdapterTest.php b/tests/ZfcUserTest/Authentication/Adapter/AbstractAdapterTest.php deleted file mode 100644 index fbc27959..00000000 --- a/tests/ZfcUserTest/Authentication/Adapter/AbstractAdapterTest.php +++ /dev/null @@ -1,63 +0,0 @@ -adapter = $adapter; - } - - /** - * @covers ZfcUser\Authentication\Adapter\AbstractAdapter::getStorage - */ - public function testGetStorageWithoutStorageSet() - { - $this->assertInstanceOf('Zend\Authentication\Storage\Session', $this->adapter->getStorage()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\AbstractAdapter::getStorage - * @covers ZfcUser\Authentication\Adapter\AbstractAdapter::setStorage - */ - public function testSetGetStorage() - { - $storage = new \Zend\Authentication\Storage\Session('ZfcUser'); - $storage->write('zfcUser'); - $this->adapter->setStorage($storage); - - $this->assertInstanceOf('Zend\Authentication\Storage\Session', $this->adapter->getStorage()); - $this->assertSame('zfcUser', $this->adapter->getStorage()->read()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\AbstractAdapter::isSatisfied - */ - public function testIsSatisfied() - { - $this->assertFalse($this->adapter->isSatisfied()); - } - - public function testSetSatisfied() - { - $result = $this->adapter->setSatisfied(); - $this->assertInstanceOf('ZfcUser\Authentication\Adapter\AbstractAdapter', $result); - $this->assertTrue($this->adapter->isSatisfied()); - - $result = $this->adapter->setSatisfied(false); - $this->assertInstanceOf('ZfcUser\Authentication\Adapter\AbstractAdapter', $result); - $this->assertFalse($this->adapter->isSatisfied()); - } -} diff --git a/tests/ZfcUserTest/Authentication/Adapter/AdapterChainEventTest.php b/tests/ZfcUserTest/Authentication/Adapter/AdapterChainEventTest.php deleted file mode 100644 index 95153032..00000000 --- a/tests/ZfcUserTest/Authentication/Adapter/AdapterChainEventTest.php +++ /dev/null @@ -1,76 +0,0 @@ -event = new AdapterChainEvent(); - } - - /** - * @covers \ZfcUser\Authentication\Adapter\AdapterChainEvent::getCode - * @covers \ZfcUser\Authentication\Adapter\AdapterChainEvent::setCode - * @covers \ZfcUser\Authentication\Adapter\AdapterChainEvent::getMessages - * @covers \ZfcUser\Authentication\Adapter\AdapterChainEvent::setMessages - */ - public function testCodeAndMessages() - { - $testCode = 103; - $testMessages = array('Message recieved loud and clear.'); - - $this->event->setCode($testCode); - $this->assertEquals($testCode, $this->event->getCode(), "Asserting code values match."); - - $this->event->setMessages($testMessages); - $this->assertEquals($testMessages, $this->event->getMessages(), "Asserting messages values match."); - } - - /** - * @depends testCodeAndMessages - * @covers \ZfcUser\Authentication\Adapter\AdapterChainEvent::getIdentity - * @covers \ZfcUser\Authentication\Adapter\AdapterChainEvent::setIdentity - */ - public function testIdentity() - { - $testCode = 123; - $testMessages = array('The message.'); - $testIdentity = 'the_user'; - - $this->event->setCode($testCode); - $this->event->setMessages($testMessages); - - $this->event->setIdentity($testIdentity); - - $this->assertEquals($testCode, $this->event->getCode(), "Asserting the code persisted."); - $this->assertEquals($testMessages, $this->event->getMessages(), "Asserting the messages persisted."); - $this->assertEquals($testIdentity, $this->event->getIdentity(), "Asserting the identity matches"); - - $this->event->setIdentity(); - - $this->assertNull($this->event->getCode(), "Asserting the code has been cleared."); - $this->assertEquals(array(), $this->event->getMessages(), "Asserting the messages have been cleared."); - $this->assertNull($this->event->getIdentity(), "Asserting the identity has been cleared"); - } - - public function testRequest() - { - $request = $this->getMock('Zend\Stdlib\RequestInterface'); - $this->event->setRequest($request); - - $this->assertInstanceOf('Zend\Stdlib\RequestInterface', $this->event->getRequest()); - } -} diff --git a/tests/ZfcUserTest/Authentication/Adapter/AdapterChainServiceFactoryTest.php b/tests/ZfcUserTest/Authentication/Adapter/AdapterChainServiceFactoryTest.php deleted file mode 100644 index c92fcd00..00000000 --- a/tests/ZfcUserTest/Authentication/Adapter/AdapterChainServiceFactoryTest.php +++ /dev/null @@ -1,134 +0,0 @@ -serviceLocatorArray[$index]; - } - - /** - * Prepare the object to be tested. - */ - protected function setUp() - { - $this->serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); - - $this->options = $this->getMockBuilder('ZfcUser\Options\ModuleOptions') - ->disableOriginalConstructor() - ->getMock(); - - $this->serviceLocatorArray = array ( - 'zfcuser_module_options'=>$this->options - ); - - $this->serviceLocator->expects($this->any()) - ->method('get') - ->will($this->returnCallback(array($this,'helperServiceLocator'))); - - $this->eventManager = $this->getMock('Zend\EventManager\EventManager'); - - $this->factory = new AdapterChainServiceFactory(); - } - - /** - * @covers \ZfcUser\Authentication\Adapter\AdapterChainServiceFactory::createService - */ - public function testCreateService() - { - $adapter = array( - 'adapter1'=> $this->getMock( - 'ZfcUser\Authentication\Adapter\AbstractAdapter', - array('authenticate', 'logout') - ), - 'adapter2'=> $this->getMock( - 'ZfcUser\Authentication\Adapter\AbstractAdapter', - array('authenticate', 'logout') - ) - ); - $adapterNames = array(100=>'adapter1', 200=>'adapter2'); - - $this->serviceLocatorArray = array_merge($this->serviceLocatorArray, $adapter); - - $this->options->expects($this->once()) - ->method('getAuthAdapters') - ->will($this->returnValue($adapterNames)); - - $adapterChain = $this->factory->createService($this->serviceLocator); - - $this->assertInstanceOf('ZfcUser\Authentication\Adapter\AdapterChain', $adapterChain); - $this->assertEquals(array('authenticate', 'logout'), $adapterChain->getEventManager()->getEvents()); - } - - /** - * @covers \ZfcUser\Authentication\Adapter\AdapterChainServiceFactory::setOptions - * @covers \ZfcUser\Authentication\Adapter\AdapterChainServiceFactory::getOptions - */ - public function testGetOptionWithSetter() - { - $this->factory->setOptions($this->options); - - $options = $this->factory->getOptions(); - - $this->assertInstanceOf('ZfcUser\Options\ModuleOptions', $options); - $this->assertSame($this->options, $options); - - - $options2 = clone $this->options; - $this->factory->setOptions($options2); - $options = $this->factory->getOptions(); - - $this->assertInstanceOf('ZfcUser\Options\ModuleOptions', $options); - $this->assertNotSame($this->options, $options); - $this->assertSame($options2, $options); - } - - /** - * @covers \ZfcUser\Authentication\Adapter\AdapterChainServiceFactory::getOptions - */ - public function testGetOptionWithLocator() - { - $options = $this->factory->getOptions($this->serviceLocator); - - $this->assertInstanceOf('ZfcUser\Options\ModuleOptions', $options); - $this->assertSame($this->options, $options); - } - - /** - * @covers \ZfcUser\Authentication\Adapter\AdapterChainServiceFactory::getOptions - * @expectedException \ZfcUser\Authentication\Adapter\Exception\OptionsNotFoundException - */ - public function testGetOptionFailing() - { - $options = $this->factory->getOptions(); - } -} diff --git a/tests/ZfcUserTest/Authentication/Adapter/AdapterChainTest.php b/tests/ZfcUserTest/Authentication/Adapter/AdapterChainTest.php index 6e564744..fb4601dd 100644 --- a/tests/ZfcUserTest/Authentication/Adapter/AdapterChainTest.php +++ b/tests/ZfcUserTest/Authentication/Adapter/AdapterChainTest.php @@ -2,9 +2,8 @@ namespace ZfcUserTest\Authentication\Adapter; -use Zend\EventManager\EventManagerInterface; use ZfcUser\Authentication\Adapter\AdapterChain; -use ZfcUser\Authentication\Adapter\AdapterChainEvent; +use Zend\Authentication\Result; class AdapterChainTest extends \PHPUnit_Framework_TestCase { @@ -15,297 +14,149 @@ class AdapterChainTest extends \PHPUnit_Framework_TestCase */ protected $adapterChain; - /** - * Mock event manager. - * - * @var EventManagerInterface - */ - protected $eventManager; - - /** - * For tests where an event is required. - * - * @var \Zend\EventManager\EventInterface - */ - protected $event; - - /** - * Used when testing prepareForAuthentication. - * - * @var \Zend\Stdlib\RequestInterface - */ - protected $request; - /** * Prepare the objects to be tested. */ protected function setUp() { - $this->event = null; - $this->request = null; - $this->adapterChain = new AdapterChain(); - - $this->eventManager = $this->getMock('Zend\EventManager\EventManagerInterface'); - $this->adapterChain->setEventManager($this->eventManager); + $this->adapterChain->setIdentity('identity'); + $this->adapterChain->setCredential('credential'); } - /** - * @covers ZfcUser\Authentication\Adapter\AdapterChain::authenticate - */ - public function testAuthenticate() + public function testAttachTriggersEvent() { - $event = $this->getMock('ZfcUser\Authentication\Adapter\AdapterChainEvent'); - $event->expects($this->once()) - ->method('getCode') - ->will($this->returnValue(123)); - $event->expects($this->once()) - ->method('getIdentity') - ->will($this->returnValue('identity')); - $event->expects($this->once()) - ->method('getMessages') - ->will($this->returnValue(array())); - - $this->eventManager->expects($this->once()) - ->method('getListeners') - ->with($this->equalTo('authenticate')) - ->will($this->returnValue(array())); + $adapter1 = $this->getMockForAbstractClass('Zend\Authentication\Adapter\AbstractAdapter'); + + $triggerCount = 0; + $this->adapterChain->getEventManager()->attach('attach', function ($e) use ($adapter1, &$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertArrayHasKey('name', $e->getParams()); + $this->assertEquals('adapter1', $e->getParam('name')); + $this->assertArrayHasKey('adapter', $e->getParams()); + $this->assertSame($adapter1, $e->getParam('adapter')); + $this->assertArrayHasKey('priority', $e->getParams()); + $this->assertEquals(29, $e->getParam('priority')); + $triggerCount++; + }); + + $this->adapterChain->attach('adapter1', $adapter1, 29); + $this->assertEquals(1, $triggerCount); + } - $this->adapterChain->setEvent($event); + public function testAuthenticateWithNoAdaptersReturnsUncategorizedFailure() + { $result = $this->adapterChain->authenticate(); $this->assertInstanceOf('Zend\Authentication\Result', $result); - $this->assertEquals($result->getIdentity(), 'identity'); + $this->assertEquals(Result::FAILURE_UNCATEGORIZED, $result->getCode()); + $this->assertEquals($result->getIdentity(), null); $this->assertEquals($result->getMessages(), array()); } - /** - * @covers ZfcUser\Authentication\Adapter\AdapterChain::resetAdapters - */ - public function testResetAdapters() - { - $listeners = array(); - - for ($i=1; $i<=3; $i++) { - $storage = $this->getMock('ZfcUser\Authentication\Storage\Db'); - $storage->expects($this->once()) - ->method('clear'); - - $adapter = $this->getMock('ZfcUser\Authentication\Adapter\AbstractAdapter'); - $adapter->expects($this->once()) - ->method('getStorage') - ->will($this->returnValue($storage)); - - $callback = $this->getMockBuilder('Zend\Stdlib\CallbackHandler')->disableOriginalConstructor()->getMock(); - $callback->expects($this->once()) - ->method('getCallback') - ->will($this->returnValue(array($adapter))); - - $listeners[] = $callback; - } - - $this->eventManager->expects($this->once()) - ->method('getListeners') - ->with($this->equalTo('authenticate')) - ->will($this->returnValue($listeners)); - - $result = $this->adapterChain->resetAdapters(); - - $this->assertInstanceOf('ZfcUser\Authentication\Adapter\AdapterChain', $result); - } - - /** - * Get through the first part of SetUpPrepareForAuthentication - */ - protected function setUpPrepareForAuthentication() + public function testAuthenticateWithZeroAdapterMatchesReturnsLastAdapterResult() { - $this->request = $this->getMock('Zend\Stdlib\RequestInterface'); - $this->event = $this->getMock('ZfcUser\Authentication\Adapter\AdapterChainEvent'); - - $this->event->expects($this->once())->method('setRequest')->with($this->request); - - $this->eventManager->expects($this->at(0))->method('trigger')->with('authenticate.pre'); - - /** - * @var $response Zend\EventManager\ResponseCollection - */ - $responses = $this->getMock('Zend\EventManager\ResponseCollection'); - - $this->eventManager->expects($this->at(1)) - ->method('trigger') - ->with('authenticate', $this->event) - ->will($this->returnCallback(function ($event, $target, $callback) use ($responses) { - if (call_user_func($callback, $responses->last())) { - $responses->setStopped(true); - } - return $responses; - })); - - $this->adapterChain->setEvent($this->event); - - return $responses; - } - - /** - * Provider for testPrepareForAuthentication() - * - * @return array - */ - public function identityProvider() - { - return array( - array(true, true), - array(false, false), - ); - } - - /** - * Tests prepareForAuthentication when falls through events. - * - * @param mixed $identity - * @param bool $expected - * - * @dataProvider identityProvider - * @covers ZfcUser\Authentication\Adapter\AdapterChain::prepareForAuthentication - */ - public function testPrepareForAuthentication($identity, $expected) - { - $result = $this->setUpPrepareForAuthentication(); - - $result->expects($this->once())->method('stopped')->will($this->returnValue(false)); - - $this->event->expects($this->once())->method('getIdentity')->will($this->returnValue($identity)); - - $this->assertEquals( - $expected, - $this->adapterChain->prepareForAuthentication($this->request), - 'Asserting prepareForAuthentication() returns true' - ); - } - - /** - * Test prepareForAuthentication() when the returned collection contains stopped. - * - * @covers ZfcUser\Authentication\Adapter\AdapterChain::prepareForAuthentication - */ - public function testPrepareForAuthenticationWithStoppedEvent() - { - $result = $this->setUpPrepareForAuthentication(); - - $result->expects($this->once())->method('stopped')->will($this->returnValue(true)); - - $lastResponse = $this->getMock('Zend\Stdlib\ResponseInterface'); - $result->expects($this->atLeastOnce())->method('last')->will($this->returnValue($lastResponse)); - - $this->assertEquals( - $lastResponse, - $this->adapterChain->prepareForAuthentication($this->request), - 'Asserting the Response returned from the event is returned' - ); - } - - /** - * Test prepareForAuthentication() when the returned collection contains stopped. - * - * @covers ZfcUser\Authentication\Adapter\AdapterChain::prepareForAuthentication - * @expectedException ZfcUser\Exception\AuthenticationEventException - */ - public function testPrepareForAuthenticationWithBadEventResult() - { - $result = $this->setUpPrepareForAuthentication(); - - $result->expects($this->once())->method('stopped')->will($this->returnValue(true)); - - $lastResponse = 'random-value'; - $result->expects($this->atLeastOnce())->method('last')->will($this->returnValue($lastResponse)); - - $this->adapterChain->prepareForAuthentication($this->request); - } - - /** - * Test getEvent() when no event has previously been set. - * - * @covers ZfcUser\Authentication\Adapter\AdapterChain::getEvent - */ - public function testGetEventWithNoEventSet() - { - $event = $this->adapterChain->getEvent(); + $result1 = new Result(Result::FAILURE_IDENTITY_NOT_FOUND, null); + $adapter1 = $this->getMockForAbstractClass('Zend\Authentication\Adapter\AbstractAdapter'); + $adapter1->expects($this->once())->method('authenticate')->will($this->returnValue($result1)); + $this->adapterChain->attach('adapter1', $adapter1); + + $result2 = new Result(Result::FAILURE_IDENTITY_NOT_FOUND, null); + $adapter2 = $this->getMockForAbstractClass('Zend\Authentication\Adapter\AbstractAdapter'); + $adapter2->expects($this->once())->method('authenticate')->will($this->returnValue($result2)); + $this->adapterChain->attach('adapter2', $adapter2); + + $result = $this->adapterChain->authenticate(); - $this->assertInstanceOf( - 'ZfcUser\Authentication\Adapter\AdapterChainEvent', - $event, - 'Asserting the adapter in an instance of ZfcUser\Authentication\Adapter\AdapterChainEvent' - ); - $this->assertEquals( - $this->adapterChain, - $event->getTarget(), - 'Asserting the Event target is the AdapterChain' - ); + $this->assertSame($result2, $result); + $this->assertEquals(Result::FAILURE_IDENTITY_NOT_FOUND, $result->getCode()); + $this->assertEquals($result->getIdentity(), null); + $this->assertEquals($result->getMessages(), array()); } - - /** - * Test getEvent() when an event has previously been set. - * - * @covers ZfcUser\Authentication\Adapter\AdapterChain::setEvent - * @covers ZfcUser\Authentication\Adapter\AdapterChain::getEvent - */ - public function testGetEventWithEventSet() + + public function testAuthenticateTriggersEventsOnFailure() { - $event = new \ZfcUser\Authentication\Adapter\AdapterChainEvent(); - - $this->adapterChain->setEvent($event); - - $this->assertEquals( - $event, - $this->adapterChain->getEvent(), - 'Asserting the event fetched is the same as the event set' - ); + $em = $this->adapterChain->getEventManager(); + + $triggerCount['pre'] = 0; + $em->attach('authenticate.pre', function ($e) use (&$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertEmpty($e->getParams()); + $triggerCount['pre']++; + }); + + $triggerCount['success'] = 0; + $em->attach('authenticate.success', function ($e) use (&$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertArrayHasKey('adapter', $e->getParams()); + $this->assertArrayHasKey('result', $e->getParams()); + $triggerCount['success']++; + }); + + $triggerCount['failure'] = 0; + $em->attach('authenticate.failure', function ($e) use (&$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertArrayHasKey('result', $e->getParams()); + $triggerCount['failure']++; + }); + + $this->testAuthenticateWithZeroAdapterMatchesReturnsLastAdapterResult(); + $this->assertEquals(1, $triggerCount['pre']); + $this->assertEquals(0, $triggerCount['success']); + $this->assertEquals(1, $triggerCount['failure']); } - + /** - * Tests the mechanism for casting one event type to AdapterChainEvent - * - * @covers ZfcUser\Authentication\Adapter\AdapterChain::setEvent + * Also enforces FIFO behavior of AdapterChain (If LIFO, adapter2 would execute first) */ - public function testSetEventWithDifferentEventType() + public function testAuthenticateWithAdapterMatchReturnsSuccessfulAdapterResult() { - $testParams = array('testParam' => 'testValue'); - - $event = new \Zend\EventManager\Event; - $event->setParams($testParams); - - $this->adapterChain->setEvent($event); - $returnEvent = $this->adapterChain->getEvent(); - - $this->assertInstanceOf( - 'ZfcUser\Authentication\Adapter\AdapterChainEvent', - $returnEvent, - 'Asserting the adapter in an instance of ZfcUser\Authentication\Adapter\AdapterChainEvent' - ); + $result1 = new Result(Result::SUCCESS, $this->adapterChain->getIdentity()); + $adapter1 = $this->getMockForAbstractClass('Zend\Authentication\Adapter\AbstractAdapter'); + $adapter1->expects($this->once())->method('authenticate')->will($this->returnValue($result1)); + $this->adapterChain->attach('adapter1', $adapter1); + + $adapter2 = $this->getMockForAbstractClass('Zend\Authentication\Adapter\AbstractAdapter'); + $adapter2->expects($this->never())->method('authenticate'); + $this->adapterChain->attach('adapter2', $adapter2); + + $result = $this->adapterChain->authenticate(); - $this->assertEquals( - $testParams, - $returnEvent->getParams(), - 'Asserting event parameters match' - ); + $this->assertSame($result1, $result); + $this->assertEquals(Result::SUCCESS, $result->getCode()); + $this->assertEquals($result->getIdentity(), $this->adapterChain->getIdentity()); + $this->assertEquals($result->getMessages(), array()); } - /** - * Test the logoutAdapters method. - * - * @depends testGetEventWithEventSet - * @covers ZfcUser\Authentication\Adapter\AdapterChain::logoutAdapters - */ - public function testLogoutAdapters() + public function testAuthenticateTriggersEventsOnSuccess() { - $event = new AdapterChainEvent(); - - $this->eventManager - ->expects($this->once()) - ->method('trigger') - ->with('logout', $event); - - $this->adapterChain->setEvent($event); - $this->adapterChain->logoutAdapters(); + $em = $this->adapterChain->getEventManager(); + + $triggerCount['pre'] = 0; + $em->attach('authenticate.pre', function ($e) use (&$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertEmpty($e->getParams()); + $triggerCount['pre']++; + }); + + $triggerCount['success'] = 0; + $em->attach('authenticate.success', function ($e) use (&$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertArrayHasKey('adapter', $e->getParams()); + $this->assertArrayHasKey('result', $e->getParams()); + $triggerCount['success']++; + }); + + $triggerCount['failure'] = 0; + $em->attach('authenticate.failure', function ($e) use (&$triggerCount) { + $this->assertSame($this->adapterChain, $e->getTarget()); + $this->assertArrayHasKey('result', $e->getParams()); + $triggerCount['failure']++; + }); + + $this->testAuthenticateWithAdapterMatchReturnsSuccessfulAdapterResult(); + $this->assertEquals(1, $triggerCount['pre']); + $this->assertEquals(1, $triggerCount['success']); + $this->assertEquals(0, $triggerCount['failure']); } } diff --git a/tests/ZfcUserTest/Authentication/Adapter/DbTest.php b/tests/ZfcUserTest/Authentication/Adapter/DbTest.php deleted file mode 100644 index 5d8b3e69..00000000 --- a/tests/ZfcUserTest/Authentication/Adapter/DbTest.php +++ /dev/null @@ -1,564 +0,0 @@ -options = $this->getMock('ZfcUser\Options\ModuleOptions'); - $this->mapper = $this->getMockForAbstractClass( - 'ZfcUser\Mapper\UserInterface' - ); - $this->user = $this->getMockForAbstractClass( - 'ZfcUser\Entity\UserInterface' - ); - $this->storage = $this->getMockForAbstractClass( - 'Zend\Authentication\Storage\StorageInterface' - ); - $this->authEvent = $this->getMock( - 'ZfcUser\Authentication\Adapter\AdapterChainEvent' - ); - - $this->bcrypt = $this->getMock('Zend\Crypt\Password\Bcrypt'); - $this->hydrator = $this->getMockForAbstractClass( - 'ZfcUser\Mapper\HydratorInterface' - ); - $this->hydrator->expects($this->any()) - ->method('getCryptoService') - ->will($this->returnValue($this->bcrypt)); - - $this->services = $this->getMock('Zend\ServiceManager\ServiceManager'); - $this->services->expects($this->any()) - ->method('get') - ->will($this->returnValueMap(array( - array('zfcuser_module_options', true, $this->options), - array('zfcuser_user_mapper', true, $this->mapper), - array('zfcuser_user_hydrator', true, $this->hydrator), - ))); - - $this->db = new Db; - $this->db->setServiceManager($this->services); - $this->db->setStorage($this->storage); - - $sessionManager = $this->getMock('Zend\Session\SessionManager'); - \Zend\Session\AbstractContainer::setDefaultManager($sessionManager); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::logout - */ - public function testLogout() - { - $this->storage->expects($this->once())->method('clear'); - $this->db->logout($this->authEvent); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::Authenticate - */ - public function testAuthenticateWhenSatisfies() - { - $this->authEvent->expects($this->once()) - ->method('setIdentity') - ->with('ZfcUser') - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setCode') - ->with(\Zend\Authentication\Result::SUCCESS) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setMessages') - ->with(array('Authentication successful.')) - ->will($this->returnValue($this->authEvent)); - - $this->storage->expects($this->at(0)) - ->method('read') - ->will($this->returnValue(array('is_satisfied' => true))); - $this->storage->expects($this->at(1)) - ->method('read') - ->will($this->returnValue(array('identity' => 'ZfcUser'))); - - $result = $this->db->authenticate($this->authEvent); - $this->assertNull($result); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::Authenticate - */ - public function testAuthenticateNoUserObject() - { - $this->setAuthenticationCredentials(); - - $this->options->expects($this->once()) - ->method('getAuthIdentityFields') - ->will($this->returnValue(array())); - - $this->authEvent->expects($this->once()) - ->method('setCode') - ->with(\Zend\Authentication\Result::FAILURE_IDENTITY_NOT_FOUND) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once(1)) - ->method('setMessages') - ->with(array('A record with the supplied identity could not be found.')) - ->will($this->returnValue($this->authEvent)); - - $result = $this->db->authenticate($this->authEvent); - - $this->assertFalse($result); - $this->assertFalse($this->db->isSatisfied()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::Authenticate - */ - public function testAuthenticationUserStateEnabledUserButUserStateNotInArray() - { - $this->setAuthenticationCredentials(); - $this->setAuthenticationUser(); - - $this->options->expects($this->once()) - ->method('getEnableUserState') - ->will($this->returnValue(true)); - $this->options->expects($this->once()) - ->method('getAllowedLoginStates') - ->will($this->returnValue(array(2, 3))); - - $this->authEvent->expects($this->once()) - ->method('setCode') - ->with(\Zend\Authentication\Result::FAILURE_UNCATEGORIZED) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setMessages') - ->with(array('A record with the supplied identity is not active.')) - ->will($this->returnValue($this->authEvent)); - - $this->user->expects($this->once()) - ->method('getState') - ->will($this->returnValue(1)); - - $result = $this->db->authenticate($this->authEvent); - - $this->assertFalse($result); - $this->assertFalse($this->db->isSatisfied()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::Authenticate - */ - public function testAuthenticateWithWrongPassword() - { - $this->setAuthenticationCredentials(); - $this->setAuthenticationUser(); - - $this->options->expects($this->once()) - ->method('getEnableUserState') - ->will($this->returnValue(false)); - - $this->bcrypt->expects($this->once()) - ->method('verify') - ->will($this->returnValue(false)); - - $this->authEvent->expects($this->once()) - ->method('setCode') - ->with(\Zend\Authentication\Result::FAILURE_CREDENTIAL_INVALID) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once(1)) - ->method('setMessages') - ->with(array('Supplied credential is invalid.')); - - $result = $this->db->authenticate($this->authEvent); - - $this->assertFalse($result); - $this->assertFalse($this->db->isSatisfied()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::Authenticate - */ - public function testAuthenticationAuthenticatesWithEmail() - { - $this->setAuthenticationCredentials('zfc-user@zf-commons.io'); - $this->setAuthenticationEmail(); - - $this->options->expects($this->once()) - ->method('getEnableUserState') - ->will($this->returnValue(false)); - - $this->bcrypt->expects($this->once()) - ->method('verify') - ->will($this->returnValue(true)); - $this->bcrypt->expects($this->any()) - ->method('getCost') - ->will($this->returnValue(static::PASSWORD_COST_04)); - - $this->user->expects($this->exactly(2)) - ->method('getPassword') - ->will($this->returnValue('$2a$04$5kq1mnYWbww8X.rIj7eOVOHXtvGw/peefjIcm0lDGxRTEjm9LnOae')); - $this->user->expects($this->once()) - ->method('getId') - ->will($this->returnValue(1)); - - $this->storage->expects($this->any()) - ->method('getNameSpace') - ->will($this->returnValue('test')); - - $this->authEvent->expects($this->once()) - ->method('setIdentity') - ->with(1) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setCode') - ->with(\Zend\Authentication\Result::SUCCESS) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setMessages') - ->with(array('Authentication successful.')) - ->will($this->returnValue($this->authEvent)); - - $result = $this->db->authenticate($this->authEvent); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::Authenticate - */ - public function testAuthenticationAuthenticates() - { - $this->setAuthenticationCredentials(); - $this->setAuthenticationUser(); - - $this->options->expects($this->once()) - ->method('getEnableUserState') - ->will($this->returnValue(true)); - - $this->options->expects($this->once()) - ->method('getAllowedLoginStates') - ->will($this->returnValue(array(1, 2, 3))); - - $this->bcrypt->expects($this->once()) - ->method('verify') - ->will($this->returnValue(true)); - $this->bcrypt->expects($this->any()) - ->method('getCost') - ->will($this->returnValue(static::PASSWORD_COST_04)); - - $this->user->expects($this->exactly(2)) - ->method('getPassword') - ->will($this->returnValue('$2a$04$5kq1mnYWbww8X.rIj7eOVOHXtvGw/peefjIcm0lDGxRTEjm9LnOae')); - $this->user->expects($this->once()) - ->method('getId') - ->will($this->returnValue(1)); - $this->user->expects($this->once()) - ->method('getState') - ->will($this->returnValue(1)); - - $this->storage->expects($this->any()) - ->method('getNameSpace') - ->will($this->returnValue('test')); - - $this->authEvent->expects($this->once()) - ->method('setIdentity') - ->with(1) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setCode') - ->with(\Zend\Authentication\Result::SUCCESS) - ->will($this->returnValue($this->authEvent)); - $this->authEvent->expects($this->once()) - ->method('setMessages') - ->with(array('Authentication successful.')) - ->will($this->returnValue($this->authEvent)); - - $result = $this->db->authenticate($this->authEvent); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::updateUserPasswordHash - */ - public function testUpdateUserPasswordHashWithSameCost() - { - $this->user->expects($this->once()) - ->method('getPassword') - ->will($this->returnValue('$2a$10$x05G2P803MrB3jaORBXBn.QHtiYzGQOBjQ7unpEIge.Mrz6c3KiVm')); - - $this->bcrypt->expects($this->once()) - ->method('getCost') - ->will($this->returnValue(static::PASSWORD_COST_10)); - - $this->hydrator->expects($this->never())->method('hydrate'); - $this->mapper->expects($this->never())->method('update'); - - $method = new \ReflectionMethod( - 'ZfcUser\Authentication\Adapter\Db', - 'updateUserPasswordHash' - ); - $method->setAccessible(true); - $method->invoke($this->db, $this->user, 'ZfcUser', $this->bcrypt); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::updateUserPasswordHash - */ - public function testUpdateUserPasswordHashWithoutSameCost() - { - $this->user->expects($this->once()) - ->method('getPassword') - ->will($this->returnValue('$2a$10$x05G2P803MrB3jaORBXBn.QHtiYzGQOBjQ7unpEIge.Mrz6c3KiVm')); - - $this->bcrypt->expects($this->once()) - ->method('getCost') - ->will($this->returnValue(static::PASSWORD_COST_04)); - - $this->hydrator->expects($this->once()) - ->method('hydrate') - ->with(array('password' => 'ZfcUserNew'), $this->user) - ->will($this->returnValue($this->user)); - - $this->mapper->expects($this->once()) - ->method('update') - ->with($this->user); - - $method = new \ReflectionMethod( - 'ZfcUser\Authentication\Adapter\Db', - 'updateUserPasswordHash' - ); - $method->setAccessible(true); - $method->invoke($this->db, $this->user, 'ZfcUserNew', $this->bcrypt); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::getCredentialPreprocessor - * @covers ZfcUser\Authentication\Adapter\Db::setCredentialPreprocessor - */ - public function testSetValidPreprocessCredential() - { - $callable = function () { - // no-op - }; - $this->db->setCredentialPreprocessor($callable); - $this->assertSame($callable, $this->db->getCredentialPreprocessor()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::setCredentialPreprocessor - * @expectedException InvalidArgumentException - * @expectedExceptionMessage Credential Preprocessor must be callable, [boolean] given - */ - public function testSetInvalidPreprocessCredential() - { - $this->db->setCredentialPreprocessor(false); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::preprocessCredential - * @covers ZfcUser\Authentication\Adapter\Db::setCredentialPreprocessor - */ - public function testPreprocessCredentialWithCallable() - { - $expected = 'processed'; - $this->db->setCredentialPreprocessor(function ($credential) use ($expected) { - return $expected; - }); - $this->assertSame($expected, $this->db->preprocessCredential('ZfcUser')); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::preprocessCredential - */ - public function testPreprocessCredentialWithoutCallable() - { - $this->assertSame('zfcUser', $this->db->preprocessCredential('zfcUser')); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::getServiceManager - * @covers ZfcUser\Authentication\Adapter\Db::setServiceManager - */ - public function testGetServiceManager() - { - $this->assertSame($this->services, $this->db->getServiceManager()); - } - - /** - * @depends testGetServiceManager - * @covers ZfcUser\Authentication\Adapter\Db::getOptions - */ - public function testLazyLoadOptions() - { - $this->assertEquals($this->options, $this->db->getOptions()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::setOptions - * @covers ZfcUser\Authentication\Adapter\Db::getOptions - */ - public function testSetOptions() - { - $options = new \ZfcUser\Options\ModuleOptions; - $options->setLoginRedirectRoute('zfcUser'); - - $this->db->setOptions($options); - - $this->assertInstanceOf('ZfcUser\Options\ModuleOptions', $this->db->getOptions()); - $this->assertSame('zfcUser', $this->db->getOptions()->getLoginRedirectRoute()); - } - - /** - * @depends testGetServiceManager - * @covers ZfcUser\Authentication\Adapter\Db::getMapper - */ - public function testLazyLoadMapper() - { - $this->assertEquals($this->mapper, $this->db->getMapper()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::setMapper - * @covers ZfcUser\Authentication\Adapter\Db::getMapper - */ - public function testSetMapper() - { - $mapper = new \ZfcUser\Mapper\User; - $mapper->setTableName('zfcUser'); - - $this->db->setMapper($mapper); - - $this->assertInstanceOf('ZfcUser\Mapper\User', $this->db->getMapper()); - $this->assertSame('zfcUser', $this->db->getMapper()->getTableName()); - } - - /** - * @depends testGetServiceManager - * @covers ZfcUser\Authentication\Adapter\Db::getHydrator - */ - public function testLazyLoadHydrator() - { - $this->assertEquals($this->hydrator, $this->db->getHydrator()); - } - - /** - * @covers ZfcUser\Authentication\Adapter\Db::setHydrator - * @covers ZfcUser\Authentication\Adapter\Db::getHydrator - */ - public function testSetHydrator() - { - $this->db->setHydrator($this->hydrator); - $this->assertSame($this->hydrator, $this->db->getHydrator()); - } - - protected function setAuthenticationEmail() - { - $this->mapper->expects($this->once()) - ->method('findByEmail') - ->with('zfc-user@zf-commons.io') - ->will($this->returnValue($this->user)); - - $this->options->expects($this->once()) - ->method('getAuthIdentityFields') - ->will($this->returnValue(array('email'))); - } - - protected function setAuthenticationUser() - { - $this->mapper->expects($this->once()) - ->method('findByUsername') - ->with('ZfcUser') - ->will($this->returnValue($this->user)); - - $this->options->expects($this->once()) - ->method('getAuthIdentityFields') - ->will($this->returnValue(array('username'))); - } - - protected function setAuthenticationCredentials($identity = 'ZfcUser', $credential = 'ZfcUserPassword') - { - $this->storage->expects($this->at(0)) - ->method('read') - ->will($this->returnValue(array('is_satisfied' => false))); - - $post = $this->getMock('Zend\Stdlib\Parameters'); - $post->expects($this->at(0)) - ->method('get') - ->with('identity') - ->will($this->returnValue($identity)); - $post->expects($this->at(1)) - ->method('get') - ->with('credential') - ->will($this->returnValue($credential)); - - $request = $this->getMock('Zend\Http\Request'); - $request->expects($this->exactly(2)) - ->method('getPost') - ->will($this->returnValue($post)); - - $this->authEvent->expects($this->exactly(2)) - ->method('getRequest') - ->will($this->returnValue($request)); - } -} diff --git a/tests/ZfcUserTest/Authentication/Adapter/MapperTest.php b/tests/ZfcUserTest/Authentication/Adapter/MapperTest.php new file mode 100644 index 00000000..d21184af --- /dev/null +++ b/tests/ZfcUserTest/Authentication/Adapter/MapperTest.php @@ -0,0 +1,105 @@ +mapper = $this->getMockForAbstractClass( + 'ZfcUser\Mapper\UserInterface' + ); + $this->user = $this->getMockForAbstractClass( + 'ZfcUser\Entity\UserInterface' + ); + $this->processor = $this->getMock('Zend\Crypt\Password\PasswordInterface'); + + $this->adapter = new Mapper($this->mapper, 'findByUsername', $this->processor); + $this->adapter->setIdentity('identity'); + $this->adapter->setCredential('credential'); + } + + public function testAuthenticateWhenNoUserEntityFound() + { + $this->mapper->expects($this->once()) + ->method('findByUsername') + ->with('identity') + ->will($this->returnValue(null)); + + $result = $this->adapter->authenticate(); + $this->assertInstanceOf('Zend\Authentication\Result', $result); + $this->assertEquals(Result::FAILURE_IDENTITY_NOT_FOUND, $result->getCode()); + $this->assertCount(1, $result->getMessages()); + } + + public function testAuthenticateWhenUserEntityFoundButPasswordIncorrect() + { + $this->user->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('notthecredential')); + $this->mapper->expects($this->once()) + ->method('findByUsername') + ->with('identity') + ->will($this->returnValue($this->user)); + $this->processor->expects($this->once()) + ->method('verify') + ->with('credential', 'notthecredential') + ->will($this->returnValue(false)); + + $result = $this->adapter->authenticate(); + $this->assertInstanceOf('Zend\Authentication\Result', $result); + $this->assertEquals(Result::FAILURE_CREDENTIAL_INVALID, $result->getCode()); + $this->assertCount(1, $result->getMessages()); + } + + public function testAuthenticateSuccessful() + { + $this->user->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('credential')); + $this->mapper->expects($this->once()) + ->method('findByUsername') + ->with('identity') + ->will($this->returnValue($this->user)); + $this->processor->expects($this->once()) + ->method('verify') + ->with('credential', 'credential') + ->will($this->returnValue(true)); + + $result = $this->adapter->authenticate(); + $this->assertInstanceOf('Zend\Authentication\Result', $result); + $this->assertEquals(Result::SUCCESS, $result->getCode()); + $this->assertCount(1, $result->getMessages()); + } +} diff --git a/tests/ZfcUserTest/Authentication/Adapter/TestAsset/AbstractAdapterExtension.php b/tests/ZfcUserTest/Authentication/Adapter/TestAsset/AbstractAdapterExtension.php deleted file mode 100644 index 30497650..00000000 --- a/tests/ZfcUserTest/Authentication/Adapter/TestAsset/AbstractAdapterExtension.php +++ /dev/null @@ -1,13 +0,0 @@ -getMock('Zend\Session\SessionManager'); + $manager->expects($this->once()) + ->method('regenerateId'); + + $listener = new RegenerateSessionIdentifier($manager); + $listener(); + } +} diff --git a/tests/ZfcUserTest/Authentication/Storage/DbTest.php b/tests/ZfcUserTest/Authentication/Storage/DbTest.php deleted file mode 100644 index f7a0ae84..00000000 --- a/tests/ZfcUserTest/Authentication/Storage/DbTest.php +++ /dev/null @@ -1,238 +0,0 @@ -db = $db; - - $this->storage = $this->getMock('Zend\Authentication\Storage\Session'); - $this->mapper = $this->getMock('ZfcUser\Mapper\User'); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::isEmpty - */ - public function testIsEmpty() - { - $this->storage->expects($this->once()) - ->method('isEmpty') - ->will($this->returnValue(true)); - - $this->db->setStorage($this->storage); - - $this->assertTrue($this->db->isEmpty()); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::read - */ - public function testReadWithResolvedEntitySet() - { - $reflectionClass = new \ReflectionClass('ZfcUser\Authentication\Storage\Db'); - $reflectionProperty = $reflectionClass->getProperty('resolvedIdentity'); - $reflectionProperty->setAccessible(true); - $reflectionProperty->setValue($this->db, 'zfcUser'); - - $this->assertSame('zfcUser', $this->db->read()); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::read - */ - public function testReadWithoutResolvedEntitySetIdentityIntUserFound() - { - $this->storage->expects($this->once()) - ->method('read') - ->will($this->returnValue(1)); - - $this->db->setStorage($this->storage); - - $user = $this->getMock('ZfcUser\Entity\User'); - $user->setUsername('zfcUser'); - - $this->mapper->expects($this->once()) - ->method('findById') - ->with(1) - ->will($this->returnValue($user)); - - $this->db->setMapper($this->mapper); - - $result = $this->db->read(); - - $this->assertSame($user, $result); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::read - */ - public function testReadWithoutResolvedEntitySetIdentityIntUserNotFound() - { - $this->storage->expects($this->once()) - ->method('read') - ->will($this->returnValue(1)); - - $this->db->setStorage($this->storage); - - $this->mapper->expects($this->once()) - ->method('findById') - ->with(1) - ->will($this->returnValue(false)); - - $this->db->setMapper($this->mapper); - - $result = $this->db->read(); - - $this->assertNull($result); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::read - */ - public function testReadWithoutResolvedEntitySetIdentityObject() - { - $user = $this->getMock('ZfcUser\Entity\User'); - $user->setUsername('zfcUser'); - - $this->storage->expects($this->once()) - ->method('read') - ->will($this->returnValue($user)); - - $this->db->setStorage($this->storage); - - $result = $this->db->read(); - - $this->assertSame($user, $result); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::write - */ - public function testWrite() - { - $reflectionClass = new \ReflectionClass('ZfcUser\Authentication\Storage\Db'); - $reflectionProperty = $reflectionClass->getProperty('resolvedIdentity'); - $reflectionProperty->setAccessible(true); - - $this->storage->expects($this->once()) - ->method('write') - ->with('zfcUser'); - - $this->db->setStorage($this->storage); - - $this->db->write('zfcUser'); - - $this->assertNull($reflectionProperty->getValue($this->db)); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::clear - */ - public function testClear() - { - $reflectionClass = new \ReflectionClass('ZfcUser\Authentication\Storage\Db'); - $reflectionProperty = $reflectionClass->getProperty('resolvedIdentity'); - $reflectionProperty->setAccessible(true); - - $this->storage->expects($this->once()) - ->method('clear'); - - $this->db->setStorage($this->storage); - - $this->db->clear(); - - $this->assertNull($reflectionProperty->getValue($this->db)); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::getMapper - */ - public function testGetMapperWithNoMapperSet() - { - $sm = $this->getMock('Zend\ServiceManager\ServiceManager'); - $sm->expects($this->once()) - ->method('get') - ->with('zfcuser_user_mapper') - ->will($this->returnValue($this->mapper)); - - $this->db->setServiceManager($sm); - - $this->assertInstanceOf('ZfcUser\Mapper\UserInterface', $this->db->getMapper()); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::setMapper - * @covers ZfcUser\Authentication\Storage\Db::getMapper - */ - public function testSetGetMapper() - { - $mapper = new \ZfcUser\Mapper\User; - $mapper->setTableName('zfcUser'); - - $this->db->setMapper($mapper); - - $this->assertInstanceOf('ZfcUser\Mapper\User', $this->db->getMapper()); - $this->assertSame('zfcUser', $this->db->getMapper()->getTableName()); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::setServiceManager - * @covers ZfcUser\Authentication\Storage\Db::getServiceManager - */ - public function testSetGetServicemanager() - { - $sm = $this->getMock('Zend\ServiceManager\ServiceManager'); - - $this->db->setServiceManager($sm); - - $this->assertInstanceOf('Zend\ServiceManager\ServiceLocatorInterface', $this->db->getServiceManager()); - $this->assertSame($sm, $this->db->getServiceManager()); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::getStorage - * @covers ZfcUser\Authentication\Storage\Db::setStorage - */ - public function testGetStorageWithoutStorageSet() - { - $this->assertInstanceOf('Zend\Authentication\Storage\Session', $this->db->getStorage()); - } - - /** - * @covers ZfcUser\Authentication\Storage\Db::getStorage - * @covers ZfcUser\Authentication\Storage\Db::setStorage - */ - public function testSetGetStorage() - { - $storage = new \Zend\Authentication\Storage\Session('ZfcUserStorage'); - $this->db->setStorage($storage); - - $this->assertInstanceOf('Zend\Authentication\Storage\Session', $this->db->getStorage()); - } -} diff --git a/tests/ZfcUserTest/Authentication/Storage/MapperTest.php b/tests/ZfcUserTest/Authentication/Storage/MapperTest.php new file mode 100644 index 00000000..78ba52b7 --- /dev/null +++ b/tests/ZfcUserTest/Authentication/Storage/MapperTest.php @@ -0,0 +1,202 @@ +storage = $this->getMock('Zend\Authentication\Storage\StorageInterface'); + $this->mapper = $this->getMock('ZfcUser\Mapper\UserInterface'); + + $this->adapter = new Mapper($this->mapper, $this->storage); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::isEmpty + */ + public function testIsEmpty() + { + $this->storage->expects($this->once()) + ->method('isEmpty') + ->will($this->returnValue(true)); + + $this->assertTrue($this->adapter->isEmpty()); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::isEmpty + */ + public function testIsEmptyWhenNotEmpty() + { + $this->adapter->write('identity'); + + $this->storage->expects($this->once()) + ->method('isEmpty') + ->will($this->returnValue(false)); + + $this->storage->expects($this->once()) + ->method('read') + ->will($this->returnValue('identity')); + + $this->mapper->expects($this->once()) + ->method('findById') + ->will($this->returnValue($this->getMock('ZfcUser\Entity\UserInterface'))); + + $this->assertFalse($this->adapter->isEmpty()); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::isEmpty + */ + public function testIsEmptyWhenStorageIsEmptyButAdapterHasNoIdentity() + { + $this->adapter->write('identity'); + + $this->storage->expects($this->once()) + ->method('isEmpty') + ->will($this->returnValue(false)); + + $this->storage->expects($this->once()) + ->method('read') + ->will($this->returnValue('identity')); + + $this->mapper->expects($this->once()) + ->method('findById') + ->will($this->returnValue(null)); + + $this->assertTrue($this->adapter->isEmpty()); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::read + */ + public function testReadWithResolvedEntitySet() + { + $reflectionClass = new \ReflectionClass('ZfcUser\Authentication\Storage\Mapper'); + $reflectionProperty = $reflectionClass->getProperty('resolvedIdentity'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->adapter, 'zfcUser'); + + $this->assertSame('zfcUser', $this->adapter->read()); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::read + */ + public function testReadWithoutResolvedEntitySetIdentityIntUserFound() + { + $this->storage->expects($this->once()) + ->method('read') + ->will($this->returnValue(1)); + + $user = $this->getMock('ZfcUser\Entity\User'); + $user->setUsername('zfcUser'); + + $this->mapper->expects($this->once()) + ->method('findById') + ->with(1) + ->will($this->returnValue($user)); + + $result = $this->adapter->read(); + + $this->assertSame($user, $result); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::read + */ + public function testReadWithoutResolvedEntitySetIdentityIntUserNotFound() + { + $this->storage->expects($this->once()) + ->method('read') + ->will($this->returnValue(1)); + + $this->mapper->expects($this->once()) + ->method('findById') + ->with(1) + ->will($this->returnValue(false)); + + $result = $this->adapter->read(); + + $this->assertNull($result); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::read + */ + public function testReadWithoutResolvedEntitySetIdentityObject() + { + $user = $this->getMock('ZfcUser\Entity\User'); + $user->setUsername('zfcUser'); + + $this->storage->expects($this->once()) + ->method('read') + ->will($this->returnValue($user)); + + $result = $this->adapter->read(); + + $this->assertSame($user, $result); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::write + */ + public function testWrite() + { + $reflectionClass = new \ReflectionClass('ZfcUser\Authentication\Storage\Mapper'); + $reflectionProperty = $reflectionClass->getProperty('resolvedIdentity'); + $reflectionProperty->setAccessible(true); + + $this->storage->expects($this->once()) + ->method('write') + ->with('zfcUser'); + + $this->adapter->write('zfcUser'); + + $this->assertNull($reflectionProperty->getValue($this->adapter)); + } + + /** + * @covers ZfcUser\Authentication\Storage\Mapper::clear + */ + public function testClear() + { + $reflectionClass = new \ReflectionClass('ZfcUser\Authentication\Storage\Mapper'); + $reflectionProperty = $reflectionClass->getProperty('resolvedIdentity'); + $reflectionProperty->setAccessible(true); + + $this->storage->expects($this->once()) + ->method('clear'); + + $this->adapter->clear(); + + $this->assertNull($reflectionProperty->getValue($this->adapter)); + } +} diff --git a/tests/ZfcUserTest/Controller/UserControllerTest.php b/tests/ZfcUserTest/Controller/UserControllerTest.php index aca42945..6e92c9cf 100644 --- a/tests/ZfcUserTest/Controller/UserControllerTest.php +++ b/tests/ZfcUserTest/Controller/UserControllerTest.php @@ -207,8 +207,6 @@ public function testLoginActionValidFormRedirectFalse($isValid, $wantRedirect) if ($isValid) { $adapter = $this->getMock('ZfcUser\Authentication\Adapter\AdapterChain'); - $adapter->expects($this->once()) - ->method('resetAdapters'); $service = $this->getMock('Zend\Authentication\AuthenticationService'); $service->expects($this->once()) @@ -349,11 +347,7 @@ public function testLogoutAction($withRedirect, $post, $query) $controller = $this->controller; $adapter = $this->getMock('ZfcUser\Authentication\Adapter\AdapterChain'); - $adapter->expects($this->once()) - ->method('resetAdapters'); - $adapter->expects($this->once()) - ->method('logoutAdapters'); $service = $this->getMock('Zend\Authentication\AuthenticationService'); $service->expects($this->once()) @@ -418,14 +412,14 @@ public function testLogoutAction($withRedirect, $post, $query) public function testLoginRedirectFailsWithUrl() { - + $this->markTestIncomplete(); } /** * @dataProvider providerTestAuthenticateAction * @depend testActionControllHasIdentity */ - public function testAuthenticateAction($wantRedirect, $post, $query, $prepareResult = false, $authValid = false) + public function testAuthenticateAction($wantRedirect, $post, $query, $authValid = false) { $controller = $this->controller; $response = new Response(); @@ -435,12 +429,12 @@ public function testAuthenticateAction($wantRedirect, $post, $query, $prepareRes $params->expects($this->any()) ->method('__invoke') ->will($this->returnSelf()); - $params->expects($this->once()) + $params->expects($this->any()) ->method('fromPost') ->will($this->returnCallback(function ($key, $default) use ($post) { return $post ?: $default; })); - $params->expects($this->once()) + $params->expects($this->any()) ->method('fromQuery') ->will($this->returnCallback(function ($key, $default) use ($query) { return $query ?: $default; @@ -454,9 +448,11 @@ public function testAuthenticateAction($wantRedirect, $post, $query, $prepareRes $adapter = $this->getMock('ZfcUser\Authentication\Adapter\AdapterChain'); $adapter->expects($this->once()) - ->method('prepareForAuthentication') - ->with($request) - ->will($this->returnValue($prepareResult)); + ->method('setIdentity') + ->will($this->returnSelf()); + $adapter->expects($this->once()) + ->method('setCredential') + ->will($this->returnSelf()); $service = $this->getMock('Zend\Authentication\AuthenticationService'); @@ -467,80 +463,72 @@ public function testAuthenticateAction($wantRedirect, $post, $query, $prepareRes 'getAuthService'=>$service )); - if (is_bool($prepareResult)) { - - $authResult = $this->getMockBuilder('Zend\Authentication\Result') - ->disableOriginalConstructor() - ->getMock(); - $authResult->expects($this->once()) - ->method('isValid') - ->will($this->returnValue($authValid)); - - $service->expects($this->once()) - ->method('authenticate') - ->with($adapter) - ->will($this->returnValue($authResult)); - - $redirect = $this->getMock('Zend\Mvc\Controller\Plugin\Redirect'); - $this->pluginManagerPlugins['redirect'] = $redirect; - - if (!$authValid) { - $flashMessenger = $this->getMock( - 'Zend\Mvc\Controller\Plugin\FlashMessenger' - ); - $this->pluginManagerPlugins['flashMessenger']= $flashMessenger; + $authResult = $this->getMockBuilder('Zend\Authentication\Result') + ->disableOriginalConstructor() + ->getMock(); + $authResult->expects($this->once()) + ->method('isValid') + ->will($this->returnValue($authValid)); - $flashMessenger->expects($this->once()) - ->method('setNamespace') - ->with('zfcuser-login-form') - ->will($this->returnSelf()); + $service->expects($this->once()) + ->method('authenticate') + ->with($adapter) + ->will($this->returnValue($authResult)); - $flashMessenger->expects($this->once()) - ->method('addMessage'); + $redirect = $this->getMock('Zend\Mvc\Controller\Plugin\Redirect'); + $this->pluginManagerPlugins['redirect'] = $redirect; - $adapter->expects($this->once()) - ->method('resetAdapters'); + if (!$authValid) { + $flashMessenger = $this->getMock( + 'Zend\Mvc\Controller\Plugin\FlashMessenger' + ); + $this->pluginManagerPlugins['flashMessenger']= $flashMessenger; - $redirectQuery = ($post ?: $query ?: false); - $redirectQuery = $redirectQuery ? '?redirect=' . rawurlencode($redirectQuery) : ''; + $flashMessenger->expects($this->once()) + ->method('setNamespace') + ->with('zfcuser-login-form') + ->will($this->returnSelf()); - $redirect->expects($this->once()) - ->method('toUrl') - ->with('user/login' . $redirectQuery) - ->will($this->returnValue($response)); + $flashMessenger->expects($this->once()) + ->method('addMessage'); - $url = $this->getMock('Zend\Mvc\Controller\Plugin\Url'); - $url->expects($this->once()) - ->method('fromRoute') - ->with($controller::ROUTE_LOGIN) - ->will($this->returnValue('user/login')); - $this->pluginManagerPlugins['url'] = $url; + $redirectQuery = ($post ?: $query ?: false); + $redirectQuery = $redirectQuery ? '?redirect=' . rawurlencode($redirectQuery) : ''; - } elseif ($wantRedirect && $hasRedirect) { - $redirect->expects($this->once()) - ->method('toRoute') - ->with(($post ?: $query ?: false)) - ->will($this->returnValue($response)); - } else { + $redirect->expects($this->once()) + ->method('toUrl') + ->with('user/login' . $redirectQuery) + ->will($this->returnValue($response)); - $redirect->expects($this->once()) - ->method('toRoute') - ->with('zfcuser') - ->will($this->returnValue($response)); + $url = $this->getMock('Zend\Mvc\Controller\Plugin\Url'); + $url->expects($this->once()) + ->method('fromRoute') + ->with($controller::ROUTE_LOGIN) + ->will($this->returnValue('user/login')); + $this->pluginManagerPlugins['url'] = $url; - $this->options->expects($this->once()) - ->method('getLoginRedirectRoute') - ->will($this->returnValue('zfcuser')); - } + } elseif ($wantRedirect && $hasRedirect) { + $redirect->expects($this->once()) + ->method('toRoute') + ->with(($post ?: $query ?: false)) + ->will($this->returnValue($response)); + } else { - $this->options->expects($this->any()) - ->method('getUseRedirectParameterIfPresent') - ->will($this->returnValue((bool) $wantRedirect)); + $redirect->expects($this->once()) + ->method('toRoute') + ->with('zfcuser') + ->will($this->returnValue($response)); + $this->options->expects($this->once()) + ->method('getLoginRedirectRoute') + ->will($this->returnValue('zfcuser')); } - $result = $controller->authenticateAction(); + $this->options->expects($this->any()) + ->method('getUseRedirectParameterIfPresent') + ->will($this->returnValue((bool) $wantRedirect)); + $result = $controller->authenticateAction(); } @@ -751,24 +739,24 @@ public function providerTestAuthenticateAction () { // $redirect, $post, $query, $prepareResult = false, $authValid = false return array( - array(false, null, null, new Response(), false), - array(false, null, null, false, false), - array(false, null, null, false, true), - array(false, 'localhost/test1', null, false, false), - array(false, 'localhost/test1', null, false, true), - array(false, 'localhost/test1', 'localhost/test2', false, false), - array(false, 'localhost/test1', 'localhost/test2', false, true), - array(false, null, 'localhost/test2', false, false), - array(false, null, 'localhost/test2', false, true), - - array(true, null, null, false, false), - array(true, null, null, false, true), - array(true, 'localhost/test1', null, false, false), - array(true, 'localhost/test1', null, false, true), - array(true, 'localhost/test1', 'localhost/test2', false, false), - array(true, 'localhost/test1', 'localhost/test2', false, true), - array(true, null, 'localhost/test2', false, false), - array(true, null, 'localhost/test2', false, true), + array(false, null, null, false), + array(false, null, null, false), + array(false, null, null, true), + array(false, 'localhost/test1', null, false), + array(false, 'localhost/test1', null, true), + array(false, 'localhost/test1', 'localhost/test2', false), + array(false, 'localhost/test1', 'localhost/test2', true), + array(false, null, 'localhost/test2', false), + array(false, null, 'localhost/test2', true), + + array(true, null, null, false), + array(true, null, null, true), + array(true, 'localhost/test1', null, false), + array(true, 'localhost/test1', null, true), + array(true, 'localhost/test1', 'localhost/test2', false), + array(true, 'localhost/test1', 'localhost/test2', true), + array(true, null, 'localhost/test2', false), + array(true, null, 'localhost/test2', true), ); } diff --git a/tests/ZfcUserTest/Factory/Authentication/Adapter/AdapterChainFactoryTest.php b/tests/ZfcUserTest/Factory/Authentication/Adapter/AdapterChainFactoryTest.php new file mode 100644 index 00000000..9e1cfe69 --- /dev/null +++ b/tests/ZfcUserTest/Factory/Authentication/Adapter/AdapterChainFactoryTest.php @@ -0,0 +1,60 @@ +serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + + $this->options = $this->getMockBuilder('ZfcUser\Options\ModuleOptions') + ->disableOriginalConstructor() + ->getMock(); + + $adapters = array( + 9999 => 'adapter1', + 20 => 'adapter2', + ); + $adapter1 = $this->getMock('Zend\Authentication\Adapter\AbstractAdapter'); + $adapter2 = $this->getMock('Zend\Authentication\Adapter\AbstractAdapter'); + + $this->options->expects($this->atLeastOnce()) + ->method('getAuthAdapters') + ->will($this->returnValue($adapters)); + + $locatorMap = array( + array('zfcuser_module_options', $this->options), + array('adapter1', $adapter1), + array('adapter2', $adapter2), + ); + + $this->serviceLocator->expects($this->atLeastOnce()) + ->method('get') + ->will($this->returnValueMap($locatorMap)); + + $this->factory = new AdapterChainFactory(); + + $adapterChain = $this->factory->createService($this->serviceLocator); + $this->assertInstanceOf('ZfcUser\Authentication\Adapter\AdapterChain', $adapterChain); + } +} diff --git a/tests/ZfcUserTest/Factory/Authentication/Adapter/MapperEmailFactoryTest.php b/tests/ZfcUserTest/Factory/Authentication/Adapter/MapperEmailFactoryTest.php new file mode 100644 index 00000000..851adbdb --- /dev/null +++ b/tests/ZfcUserTest/Factory/Authentication/Adapter/MapperEmailFactoryTest.php @@ -0,0 +1,28 @@ +setService( + 'zfcuser_user_mapper', + $this->getMock('ZfcUser\Mapper\UserInterface') + ); + + $serviceLocator->setService( + 'zfcuser_authentication_credentialprocessor', + $this->getMock('Zend\Crypt\Password\PasswordInterface') + ); + + $factory = new MapperEmailFactory(); + $mapper = $factory->createService($serviceLocator); + $this->assertInstanceOf('ZfcUser\Authentication\Adapter\Mapper', $mapper); + } +} diff --git a/tests/ZfcUserTest/Factory/Authentication/Adapter/MapperUsernameFactoryTest.php b/tests/ZfcUserTest/Factory/Authentication/Adapter/MapperUsernameFactoryTest.php new file mode 100644 index 00000000..3b557810 --- /dev/null +++ b/tests/ZfcUserTest/Factory/Authentication/Adapter/MapperUsernameFactoryTest.php @@ -0,0 +1,28 @@ +setService( + 'zfcuser_user_mapper', + $this->getMock('ZfcUser\Mapper\UserInterface') + ); + + $serviceLocator->setService( + 'zfcuser_authentication_credentialprocessor', + $this->getMock('Zend\Crypt\Password\PasswordInterface') + ); + + $factory = new MapperUsernameFactory(); + $mapper = $factory->createService($serviceLocator); + $this->assertInstanceOf('ZfcUser\Authentication\Adapter\Mapper', $mapper); + } +} diff --git a/tests/ZfcUserTest/Factory/Authentication/CredentialProcessor/BcryptFactoryTest.php b/tests/ZfcUserTest/Factory/Authentication/CredentialProcessor/BcryptFactoryTest.php new file mode 100644 index 00000000..6049a8cc --- /dev/null +++ b/tests/ZfcUserTest/Factory/Authentication/CredentialProcessor/BcryptFactoryTest.php @@ -0,0 +1,23 @@ +getMock('ZfcUser\Options\ModuleOptions'); + $options->expects($this->once())->method('getPasswordCost')->will($this->returnValue(5)); + + $serviceLocator = new ServiceManager(); + $serviceLocator->setService('zfcuser_module_options', $options); + + $factory = new BcryptFactory(); + $processor = $factory->createService($serviceLocator); + $this->assertInstanceOf('Zend\Crypt\Password\Bcrypt', $processor); + $this->assertEquals(5, $processor->getCost()); + } +} diff --git a/tests/ZfcUserTest/Factory/Authentication/Storage/MapperFactoryTest.php b/tests/ZfcUserTest/Factory/Authentication/Storage/MapperFactoryTest.php new file mode 100644 index 00000000..eb30fef2 --- /dev/null +++ b/tests/ZfcUserTest/Factory/Authentication/Storage/MapperFactoryTest.php @@ -0,0 +1,28 @@ +setService( + 'zfcuser_user_mapper', + $this->getMock('ZfcUser\Mapper\UserInterface') + ); + + $serviceLocator->setService( + 'zfcuser_authentication_storage_backend', + $this->getMock('Zend\Authentication\Storage\StorageInterface') + ); + + $factory = new MapperFactory(); + $mapper = $factory->createService($serviceLocator); + $this->assertInstanceOf('ZfcUser\Authentication\Storage\Mapper', $mapper); + } +} diff --git a/tests/ZfcUserTest/Factory/AuthenticationServiceFactoryTest.php b/tests/ZfcUserTest/Factory/AuthenticationServiceFactoryTest.php index 792cc5c0..89178c98 100644 --- a/tests/ZfcUserTest/Factory/AuthenticationServiceFactoryTest.php +++ b/tests/ZfcUserTest/Factory/AuthenticationServiceFactoryTest.php @@ -8,9 +8,15 @@ class AuthenticationServiceFactoryTest extends \PHPUnit_Framework_TestCase { public function testFactory() { + $mapper = $this->getMockBuilder('ZfcUser\Authentication\Storage\Mapper') + ->disableOriginalConstructor() + ->getMock(); + + $adapter = $this->getMock('ZfcUser\Authentication\Adapter\AdapterChain'); + $serviceManager = new ServiceManager; - $serviceManager->setService('ZfcUser\Authentication\Storage\Db', $this->getMock('ZfcUser\Authentication\Storage\Db')); - $serviceManager->setService('ZfcUser\Authentication\Adapter\AdapterChain', $this->getMock('ZfcUser\Authentication\Adapter\AdapterChain')); + $serviceManager->setService('zfcuser_authentication_storage', $mapper); + $serviceManager->setService('ZfcUser\Authentication\Adapter\AdapterChain', $adapter); $factory = new AuthenticationServiceFactory; diff --git a/tests/ZfcUserTest/Options/ModuleOptionsTest.php b/tests/ZfcUserTest/Options/ModuleOptionsTest.php index 86e913c5..cb56055b 100644 --- a/tests/ZfcUserTest/Options/ModuleOptionsTest.php +++ b/tests/ZfcUserTest/Options/ModuleOptionsTest.php @@ -220,7 +220,7 @@ public function testSetGetAllowedLoginStates() */ public function testGetAuthAdapters() { - $this->assertEquals(array(100 => 'ZfcUser\Authentication\Adapter\Db'), $this->options->getAuthAdapters()); + $this->assertEquals(array(100 => 'ZfcUser\Authentication\Adapter\Mapper'), $this->options->getAuthAdapters()); } /**