From b1094044a64b15657f4d36be661e90383efc555d Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Tue, 8 Nov 2016 09:15:02 +0100 Subject: [PATCH] add login credential store Signed-off-by: Christoph Wurst --- lib/composer/composer/autoload_classmap.php | 6 + lib/composer/composer/autoload_static.php | 6 + .../DependencyInjection/DIContainer.php | 4 + .../LoginCredentials/Credentials.php | 72 ++++++++++ .../Authentication/LoginCredentials/Store.php | 86 ++++++++++++ lib/private/Server.php | 9 ++ .../CredentialsUnavailableException.php | 34 +++++ .../LoginCredentials/ICredentials.php | 46 +++++++ .../LoginCredentials/IStore.php | 42 ++++++ .../LoginCredentials/CredentialsTest.php | 66 +++++++++ .../LoginCredentials/StoreTest.php | 127 ++++++++++++++++++ 11 files changed, 498 insertions(+) create mode 100644 lib/private/Authentication/LoginCredentials/Credentials.php create mode 100644 lib/private/Authentication/LoginCredentials/Store.php create mode 100644 lib/public/Authentication/Exceptions/CredentialsUnavailableException.php create mode 100644 lib/public/Authentication/LoginCredentials/ICredentials.php create mode 100644 lib/public/Authentication/LoginCredentials/IStore.php create mode 100644 tests/lib/Authentication/LoginCredentials/CredentialsTest.php create mode 100644 tests/lib/Authentication/LoginCredentials/StoreTest.php diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 42cfb8c45e14c..442fc602059fc 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -49,7 +49,10 @@ 'OCP\\AppFramework\\Utility\\ITimeFactory' => $baseDir . '/lib/public/AppFramework/Utility/ITimeFactory.php', 'OCP\\App\\IAppManager' => $baseDir . '/lib/public/App/IAppManager.php', 'OCP\\App\\ManagerEvent' => $baseDir . '/lib/public/App/ManagerEvent.php', + 'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => $baseDir . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php', 'OCP\\Authentication\\IApacheBackend' => $baseDir . '/lib/public/Authentication/IApacheBackend.php', + 'OCP\\Authentication\\LoginCredentials\\ICredentials' => $baseDir . '/lib/public/Authentication/LoginCredentials/ICredentials.php', + 'OCP\\Authentication\\LoginCredentials\\IStore' => $baseDir . '/lib/public/Authentication/LoginCredentials/IStore.php', 'OCP\\Authentication\\TwoFactorAuth\\IProvider' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvider.php', 'OCP\\AutoloadNotAllowedException' => $baseDir . '/lib/public/AutoloadNotAllowedException.php', 'OCP\\BackgroundJob' => $baseDir . '/lib/public/BackgroundJob.php', @@ -306,6 +309,8 @@ 'OC\\Authentication\\Exceptions\\PasswordlessTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/PasswordlessTokenException.php', 'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => $baseDir . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php', 'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => $baseDir . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php', + 'OC\\Authentication\\LoginCredentials\\Credentials' => $baseDir . '/lib/private/Authentication/LoginCredentials/Credentials.php', + 'OC\\Authentication\\LoginCredentials\\Store' => $baseDir . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Token\\DefaultToken' => $baseDir . '/lib/private/Authentication/Token/DefaultToken.php', 'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php', 'OC\\Authentication\\Token\\DefaultTokenMapper' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenMapper.php', @@ -725,6 +730,7 @@ 'OC\\Settings\\Controller\\GroupsController' => $baseDir . '/settings/Controller/GroupsController.php', 'OC\\Settings\\Controller\\LogSettingsController' => $baseDir . '/settings/Controller/LogSettingsController.php', 'OC\\Settings\\Controller\\MailSettingsController' => $baseDir . '/settings/Controller/MailSettingsController.php', + 'OC\\Settings\\Controller\\PersonalController' => $baseDir . '/settings/Controller/PersonalController.php', 'OC\\Settings\\Controller\\SecuritySettingsController' => $baseDir . '/settings/Controller/SecuritySettingsController.php', 'OC\\Settings\\Controller\\UsersController' => $baseDir . '/settings/Controller/UsersController.php', 'OC\\Settings\\Manager' => $baseDir . '/lib/private/Settings/Manager.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index d7e937577f254..39930ef4caa13 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -79,7 +79,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\AppFramework\\Utility\\ITimeFactory' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Utility/ITimeFactory.php', 'OCP\\App\\IAppManager' => __DIR__ . '/../../..' . '/lib/public/App/IAppManager.php', 'OCP\\App\\ManagerEvent' => __DIR__ . '/../../..' . '/lib/public/App/ManagerEvent.php', + 'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php', 'OCP\\Authentication\\IApacheBackend' => __DIR__ . '/../../..' . '/lib/public/Authentication/IApacheBackend.php', + 'OCP\\Authentication\\LoginCredentials\\ICredentials' => __DIR__ . '/../../..' . '/lib/public/Authentication/LoginCredentials/ICredentials.php', + 'OCP\\Authentication\\LoginCredentials\\IStore' => __DIR__ . '/../../..' . '/lib/public/Authentication/LoginCredentials/IStore.php', 'OCP\\Authentication\\TwoFactorAuth\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvider.php', 'OCP\\AutoloadNotAllowedException' => __DIR__ . '/../../..' . '/lib/public/AutoloadNotAllowedException.php', 'OCP\\BackgroundJob' => __DIR__ . '/../../..' . '/lib/public/BackgroundJob.php', @@ -336,6 +339,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Exceptions\\PasswordlessTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/PasswordlessTokenException.php', 'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php', 'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php', + 'OC\\Authentication\\LoginCredentials\\Credentials' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Credentials.php', + 'OC\\Authentication\\LoginCredentials\\Store' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Token\\DefaultToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultToken.php', 'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php', 'OC\\Authentication\\Token\\DefaultTokenMapper' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenMapper.php', @@ -755,6 +760,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Settings\\Controller\\GroupsController' => __DIR__ . '/../../..' . '/settings/Controller/GroupsController.php', 'OC\\Settings\\Controller\\LogSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/LogSettingsController.php', 'OC\\Settings\\Controller\\MailSettingsController' => __DIR__ . '/../../..' . '/settings/Controller/MailSettingsController.php', + 'OC\\Settings\\Controller\\PersonalController' => __DIR__ . '/../../..' . '/settings/Controller/PersonalController.php', 'OC\\Settings\\Controller\\SecuritySettingsController' => __DIR__ . '/../../..' . '/settings/Controller/SecuritySettingsController.php', 'OC\\Settings\\Controller\\UsersController' => __DIR__ . '/../../..' . '/settings/Controller/UsersController.php', 'OC\\Settings\\Manager' => __DIR__ . '/../../..' . '/lib/private/Settings/Manager.php', diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index e1516c47ed6bc..78d27881e1828 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -91,6 +91,10 @@ public function __construct($appName, $urlParams = array()){ return new Output($this->getServer()->getWebRoot()); }); + $this->registerService(\OCP\Authentication\LoginCredentials\IStore::class, function() { + return $this->getServer()->query(\OCP\Authentication\LoginCredentials\IStore::class); + }); + $this->registerService('OCP\\IAvatarManager', function($c) { return $this->getServer()->getAvatarManager(); }); diff --git a/lib/private/Authentication/LoginCredentials/Credentials.php b/lib/private/Authentication/LoginCredentials/Credentials.php new file mode 100644 index 0000000000000..9314b7489dbc9 --- /dev/null +++ b/lib/private/Authentication/LoginCredentials/Credentials.php @@ -0,0 +1,72 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OC\Authentication\LoginCredentials; + +use OCP\Authentication\LoginCredentials\ICredentials; + +class Credentials implements ICredentials { + + /** @var string */ + private $uid; + + /** @var string */ + private $loginName; + + /** @var string */ + private $password; + + /** + * @param string $uid + * @param string $loginName + * @param string $password + */ + public function __construct($uid, $loginName, $password) { + $this->uid = $uid; + $this->loginName = $loginName; + $this->password = $password; + } + + /** + * @return string + */ + public function getUID() { + return $this->uid; + } + + /** + * @return string + */ + public function getLoginName() { + return $this->loginName; + } + + /** + * @return string + */ + public function getPassword() { + return $this->password; + } + +} diff --git a/lib/private/Authentication/LoginCredentials/Store.php b/lib/private/Authentication/LoginCredentials/Store.php new file mode 100644 index 0000000000000..ea4c9fdd0c5c9 --- /dev/null +++ b/lib/private/Authentication/LoginCredentials/Store.php @@ -0,0 +1,86 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OC\Authentication\LoginCredentials; + +use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Exceptions\PasswordlessTokenException; +use OC\Authentication\Token\IProvider; +use OCP\Authentication\Exceptions\CredentialsUnavailableException; +use OCP\Authentication\LoginCredentials\ICredentials; +use OCP\Authentication\LoginCredentials\IStore; +use OCP\ILogger; +use OCP\ISession; +use OCP\Session\Exceptions\SessionNotAvailableException; + +class Store implements IStore { + + /** @var ISession */ + private $session; + + /** @var IProvider */ + private $tokenProvider; + + /** @var ILogger */ + private $logger; + + /** + * @param ISession $session + * @param IProvider $tokenProvider + * @param ILogger $logger + */ + public function __construct(ISession $session, IProvider $tokenProvider, ILogger $logger) { + $this->session = $session; + $this->tokenProvider = $tokenProvider; + $this->logger = $logger; + } + + /** + * @since 9.2 + * + * @return ICredentials the login credentials of the current user + * @throws CredentialsUnavailableException + */ + public function getLoginCredentials() { + try { + $sessionId = $this->session->getId(); + $token = $this->tokenProvider->getToken($sessionId); + + $uid = $token->getUID(); + $user = $token->getLoginName(); + $password = $this->tokenProvider->getPassword($token, $sessionId); + + return new Credentials($uid, $user, $password); + } catch (SessionNotAvailableException $ex) { + $this->logger->debug('could not get login credentials because session is unavailable', ['app' => 'core']); + } catch (InvalidTokenException $ex) { + $this->logger->debug('could not get login credentials because the token is invalid', ['app' => 'core']); + } catch (PasswordlessTokenException $ex) { + $this->logger->debug('could not get login credentials because the token has no password', ['app' => 'core']); + } + // If we reach this line, an exception was thrown. + throw new CredentialsUnavailableException(); + } + +} diff --git a/lib/private/Server.php b/lib/private/Server.php index 8f4e7d9ca2d50..9bbc071e9b1db 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -47,6 +47,7 @@ use OC\AppFramework\Http\Request; use OC\AppFramework\Db\Db; use OC\AppFramework\Utility\TimeFactory; +use OC\Authentication\LoginCredentials\Store; use OC\Command\AsyncBus; use OC\Diagnostics\EventLogger; use OC\Diagnostics\NullEventLogger; @@ -87,6 +88,7 @@ use OC\Session\CryptoWrapper; use OC\Tagging\TagMapper; use OCA\Theming\ThemingDefaults; +use OCP\Authentication\LoginCredentials\IStore; use OCP\IL10N; use OCP\IServerContainer; use OCP\Security\IContentSecurityPolicyManager; @@ -241,6 +243,13 @@ public function __construct($webRoot, \OC\Config $config) { }); return $groupManager; }); + $this->registerService(Store::class, function(Server $c) { + $session = $c->getSession(); + $tokenProvider = $c->query('OC\Authentication\Token\DefaultTokenProvider'); + $logger = $c->getLogger(); + return new Store($session, $tokenProvider, $logger); + }); + $this->registerAlias(IStore::class, Store::class); $this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) { $dbConnection = $c->getDatabaseConnection(); return new Authentication\Token\DefaultTokenMapper($dbConnection); diff --git a/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php b/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php new file mode 100644 index 0000000000000..44ae8d37ffb03 --- /dev/null +++ b/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php @@ -0,0 +1,34 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Authentication\Exceptions; + +use Exception; + +/** + * @since 9.2 + */ +class CredentialsUnavailableException extends Exception { + +} diff --git a/lib/public/Authentication/LoginCredentials/ICredentials.php b/lib/public/Authentication/LoginCredentials/ICredentials.php new file mode 100644 index 0000000000000..97c88dda5de53 --- /dev/null +++ b/lib/public/Authentication/LoginCredentials/ICredentials.php @@ -0,0 +1,46 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Authentication\LoginCredentials; + +/** + * @since 9.2 + */ +interface ICredentials { + + /** + * @return string + */ + public function getUID(); + + /** + * @return string + */ + public function getLoginName(); + + /** + * @return string + */ + public function getPassword(); +} diff --git a/lib/public/Authentication/LoginCredentials/IStore.php b/lib/public/Authentication/LoginCredentials/IStore.php new file mode 100644 index 0000000000000..a35e9214e7e58 --- /dev/null +++ b/lib/public/Authentication/LoginCredentials/IStore.php @@ -0,0 +1,42 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Authentication\LoginCredentials; + +use OCP\Authentication\Exceptions\CredentialsUnavailableException; + +/** + * @since 9.2 + */ +interface IStore { + + /** + * @since 9.2 + * + * @throws CredentialsUnavailableException + * @return ICredentials the login credentials of the current user + */ + public function getLoginCredentials(); + +} diff --git a/tests/lib/Authentication/LoginCredentials/CredentialsTest.php b/tests/lib/Authentication/LoginCredentials/CredentialsTest.php new file mode 100644 index 0000000000000..308ccafb151e0 --- /dev/null +++ b/tests/lib/Authentication/LoginCredentials/CredentialsTest.php @@ -0,0 +1,66 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Test\Authentication\LoginCredentials; + +use OC\Authentication\LoginCredentials\Credentials; +use Test\TestCase; + +class CredentialsTest extends TestCase { + + /** @var string */ + private $uid; + + /** @var string */ + private $user; + + /** @var string */ + private $password; + + /** @var Credentials */ + private $credentials; + + protected function setUp() { + parent::setUp(); + + $this->uid = 'user123'; + $this->user = 'User123'; + $this->password = '123456'; + + $this->credentials = new Credentials($this->uid, $this->user, $this->password); + } + + public function testGetUID() { + $this->assertEquals($this->uid, $this->credentials->getUID()); + } + + public function testGetUserName() { + $this->assertEquals($this->user, $this->credentials->getLoginName()); + } + + public function testGetPassword() { + $this->assertEquals($this->password, $this->credentials->getPassword()); + } + +} diff --git a/tests/lib/Authentication/LoginCredentials/StoreTest.php b/tests/lib/Authentication/LoginCredentials/StoreTest.php new file mode 100644 index 0000000000000..d60add67137ef --- /dev/null +++ b/tests/lib/Authentication/LoginCredentials/StoreTest.php @@ -0,0 +1,127 @@ + + * + * @author 2016 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Test\Authentication\LoginCredentials; + +use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Exceptions\PasswordlessTokenException; +use OC\Authentication\LoginCredentials\Credentials; +use OC\Authentication\LoginCredentials\Store; +use OC\Authentication\Token\IProvider; +use OC\Authentication\Token\IToken; +use OCP\Authentication\Exceptions\CredentialsUnavailableException; +use OCP\ILogger; +use OCP\ISession; +use OCP\Session\Exceptions\SessionNotAvailableException; +use Test\TestCase; + +class StoreTest extends TestCase { + + /** @var ISession|PHPUnit_Framework_MockObject_MockObject */ + private $session; + + /** @var IProvider|PHPUnit_Framework_MockObject_MockObject */ + private $tokenProvider; + + /** @var ILogger|PHPUnit_Framework_MockObject_MockObject */ + private $logger; + + /** @var Store */ + private $store; + + protected function setUp() { + parent::setUp(); + + $this->session = $this->createMock(ISession::class); + $this->tokenProvider = $this->createMock(IProvider::class); + $this->logger = $this->createMock(ILogger::class); + + $this->store = new Store($this->session, $this->tokenProvider, $this->logger); + } + + public function testGetLoginCredentials() { + $uid = 'uid'; + $user = 'user123'; + $password = 'passme'; + $token = $this->createMock(IToken::class); + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('sess2233')); + $this->tokenProvider->expects($this->once()) + ->method('getToken') + ->with('sess2233') + ->will($this->returnValue($token)); + $token->expects($this->once()) + ->method('getUID') + ->will($this->returnValue($uid)); + $token->expects($this->once()) + ->method('getLoginName') + ->will($this->returnValue($user)); + $this->tokenProvider->expects($this->once()) + ->method('getPassword') + ->with($token, 'sess2233') + ->will($this->returnValue($password)); + $expected = new Credentials($uid, $user, $password); + + $creds = $this->store->getLoginCredentials(); + + $this->assertEquals($expected, $creds); + } + + public function testGetLoginCredentialsSessionNotAvailable() { + $this->session->expects($this->once()) + ->method('getId') + ->will($this->throwException(new SessionNotAvailableException())); + $this->expectException(CredentialsUnavailableException::class); + + $this->store->getLoginCredentials(); + } + + public function testGetLoginCredentialsInvalidToken() { + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('sess2233')); + $this->tokenProvider->expects($this->once()) + ->method('getToken') + ->with('sess2233') + ->will($this->throwException(new InvalidTokenException())); + $this->expectException(CredentialsUnavailableException::class); + + $this->store->getLoginCredentials(); + } + + public function testGetLoginCredentialsPasswordlessToken() { + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('sess2233')); + $this->tokenProvider->expects($this->once()) + ->method('getToken') + ->with('sess2233') + ->will($this->throwException(new PasswordlessTokenException())); + $this->expectException(CredentialsUnavailableException::class); + + $this->store->getLoginCredentials(); + } + +}