diff --git a/apps/oauth2/lib/Controller/SettingsController.php b/apps/oauth2/lib/Controller/SettingsController.php index 2850012862988..046e6d7704188 100644 --- a/apps/oauth2/lib/Controller/SettingsController.php +++ b/apps/oauth2/lib/Controller/SettingsController.php @@ -30,7 +30,6 @@ */ namespace OCA\OAuth2\Controller; -use OC\Authentication\Token\DefaultTokenMapper; use OCA\OAuth2\Db\AccessTokenMapper; use OCA\OAuth2\Db\Client; use OCA\OAuth2\Db\ClientMapper; @@ -48,34 +47,22 @@ class SettingsController extends Controller { private $secureRandom; /** @var AccessTokenMapper */ private $accessTokenMapper; - /** @var DefaultTokenMapper */ - private $defaultTokenMapper; /** @var IL10N */ private $l; public const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - /** - * @param string $appName - * @param IRequest $request - * @param ClientMapper $clientMapper - * @param ISecureRandom $secureRandom - * @param AccessTokenMapper $accessTokenMapper - * @param DefaultTokenMapper $defaultTokenMapper - */ public function __construct(string $appName, IRequest $request, ClientMapper $clientMapper, ISecureRandom $secureRandom, AccessTokenMapper $accessTokenMapper, - DefaultTokenMapper $defaultTokenMapper, IL10N $l ) { parent::__construct($appName, $request); $this->secureRandom = $secureRandom; $this->clientMapper = $clientMapper; $this->accessTokenMapper = $accessTokenMapper; - $this->defaultTokenMapper = $defaultTokenMapper; $this->l = $l; } @@ -106,7 +93,6 @@ public function addClient(string $name, public function deleteClient(int $id): JSONResponse { $client = $this->clientMapper->getByUid($id); $this->accessTokenMapper->deleteByClientId($id); - $this->defaultTokenMapper->deleteByName($client->getName()); $this->clientMapper->delete($client); return new JSONResponse([]); } diff --git a/apps/oauth2/tests/Controller/OauthApiControllerTest.php b/apps/oauth2/tests/Controller/OauthApiControllerTest.php index e723877a7b4d0..24385e785e50e 100644 --- a/apps/oauth2/tests/Controller/OauthApiControllerTest.php +++ b/apps/oauth2/tests/Controller/OauthApiControllerTest.php @@ -27,8 +27,8 @@ use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\IProvider as TokenProvider; +use OC\Authentication\Token\PublicKeyToken; use OC\Security\Bruteforce\Throttler; use OCA\OAuth2\Controller\OauthApiController; use OCA\OAuth2\Db\AccessToken; @@ -238,7 +238,7 @@ public function testGetTokenValidAppToken() { 'validrefresh' )->willReturn('decryptedToken'); - $appToken = new DefaultToken(); + $appToken = new PublicKeyToken(); $appToken->setUid('userId'); $this->tokenProvider->method('getTokenById') ->with(1337) @@ -267,7 +267,7 @@ public function testGetTokenValidAppToken() { $this->tokenProvider->expects($this->once()) ->method('updateToken') ->with( - $this->callback(function (DefaultToken $token) { + $this->callback(function (PublicKeyToken $token) { return $token->getExpires() === 4600; }) ); @@ -330,7 +330,7 @@ public function testGetTokenValidAppTokenBasicAuth() { 'validrefresh' )->willReturn('decryptedToken'); - $appToken = new DefaultToken(); + $appToken = new PublicKeyToken(); $appToken->setUid('userId'); $this->tokenProvider->method('getTokenById') ->with(1337) @@ -359,7 +359,7 @@ public function testGetTokenValidAppTokenBasicAuth() { $this->tokenProvider->expects($this->once()) ->method('updateToken') ->with( - $this->callback(function (DefaultToken $token) { + $this->callback(function (PublicKeyToken $token) { return $token->getExpires() === 4600; }) ); @@ -425,7 +425,7 @@ public function testGetTokenExpiredAppToken() { 'validrefresh' )->willReturn('decryptedToken'); - $appToken = new DefaultToken(); + $appToken = new PublicKeyToken(); $appToken->setUid('userId'); $this->tokenProvider->method('getTokenById') ->with(1337) @@ -454,7 +454,7 @@ public function testGetTokenExpiredAppToken() { $this->tokenProvider->expects($this->once()) ->method('updateToken') ->with( - $this->callback(function (DefaultToken $token) { + $this->callback(function (PublicKeyToken $token) { return $token->getExpires() === 4600; }) ); diff --git a/apps/oauth2/tests/Controller/SettingsControllerTest.php b/apps/oauth2/tests/Controller/SettingsControllerTest.php index 40785e280a0d3..4954d379f9d31 100644 --- a/apps/oauth2/tests/Controller/SettingsControllerTest.php +++ b/apps/oauth2/tests/Controller/SettingsControllerTest.php @@ -26,7 +26,6 @@ */ namespace OCA\OAuth2\Tests\Controller; -use OC\Authentication\Token\DefaultTokenMapper; use OCA\OAuth2\Controller\SettingsController; use OCA\OAuth2\Db\AccessTokenMapper; use OCA\OAuth2\Db\Client; @@ -47,8 +46,6 @@ class SettingsControllerTest extends TestCase { private $secureRandom; /** @var AccessTokenMapper|\PHPUnit\Framework\MockObject\MockObject */ private $accessTokenMapper; - /** @var DefaultTokenMapper|\PHPUnit\Framework\MockObject\MockObject */ - private $defaultTokenMapper; /** @var SettingsController */ private $settingsController; @@ -59,7 +56,6 @@ protected function setUp(): void { $this->clientMapper = $this->createMock(ClientMapper::class); $this->secureRandom = $this->createMock(ISecureRandom::class); $this->accessTokenMapper = $this->createMock(AccessTokenMapper::class); - $this->defaultTokenMapper = $this->createMock(DefaultTokenMapper::class); $l = $this->createMock(IL10N::class); $l->method('t') ->willReturnArgument(0); @@ -70,7 +66,6 @@ protected function setUp(): void { $this->clientMapper, $this->secureRandom, $this->accessTokenMapper, - $this->defaultTokenMapper, $l ); } @@ -136,10 +131,6 @@ public function testDeleteClient() { ->expects($this->once()) ->method('deleteByClientId') ->with(123); - $this->defaultTokenMapper - ->expects($this->once()) - ->method('deleteByName') - ->with('My Client Name'); $this->clientMapper ->method('delete') ->with($client); diff --git a/apps/settings/tests/Controller/AuthSettingsControllerTest.php b/apps/settings/tests/Controller/AuthSettingsControllerTest.php index 477d0fcc8f59b..b744b942e093b 100644 --- a/apps/settings/tests/Controller/AuthSettingsControllerTest.php +++ b/apps/settings/tests/Controller/AuthSettingsControllerTest.php @@ -32,10 +32,10 @@ use OC\AppFramework\Http; use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; use OC\Authentication\Token\IWipeableToken; +use OC\Authentication\Token\PublicKeyToken; use OC\Authentication\Token\RemoteWipe; use OCA\Settings\Controller\AuthSettingsController; use OCP\Activity\IEvent; @@ -178,7 +178,7 @@ public function testCreateInvalidToken() { public function testDestroy() { $tokenId = 124; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $this->mockGetTokenById($tokenId, $token); $this->mockActivityManager(); @@ -200,7 +200,7 @@ public function testDestroy() { public function testDestroyExpired() { $tokenId = 124; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $token->expects($this->exactly(2)) ->method('getId') @@ -224,7 +224,7 @@ public function testDestroyExpired() { public function testDestroyWrongUser() { $tokenId = 124; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $this->mockGetTokenById($tokenId, $token); @@ -252,7 +252,7 @@ public function dataRenameToken(): array { */ public function testUpdateRename(string $name, string $newName): void { $tokenId = 42; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $this->mockGetTokenById($tokenId, $token); $this->mockActivityManager(); @@ -295,7 +295,7 @@ public function dataUpdateFilesystemScope(): array { */ public function testUpdateFilesystemScope(bool $filesystem, bool $newFilesystem): void { $tokenId = 42; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $this->mockGetTokenById($tokenId, $token); $this->mockActivityManager(); @@ -325,7 +325,7 @@ public function testUpdateFilesystemScope(bool $filesystem, bool $newFilesystem) public function testUpdateNoChange(): void { $tokenId = 42; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $this->mockGetTokenById($tokenId, $token); @@ -356,7 +356,7 @@ public function testUpdateNoChange(): void { public function testUpdateExpired() { $tokenId = 42; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $token->expects($this->once()) ->method('getUID') @@ -376,7 +376,7 @@ public function testUpdateExpired() { public function testUpdateTokenWrongUser() { $tokenId = 42; - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(PublicKeyToken::class); $this->mockGetTokenById($tokenId, $token); diff --git a/apps/settings/tests/Settings/Personal/Security/AuthtokensTest.php b/apps/settings/tests/Settings/Personal/Security/AuthtokensTest.php index 3ee39c3624c8a..8fae0a44d8ff4 100644 --- a/apps/settings/tests/Settings/Personal/Security/AuthtokensTest.php +++ b/apps/settings/tests/Settings/Personal/Security/AuthtokensTest.php @@ -25,8 +25,8 @@ */ namespace OCA\Settings\Tests\Settings\Personal\Security; -use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\IProvider as IAuthTokenProvider; +use OC\Authentication\Token\PublicKeyToken; use OCA\Settings\Settings\Personal\Security\Authtokens; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; @@ -74,15 +74,15 @@ protected function setUp(): void { } public function testGetForm() { - $token1 = new DefaultToken(); + $token1 = new PublicKeyToken(); $token1->setId(100); - $token2 = new DefaultToken(); + $token2 = new PublicKeyToken(); $token2->setId(200); $tokens = [ $token1, $token2, ]; - $sessionToken = new DefaultToken(); + $sessionToken = new PublicKeyToken(); $sessionToken->setId(100); $this->authTokenProvider->expects($this->once()) diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 09d5159369eb2..70d298a851dcf 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -728,10 +728,6 @@ 'OC\\Authentication\\Login\\WebAuthnChain' => $baseDir . '/lib/private/Authentication/Login/WebAuthnChain.php', 'OC\\Authentication\\Login\\WebAuthnLoginCommand' => $baseDir . '/lib/private/Authentication/Login/WebAuthnLoginCommand.php', 'OC\\Authentication\\Notifications\\Notifier' => $baseDir . '/lib/private/Authentication/Notifications/Notifier.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', - 'OC\\Authentication\\Token\\DefaultTokenProvider' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenProvider.php', 'OC\\Authentication\\Token\\INamedToken' => $baseDir . '/lib/private/Authentication/Token/INamedToken.php', 'OC\\Authentication\\Token\\IProvider' => $baseDir . '/lib/private/Authentication/Token/IProvider.php', 'OC\\Authentication\\Token\\IToken' => $baseDir . '/lib/private/Authentication/Token/IToken.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 932de0b78582a..280c590cd9a37 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -757,10 +757,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Login\\WebAuthnChain' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/WebAuthnChain.php', 'OC\\Authentication\\Login\\WebAuthnLoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/WebAuthnLoginCommand.php', 'OC\\Authentication\\Notifications\\Notifier' => __DIR__ . '/../../..' . '/lib/private/Authentication/Notifications/Notifier.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', - 'OC\\Authentication\\Token\\DefaultTokenProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenProvider.php', 'OC\\Authentication\\Token\\INamedToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/INamedToken.php', 'OC\\Authentication\\Token\\IProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IProvider.php', 'OC\\Authentication\\Token\\IToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IToken.php', diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php deleted file mode 100644 index b649fdbb6aff4..0000000000000 --- a/lib/private/Authentication/Token/DefaultToken.php +++ /dev/null @@ -1,209 +0,0 @@ - - * @author Daniel Kesselberg - * @author Robin Appelman - * @author Roeland Jago Douma - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ -namespace OC\Authentication\Token; - -use OCP\AppFramework\Db\Entity; - -/** - * @method void setId(int $id) - * @method void setUid(string $uid); - * @method void setLoginName(string $loginname) - * @method string getToken() - * @method void setType(int $type) - * @method int getType() - * @method void setRemember(int $remember) - * @method void setLastActivity(int $lastactivity) - * @method int getLastActivity() - * @method void setVersion(int $version) - */ -class DefaultToken extends Entity implements INamedToken { - public const VERSION = 1; - - /** @var string user UID */ - protected $uid; - - /** @var string login name used for generating the token */ - protected $loginName; - - /** @var string encrypted user password */ - protected $password; - - /** @var string token name (e.g. browser/OS) */ - protected $name; - - /** @var string */ - protected $token; - - /** @var int */ - protected $type; - - /** @var int */ - protected $remember; - - /** @var int */ - protected $lastActivity; - - /** @var int */ - protected $lastCheck; - - /** @var string */ - protected $scope; - - /** @var int */ - protected $expires; - - /** @var int */ - protected $version; - - public function __construct() { - $this->addType('uid', 'string'); - $this->addType('loginName', 'string'); - $this->addType('password', 'string'); - $this->addType('name', 'string'); - $this->addType('token', 'string'); - $this->addType('type', 'int'); - $this->addType('remember', 'int'); - $this->addType('lastActivity', 'int'); - $this->addType('lastCheck', 'int'); - $this->addType('scope', 'string'); - $this->addType('expires', 'int'); - $this->addType('version', 'int'); - } - - public function getId(): int { - return $this->id; - } - - public function getUID(): string { - return $this->uid; - } - - /** - * Get the login name used when generating the token - * - * @return string - */ - public function getLoginName(): string { - return parent::getLoginName(); - } - - /** - * Get the (encrypted) login password - * - * @return string|null - */ - public function getPassword() { - return parent::getPassword(); - } - - public function jsonSerialize(): array { - return [ - 'id' => $this->id, - 'name' => $this->name, - 'lastActivity' => $this->lastActivity, - 'type' => $this->type, - 'scope' => $this->getScopeAsArray() - ]; - } - - /** - * Get the timestamp of the last password check - * - * @return int - */ - public function getLastCheck(): int { - return parent::getLastCheck(); - } - - /** - * Get the timestamp of the last password check - * - * @param int $time - */ - public function setLastCheck(int $time) { - parent::setLastCheck($time); - } - - public function getScope(): string { - $scope = parent::getScope(); - if ($scope === null) { - return ''; - } - - return $scope; - } - - public function getScopeAsArray(): array { - $scope = json_decode($this->getScope(), true); - if (!$scope) { - return [ - 'filesystem' => true - ]; - } - return $scope; - } - - public function setScope($scope) { - if (\is_array($scope)) { - parent::setScope(json_encode($scope)); - } else { - parent::setScope((string)$scope); - } - } - - public function getName(): string { - return parent::getName(); - } - - public function setName(string $name): void { - parent::setName($name); - } - - public function getRemember(): int { - return parent::getRemember(); - } - - public function setToken(string $token) { - parent::setToken($token); - } - - public function setPassword(string $password = null) { - parent::setPassword($password); - } - - public function setExpires($expires) { - parent::setExpires($expires); - } - - /** - * @return int|null - */ - public function getExpires() { - return parent::getExpires(); - } -} diff --git a/lib/private/Authentication/Token/DefaultTokenCleanupJob.php b/lib/private/Authentication/Token/DefaultTokenCleanupJob.php deleted file mode 100644 index c3d80beac693a..0000000000000 --- a/lib/private/Authentication/Token/DefaultTokenCleanupJob.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @author Morris Jobke - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ -namespace OC\Authentication\Token; - -use OC; -use OC\BackgroundJob\Job; - -class DefaultTokenCleanupJob extends Job { - protected function run($argument) { - /* @var $provider IProvider */ - $provider = OC::$server->query(IProvider::class); - $provider->invalidateOldTokens(); - } -} diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php deleted file mode 100644 index 6ceb777c30fc7..0000000000000 --- a/lib/private/Authentication/Token/DefaultTokenMapper.php +++ /dev/null @@ -1,172 +0,0 @@ - - * @author Christoph Wurst - * @author Lukas Reschke - * @author Marcel Waldvogel - * @author Robin Appelman - * @author Roeland Jago Douma - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ -namespace OC\Authentication\Token; - -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Db\QBMapper; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IDBConnection; - -/** - * @template-extends QBMapper - */ -class DefaultTokenMapper extends QBMapper { - public function __construct(IDBConnection $db) { - parent::__construct($db, 'authtoken'); - } - - /** - * Invalidate (delete) a given token - * - * @param string $token - */ - public function invalidate(string $token) { - /* @var $qb IQueryBuilder */ - $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') - ->where($qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR))) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))) - ->execute(); - } - - /** - * @param int $olderThan - * @param int $remember - */ - public function invalidateOld(int $olderThan, int $remember = IToken::DO_NOT_REMEMBER) { - /* @var $qb IQueryBuilder */ - $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') - ->where($qb->expr()->lt('last_activity', $qb->createNamedParameter($olderThan, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->eq('remember', $qb->createNamedParameter($remember, IQueryBuilder::PARAM_INT))) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))) - ->execute(); - } - - /** - * Get the user UID for the given token - * - * @param string $token - * @throws DoesNotExistException - * @return DefaultToken - */ - public function getToken(string $token): DefaultToken { - /* @var $qb IQueryBuilder */ - $qb = $this->db->getQueryBuilder(); - $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'token', 'type', 'remember', 'last_activity', 'last_check', 'scope', 'expires', 'version') - ->from('authtoken') - ->where($qb->expr()->eq('token', $qb->createNamedParameter($token))) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))) - ->execute(); - - $data = $result->fetch(); - $result->closeCursor(); - if ($data === false) { - throw new DoesNotExistException('token does not exist'); - } - return DefaultToken::fromRow($data); - } - - /** - * Get the token for $id - * - * @param int $id - * @throws DoesNotExistException - * @return DefaultToken - */ - public function getTokenById(int $id): DefaultToken { - /* @var $qb IQueryBuilder */ - $qb = $this->db->getQueryBuilder(); - $result = $qb->select('id', 'uid', 'login_name', 'password', 'name', 'token', 'type', 'remember', 'last_activity', 'last_check', 'scope', 'expires', 'version') - ->from('authtoken') - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))) - ->execute(); - - $data = $result->fetch(); - $result->closeCursor(); - if ($data === false) { - throw new DoesNotExistException('token does not exist'); - } - return DefaultToken::fromRow($data); - } - - /** - * Get all tokens of a user - * - * The provider may limit the number of result rows in case of an abuse - * where a high number of (session) tokens is generated - * - * @param string $uid - * @return DefaultToken[] - */ - public function getTokenByUser(string $uid): array { - /* @var $qb IQueryBuilder */ - $qb = $this->db->getQueryBuilder(); - $qb->select('id', 'uid', 'login_name', 'password', 'name', 'token', 'type', 'remember', 'last_activity', 'last_check', 'scope', 'expires', 'version') - ->from('authtoken') - ->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid))) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))) - ->setMaxResults(1000); - $result = $qb->execute(); - $data = $result->fetchAll(); - $result->closeCursor(); - - $entities = array_map(function ($row) { - return DefaultToken::fromRow($row); - }, $data); - - return $entities; - } - - public function deleteById(string $uid, int $id) { - /* @var $qb IQueryBuilder */ - $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($uid))) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))); - $qb->execute(); - } - - /** - * delete all auth token which belong to a specific client if the client was deleted - * - * @param string $name - */ - public function deleteByName(string $name) { - $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') - ->where($qb->expr()->eq('name', $qb->createNamedParameter($name), IQueryBuilder::PARAM_STR)) - ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(DefaultToken::VERSION, IQueryBuilder::PARAM_INT))); - $qb->execute(); - } -} diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php deleted file mode 100644 index c10d7f17bc2af..0000000000000 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ /dev/null @@ -1,343 +0,0 @@ - - * - * @author Christoph Wurst - * @author Flávio Gomes da Silva Lisboa - * @author Joas Schilling - * @author Lukas Reschke - * @author Martin - * @author Robin Appelman - * @author Roeland Jago Douma - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ -namespace OC\Authentication\Token; - -use Exception; -use OC\Authentication\Exceptions\ExpiredTokenException; -use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Exceptions\PasswordlessTokenException; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Utility\ITimeFactory; -use OCP\IConfig; -use OCP\Security\ICrypto; -use Psr\Log\LoggerInterface; - -class DefaultTokenProvider implements IProvider { - - /** @var DefaultTokenMapper */ - private $mapper; - - /** @var ICrypto */ - private $crypto; - - /** @var IConfig */ - private $config; - - /** @var LoggerInterface */ - private $logger; - - /** @var ITimeFactory */ - private $time; - - public function __construct(DefaultTokenMapper $mapper, - ICrypto $crypto, - IConfig $config, - LoggerInterface $logger, - ITimeFactory $time) { - $this->mapper = $mapper; - $this->crypto = $crypto; - $this->config = $config; - $this->logger = $logger; - $this->time = $time; - } - - /** - * {@inheritDoc} - */ - public function generateToken(string $token, - string $uid, - string $loginName, - ?string $password, - string $name, - int $type = IToken::TEMPORARY_TOKEN, - int $remember = IToken::DO_NOT_REMEMBER): IToken { - $dbToken = new DefaultToken(); - $dbToken->setUid($uid); - $dbToken->setLoginName($loginName); - if (!is_null($password)) { - $dbToken->setPassword($this->encryptPassword($password, $token)); - } - $dbToken->setName($name); - $dbToken->setToken($this->hashToken($token)); - $dbToken->setType($type); - $dbToken->setRemember($remember); - $dbToken->setLastActivity($this->time->getTime()); - $dbToken->setLastCheck($this->time->getTime()); - $dbToken->setVersion(DefaultToken::VERSION); - - $this->mapper->insert($dbToken); - - return $dbToken; - } - - /** - * Save the updated token - * - * @param IToken $token - * @throws InvalidTokenException - */ - public function updateToken(IToken $token) { - if (!($token instanceof DefaultToken)) { - throw new InvalidTokenException("Invalid token type"); - } - $this->mapper->update($token); - } - - /** - * Update token activity timestamp - * - * @throws InvalidTokenException - * @param IToken $token - */ - public function updateTokenActivity(IToken $token) { - if (!($token instanceof DefaultToken)) { - throw new InvalidTokenException("Invalid token type"); - } - /** @var DefaultToken $token */ - $now = $this->time->getTime(); - if ($token->getLastActivity() < ($now - 60)) { - // Update token only once per minute - $token->setLastActivity($now); - $this->mapper->update($token); - } - } - - public function getTokenByUser(string $uid): array { - return $this->mapper->getTokenByUser($uid); - } - - /** - * Get a token by token - * - * @param string $tokenId - * @throws InvalidTokenException - * @throws ExpiredTokenException - * @return IToken - */ - public function getToken(string $tokenId): IToken { - try { - $token = $this->mapper->getToken($this->hashToken($tokenId)); - } catch (DoesNotExistException $ex) { - throw new InvalidTokenException("Token does not exist", 0, $ex); - } - - if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) { - throw new ExpiredTokenException($token); - } - - return $token; - } - - /** - * Get a token by token id - * - * @param int $tokenId - * @throws InvalidTokenException - * @throws ExpiredTokenException - * @return IToken - */ - public function getTokenById(int $tokenId): IToken { - try { - $token = $this->mapper->getTokenById($tokenId); - } catch (DoesNotExistException $ex) { - throw new InvalidTokenException("Token with ID $tokenId does not exist", 0, $ex); - } - - if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) { - throw new ExpiredTokenException($token); - } - - return $token; - } - - /** - * @param string $oldSessionId - * @param string $sessionId - * @throws InvalidTokenException - * @return IToken - */ - public function renewSessionToken(string $oldSessionId, string $sessionId): IToken { - $token = $this->getToken($oldSessionId); - - $newToken = new DefaultToken(); - $newToken->setUid($token->getUID()); - $newToken->setLoginName($token->getLoginName()); - if (!is_null($token->getPassword())) { - $password = $this->decryptPassword($token->getPassword(), $oldSessionId); - $newToken->setPassword($this->encryptPassword($password, $sessionId)); - } - $newToken->setName($token->getName()); - $newToken->setToken($this->hashToken($sessionId)); - $newToken->setType(IToken::TEMPORARY_TOKEN); - $newToken->setRemember($token->getRemember()); - $newToken->setLastActivity($this->time->getTime()); - $this->mapper->insert($newToken); - $this->mapper->delete($token); - - return $newToken; - } - - /** - * @param IToken $savedToken - * @param string $tokenId session token - * @throws InvalidTokenException - * @throws PasswordlessTokenException - * @return string - */ - public function getPassword(IToken $savedToken, string $tokenId): string { - $password = $savedToken->getPassword(); - if ($password === null || $password === '') { - throw new PasswordlessTokenException(); - } - return $this->decryptPassword($password, $tokenId); - } - - /** - * Encrypt and set the password of the given token - * - * @param IToken $token - * @param string $tokenId - * @param string $password - * @throws InvalidTokenException - */ - public function setPassword(IToken $token, string $tokenId, string $password) { - if (!($token instanceof DefaultToken)) { - throw new InvalidTokenException("Invalid token type"); - } - /** @var DefaultToken $token */ - $token->setPassword($this->encryptPassword($password, $tokenId)); - $this->mapper->update($token); - } - - /** - * Invalidate (delete) the given session token - * - * @param string $token - */ - public function invalidateToken(string $token) { - $this->mapper->invalidate($this->hashToken($token)); - } - - public function invalidateTokenById(string $uid, int $id) { - $this->mapper->deleteById($uid, $id); - } - - /** - * Invalidate (delete) old session tokens - */ - public function invalidateOldTokens() { - $olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24); - $this->logger->debug('Invalidating session tokens older than ' . date('c', $olderThan), ['app' => 'cron']); - $this->mapper->invalidateOld($olderThan, IToken::DO_NOT_REMEMBER); - $rememberThreshold = $this->time->getTime() - (int) $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); - $this->logger->debug('Invalidating remembered session tokens older than ' . date('c', $rememberThreshold), ['app' => 'cron']); - $this->mapper->invalidateOld($rememberThreshold, IToken::REMEMBER); - } - - /** - * Rotate the token. Usefull for for example oauth tokens - * - * @param IToken $token - * @param string $oldTokenId - * @param string $newTokenId - * @return IToken - */ - public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken { - try { - $password = $this->getPassword($token, $oldTokenId); - $token->setPassword($this->encryptPassword($password, $newTokenId)); - } catch (PasswordlessTokenException $e) { - } - - $token->setToken($this->hashToken($newTokenId)); - $this->updateToken($token); - - return $token; - } - - /** - * @param string $token - * @return string - */ - private function hashToken(string $token): string { - $secret = $this->config->getSystemValue('secret'); - return hash('sha512', $token . $secret); - } - - /** - * Encrypt the given password - * - * The token is used as key - * - * @param string $password - * @param string $token - * @return string encrypted password - */ - private function encryptPassword(string $password, string $token): string { - $secret = $this->config->getSystemValue('secret'); - return $this->crypto->encrypt($password, $token . $secret); - } - - /** - * Decrypt the given password - * - * The token is used as key - * - * @param string $password - * @param string $token - * @throws InvalidTokenException - * @return string the decrypted key - */ - private function decryptPassword(string $password, string $token): string { - $secret = $this->config->getSystemValue('secret'); - try { - return $this->crypto->decrypt($password, $token . $secret); - } catch (Exception $ex) { - // Delete the invalid token - $this->invalidateToken($token); - throw new InvalidTokenException("Can not decrypt token password: " . $ex->getMessage(), 0, $ex); - } - } - - public function markPasswordInvalid(IToken $token, string $tokenId) { - if (!($token instanceof DefaultToken)) { - throw new InvalidTokenException("Invalid token type"); - } - - //No need to mark as invalid. We just invalide default tokens - $this->invalidateToken($tokenId); - } - - public function updatePasswords(string $uid, string $password) { - // Nothing to do here - } -} diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php index b718ce73ea478..0a7a821e23e7e 100644 --- a/lib/private/Authentication/Token/Manager.php +++ b/lib/private/Authentication/Token/Manager.php @@ -35,14 +35,10 @@ class Manager implements IProvider { - /** @var DefaultTokenProvider */ - private $defaultTokenProvider; - /** @var PublicKeyTokenProvider */ private $publicKeyTokenProvider; - public function __construct(DefaultTokenProvider $defaultTokenProvider, PublicKeyTokenProvider $publicKeyTokenProvider) { - $this->defaultTokenProvider = $defaultTokenProvider; + public function __construct(PublicKeyTokenProvider $publicKeyTokenProvider) { $this->publicKeyTokenProvider = $publicKeyTokenProvider; } @@ -117,10 +113,7 @@ public function updateTokenActivity(IToken $token) { * @return IToken[] */ public function getTokenByUser(string $uid): array { - $old = $this->defaultTokenProvider->getTokenByUser($uid); - $new = $this->publicKeyTokenProvider->getTokenByUser($uid); - - return array_merge($old, $new); + return $this->publicKeyTokenProvider->getTokenByUser($uid); } /** @@ -139,19 +132,8 @@ public function getToken(string $tokenId): IToken { } catch (ExpiredTokenException $e) { throw $e; } catch (InvalidTokenException $e) { - // No worries we try to convert it to a PublicKey Token - } - - //Convert! - $token = $this->defaultTokenProvider->getToken($tokenId); - - try { - $password = $this->defaultTokenProvider->getPassword($token, $tokenId); - } catch (PasswordlessTokenException $e) { - $password = null; + throw $e; } - - return $this->publicKeyTokenProvider->convertToken($token, $tokenId, $password); } /** @@ -169,7 +151,7 @@ public function getTokenById(int $tokenId): IToken { } catch (WipeTokenException $e) { throw $e; } catch (InvalidTokenException $e) { - return $this->defaultTokenProvider->getTokenById($tokenId); + throw $e; } } @@ -185,7 +167,7 @@ public function renewSessionToken(string $oldSessionId, string $sessionId): ITok } catch (ExpiredTokenException $e) { throw $e; } catch (InvalidTokenException $e) { - return $this->defaultTokenProvider->renewSessionToken($oldSessionId, $sessionId); + throw $e; } } @@ -207,17 +189,14 @@ public function setPassword(IToken $token, string $tokenId, string $password) { } public function invalidateToken(string $token) { - $this->defaultTokenProvider->invalidateToken($token); $this->publicKeyTokenProvider->invalidateToken($token); } public function invalidateTokenById(string $uid, int $id) { - $this->defaultTokenProvider->invalidateTokenById($uid, $id); $this->publicKeyTokenProvider->invalidateTokenById($uid, $id); } public function invalidateOldTokens() { - $this->defaultTokenProvider->invalidateOldTokens(); $this->publicKeyTokenProvider->invalidateOldTokens(); } @@ -230,16 +209,6 @@ public function invalidateOldTokens() { * @throws \RuntimeException when OpenSSL reports a problem */ public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken { - if ($token instanceof DefaultToken) { - try { - $password = $this->defaultTokenProvider->getPassword($token, $oldTokenId); - } catch (PasswordlessTokenException $e) { - $password = null; - } - - return $this->publicKeyTokenProvider->convertToken($token, $newTokenId, $password); - } - if ($token instanceof PublicKeyToken) { return $this->publicKeyTokenProvider->rotate($token, $oldTokenId, $newTokenId); } @@ -253,9 +222,6 @@ public function rotate(IToken $token, string $oldTokenId, string $newTokenId): I * @throws InvalidTokenException */ private function getProvider(IToken $token): IProvider { - if ($token instanceof DefaultToken) { - return $this->defaultTokenProvider; - } if ($token instanceof PublicKeyToken) { return $this->publicKeyTokenProvider; } @@ -268,7 +234,6 @@ public function markPasswordInvalid(IToken $token, string $tokenId) { } public function updatePasswords(string $uid, string $password) { - $this->defaultTokenProvider->updatePasswords($uid, $password); $this->publicKeyTokenProvider->updatePasswords($uid, $password); } } diff --git a/lib/private/Authentication/Token/PublicKeyTokenMapper.php b/lib/private/Authentication/Token/PublicKeyTokenMapper.php index 0c532312acee8..7b11ef8adf3b3 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenMapper.php +++ b/lib/private/Authentication/Token/PublicKeyTokenMapper.php @@ -48,7 +48,7 @@ public function __construct(IDBConnection $db) { public function invalidate(string $token) { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') + $qb->delete($this->tableName) ->where($qb->expr()->eq('token', $qb->createNamedParameter($token))) ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT))) ->execute(); @@ -61,7 +61,7 @@ public function invalidate(string $token) { public function invalidateOld(int $olderThan, int $remember = IToken::DO_NOT_REMEMBER) { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') + $qb->delete($this->tableName) ->where($qb->expr()->lt('last_activity', $qb->createNamedParameter($olderThan, IQueryBuilder::PARAM_INT))) ->andWhere($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN, IQueryBuilder::PARAM_INT))) ->andWhere($qb->expr()->eq('remember', $qb->createNamedParameter($remember, IQueryBuilder::PARAM_INT))) @@ -78,7 +78,7 @@ public function getToken(string $token): PublicKeyToken { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $result = $qb->select('*') - ->from('authtoken') + ->from($this->tableName) ->where($qb->expr()->eq('token', $qb->createNamedParameter($token))) ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT))) ->execute(); @@ -100,7 +100,7 @@ public function getTokenById(int $id): PublicKeyToken { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $result = $qb->select('*') - ->from('authtoken') + ->from($this->tableName) ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT))) ->execute(); @@ -126,7 +126,7 @@ public function getTokenByUser(string $uid): array { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $qb->select('*') - ->from('authtoken') + ->from($this->tableName) ->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid))) ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT))) ->setMaxResults(1000); @@ -144,7 +144,7 @@ public function getTokenByUser(string $uid): array { public function deleteById(string $uid, int $id) { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') + $qb->delete($this->tableName) ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($uid))) ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT))); @@ -158,7 +158,7 @@ public function deleteById(string $uid, int $id) { */ public function deleteByName(string $name) { $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') + $qb->delete($this->tableName) ->where($qb->expr()->eq('name', $qb->createNamedParameter($name), IQueryBuilder::PARAM_STR)) ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(PublicKeyToken::VERSION, IQueryBuilder::PARAM_INT))); $qb->execute(); @@ -167,7 +167,7 @@ public function deleteByName(string $name) { public function deleteTempToken(PublicKeyToken $except) { $qb = $this->db->getQueryBuilder(); - $qb->delete('authtoken') + $qb->delete($this->tableName) ->where($qb->expr()->eq('uid', $qb->createNamedParameter($except->getUID()))) ->andWhere($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN))) ->andWhere($qb->expr()->neq('id', $qb->createNamedParameter($except->getId()))) @@ -179,7 +179,7 @@ public function deleteTempToken(PublicKeyToken $except) { public function hasExpiredTokens(string $uid): bool { $qb = $this->db->getQueryBuilder(); $qb->select('*') - ->from('authtoken') + ->from($this->tableName) ->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid))) ->andWhere($qb->expr()->eq('password_invalid', $qb->createNamedParameter(true), IQueryBuilder::PARAM_BOOL)) ->setMaxResults(1); diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index b9cfce6c86930..04781457a7a86 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -321,30 +321,6 @@ private function hashToken(string $token): string { return hash('sha512', $token . $secret); } - /** - * Convert a DefaultToken to a publicKeyToken - * This will also be updated directly in the Database - * @throws \RuntimeException when OpenSSL reports a problem - */ - public function convertToken(DefaultToken $defaultToken, string $token, $password): PublicKeyToken { - $this->cache->clear(); - - $pkToken = $this->newToken( - $token, - $defaultToken->getUID(), - $defaultToken->getLoginName(), - $password, - $defaultToken->getName(), - $defaultToken->getType(), - $defaultToken->getRemember() - ); - - $pkToken->setExpires($defaultToken->getExpires()); - $pkToken->setId($defaultToken->getId()); - - return $this->mapper->update($pkToken); - } - /** * @throws \RuntimeException when OpenSSL reports a problem */ diff --git a/lib/private/Server.php b/lib/private/Server.php index baebbe7558d92..92f0ef57f0fa1 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -522,11 +522,11 @@ public function __construct($webRoot, \OC\Config $config) { $session = new \OC\Session\Memory(''); $timeFactory = new TimeFactory(); // Token providers might require a working database. This code - // might however be called when ownCloud is not yet setup. + // might however be called when Nextcloud is not yet setup. if (\OC::$server->get(SystemConfig::class)->getValue('installed', false)) { - $defaultTokenProvider = $c->get(IProvider::class); + $provider = $c->get(IProvider::class); } else { - $defaultTokenProvider = null; + $provider = null; } $legacyDispatcher = $c->get(SymfonyAdapter::class); @@ -535,7 +535,7 @@ public function __construct($webRoot, \OC\Config $config) { $manager, $session, $timeFactory, - $defaultTokenProvider, + $provider, $c->get(\OCP\IConfig::class), $c->get(ISecureRandom::class), $c->getLockdownManager(), diff --git a/lib/private/Setup.php b/lib/private/Setup.php index 589bbb273c06d..177ede1e29254 100644 --- a/lib/private/Setup.php +++ b/lib/private/Setup.php @@ -52,8 +52,7 @@ use Exception; use InvalidArgumentException; use OC\App\AppStore\Bundles\BundleFetcher; -use OC\Authentication\Token\DefaultTokenCleanupJob; -use OC\Authentication\Token\DefaultTokenProvider; +use OC\Authentication\Token\PublicKeyTokenProvider; use OC\Log\Rotate; use OC\Preview\BackgroundCleanupJob; use OCP\AppFramework\Utility\ITimeFactory; @@ -432,8 +431,8 @@ public function install($options) { // The token provider requires a working db, so it's not injected on setup /* @var $userSession User\Session */ $userSession = \OC::$server->getUserSession(); - $defaultTokenProvider = \OC::$server->query(DefaultTokenProvider::class); - $userSession->setTokenProvider($defaultTokenProvider); + $provider = \OC::$server->query(PublicKeyTokenProvider::class); + $userSession->setTokenProvider($provider); $userSession->login($username, $password); $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password); @@ -451,7 +450,6 @@ public function install($options) { public static function installBackgroundJobs() { $jobList = \OC::$server->getJobList(); - $jobList->add(DefaultTokenCleanupJob::class); $jobList->add(Rotate::class); $jobList->add(BackgroundCleanupJob::class); } diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 710cba84879af..e84576236b8a2 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -123,7 +123,7 @@ class Session implements IUserSession, Emitter { * @param Manager $manager * @param ISession $session * @param ITimeFactory $timeFactory - * @param IProvider $tokenProvider + * @param IProvider|null $tokenProvider * @param IConfig $config * @param ISecureRandom $random * @param ILockdownManager $lockdownManager @@ -132,7 +132,7 @@ class Session implements IUserSession, Emitter { public function __construct(Manager $manager, ISession $session, ITimeFactory $timeFactory, - $tokenProvider, + ?IProvider $tokenProvider, IConfig $config, ISecureRandom $random, ILockdownManager $lockdownManager, diff --git a/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php b/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php deleted file mode 100644 index 0991c8b1fc807..0000000000000 --- a/tests/lib/Authentication/Token/DefaultTokenCleanupJobTest.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -namespace Test\Authentication\Token; - -use OC\Authentication\Token\DefaultTokenCleanupJob; -use OC\Authentication\Token\IProvider; -use OC\Authentication\Token\Manager; -use Test\TestCase; - -class DefaultTokenCleanupJobTest extends TestCase { - - /** @var DefaultTokenCleanupJob */ - private $job; - private $tokenProvider; - - protected function setUp(): void { - parent::setUp(); - - $this->tokenProvider = $this->getMockBuilder(Manager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->overwriteService(IProvider::class, $this->tokenProvider); - $this->job = new DefaultTokenCleanupJob(); - } - - public function testRun() { - $this->tokenProvider->expects($this->once()) - ->method('invalidateOldTokens') - ->with(); - $this->invokePrivate($this->job, 'run', [null]); - } -} diff --git a/tests/lib/Authentication/Token/DefaultTokenMapperTest.php b/tests/lib/Authentication/Token/DefaultTokenMapperTest.php deleted file mode 100644 index da779be080752..0000000000000 --- a/tests/lib/Authentication/Token/DefaultTokenMapperTest.php +++ /dev/null @@ -1,233 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -namespace Test\Authentication\Token; - -use OC; -use OC\Authentication\Token\DefaultToken; -use OC\Authentication\Token\DefaultTokenMapper; -use OC\Authentication\Token\IToken; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IDBConnection; -use OCP\IUser; -use Test\TestCase; - -/** - * Class DefaultTokenMapperTest - * - * @group DB - * @package Test\Authentication - */ -class DefaultTokenMapperTest extends TestCase { - - /** @var DefaultTokenMapper */ - private $mapper; - - /** @var IDBConnection */ - private $dbConnection; - private $time; - - protected function setUp(): void { - parent::setUp(); - - $this->dbConnection = OC::$server->getDatabaseConnection(); - $this->time = time(); - $this->resetDatabase(); - - $this->mapper = new DefaultTokenMapper($this->dbConnection); - } - - private function resetDatabase() { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->delete('authtoken')->execute(); - $qb->insert('authtoken')->values([ - 'uid' => $qb->createNamedParameter('user1'), - 'login_name' => $qb->createNamedParameter('User1'), - 'password' => $qb->createNamedParameter('a75c7116460c082912d8f6860a850904|3nz5qbG1nNSLLi6V|c55365a0e54cfdfac4a175bcf11a7612aea74492277bba6e5d96a24497fa9272488787cb2f3ad34d8b9b8060934fce02f008d371df3ff3848f4aa61944851ff0'), - 'name' => $qb->createNamedParameter('Firefox on Linux'), - 'token' => $qb->createNamedParameter('9c5a2e661482b65597408a6bb6c4a3d1af36337381872ac56e445a06cdb7fea2b1039db707545c11027a4966919918b19d875a8b774840b18c6cbb7ae56fe206'), - 'type' => $qb->createNamedParameter(IToken::TEMPORARY_TOKEN), - 'last_activity' => $qb->createNamedParameter($this->time - 120, IQueryBuilder::PARAM_INT), // Two minutes ago - 'last_check' => $this->time - 60 * 10, // 10mins ago - ])->execute(); - $qb->insert('authtoken')->values([ - 'uid' => $qb->createNamedParameter('user2'), - 'login_name' => $qb->createNamedParameter('User2'), - 'password' => $qb->createNamedParameter('971a337057853344700bbeccf836519f|UwOQwyb34sJHtqPV|036d4890f8c21d17bbc7b88072d8ef049a5c832a38e97f3e3d5f9186e896c2593aee16883f617322fa242728d0236ff32d163caeb4bd45e14ca002c57a88665f'), - 'name' => $qb->createNamedParameter('Firefox on Android'), - 'token' => $qb->createNamedParameter('1504445f1524fc801035448a95681a9378ba2e83930c814546c56e5d6ebde221198792fd900c88ed5ead0555780dad1ebce3370d7e154941cd5de87eb419899b'), - 'type' => $qb->createNamedParameter(IToken::TEMPORARY_TOKEN), - 'last_activity' => $qb->createNamedParameter($this->time - 60 * 60 * 24 * 3, IQueryBuilder::PARAM_INT), // Three days ago - 'last_check' => $this->time - 10, // 10secs ago - ])->execute(); - $qb->insert('authtoken')->values([ - 'uid' => $qb->createNamedParameter('user1'), - 'login_name' => $qb->createNamedParameter('User1'), - 'password' => $qb->createNamedParameter('063de945d6f6b26862d9b6f40652f2d5|DZ/z520tfdXPtd0T|395f6b89be8d9d605e409e20b9d9abe477fde1be38a3223f9e508f979bf906e50d9eaa4dca983ca4fb22a241eb696c3f98654e7775f78c4caf13108f98642b53'), - 'name' => $qb->createNamedParameter('Iceweasel on Linux'), - 'token' => $qb->createNamedParameter('47af8697ba590fb82579b5f1b3b6e8066773a62100abbe0db09a289a62f5d980dc300fa3d98b01d7228468d1ab05c1aa14c8d14bd5b6eee9cdf1ac14864680c3'), - 'type' => $qb->createNamedParameter(IToken::TEMPORARY_TOKEN), - 'last_activity' => $qb->createNamedParameter($this->time - 120, IQueryBuilder::PARAM_INT), // Two minutes ago - 'last_check' => $this->time - 60 * 10, // 10mins ago - ])->execute(); - } - - private function getNumberOfTokens() { - $qb = $this->dbConnection->getQueryBuilder(); - $result = $qb->select($qb->func()->count('*', 'count')) - ->from('authtoken') - ->execute() - ->fetch(); - return (int) $result['count']; - } - - public function testInvalidate() { - $token = '9c5a2e661482b65597408a6bb6c4a3d1af36337381872ac56e445a06cdb7fea2b1039db707545c11027a4966919918b19d875a8b774840b18c6cbb7ae56fe206'; - - $this->mapper->invalidate($token); - - $this->assertSame(2, $this->getNumberOfTokens()); - } - - public function testInvalidateInvalid() { - $token = 'youwontfindthisoneinthedatabase'; - - $this->mapper->invalidate($token); - - $this->assertSame(3, $this->getNumberOfTokens()); - } - - public function testInvalidateOld() { - $olderThan = $this->time - 60 * 60; // One hour - - $this->mapper->invalidateOld($olderThan); - - $this->assertSame(2, $this->getNumberOfTokens()); - } - - public function testGetToken() { - $token = new DefaultToken(); - $token->setUid('user2'); - $token->setLoginName('User2'); - $token->setPassword('971a337057853344700bbeccf836519f|UwOQwyb34sJHtqPV|036d4890f8c21d17bbc7b88072d8ef049a5c832a38e97f3e3d5f9186e896c2593aee16883f617322fa242728d0236ff32d163caeb4bd45e14ca002c57a88665f'); - $token->setName('Firefox on Android'); - $token->setToken('1504445f1524fc801035448a95681a9378ba2e83930c814546c56e5d6ebde221198792fd900c88ed5ead0555780dad1ebce3370d7e154941cd5de87eb419899b'); - $token->setType(IToken::TEMPORARY_TOKEN); - $token->setRemember(IToken::DO_NOT_REMEMBER); - $token->setLastActivity($this->time - 60 * 60 * 24 * 3); - $token->setLastCheck($this->time - 10); - $token->setVersion(DefaultToken::VERSION); - - $dbToken = $this->mapper->getToken($token->getToken()); - - $token->setId($dbToken->getId()); // We don't know the ID - $token->resetUpdatedFields(); - - $this->assertEquals($token, $dbToken); - } - - - public function testGetInvalidToken() { - $this->expectException(\OCP\AppFramework\Db\DoesNotExistException::class); - - $token = 'thisisaninvalidtokenthatisnotinthedatabase'; - - $this->mapper->getToken($token); - } - - public function testGetTokenById() { - $token = new DefaultToken(); - $token->setUid('user2'); - $token->setLoginName('User2'); - $token->setPassword('971a337057853344700bbeccf836519f|UwOQwyb34sJHtqPV|036d4890f8c21d17bbc7b88072d8ef049a5c832a38e97f3e3d5f9186e896c2593aee16883f617322fa242728d0236ff32d163caeb4bd45e14ca002c57a88665f'); - $token->setName('Firefox on Android'); - $token->setToken('1504445f1524fc801035448a95681a9378ba2e83930c814546c56e5d6ebde221198792fd900c88ed5ead0555780dad1ebce3370d7e154941cd5de87eb419899b'); - $token->setType(IToken::TEMPORARY_TOKEN); - $token->setRemember(IToken::DO_NOT_REMEMBER); - $token->setLastActivity($this->time - 60 * 60 * 24 * 3); - $token->setLastCheck($this->time - 10); - $token->setVersion(DefaultToken::VERSION); - - $dbToken = $this->mapper->getToken($token->getToken()); - $token->setId($dbToken->getId()); // We don't know the ID - $token->resetUpdatedFields(); - - $dbToken = $this->mapper->getTokenById($token->getId()); - $this->assertEquals($token, $dbToken); - } - - - public function testGetTokenByIdNotFound() { - $this->expectException(\OCP\AppFramework\Db\DoesNotExistException::class); - - $this->mapper->getTokenById(-1); - } - - - public function testGetInvalidTokenById() { - $this->expectException(\OCP\AppFramework\Db\DoesNotExistException::class); - - $id = 42; - - $this->mapper->getToken($id); - } - - public function testGetTokenByUser() { - $this->assertCount(2, $this->mapper->getTokenByUser('user1')); - } - - public function testGetTokenByUserNotFound() { - $this->assertCount(0, $this->mapper->getTokenByUser('user1000')); - } - - public function testDeleteById() { - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */ - $user = $this->createMock(IUser::class); - $qb = $this->dbConnection->getQueryBuilder(); - $qb->select('id') - ->from('authtoken') - ->where($qb->expr()->eq('token', $qb->createNamedParameter('9c5a2e661482b65597408a6bb6c4a3d1af36337381872ac56e445a06cdb7fea2b1039db707545c11027a4966919918b19d875a8b774840b18c6cbb7ae56fe206'))); - $result = $qb->execute(); - $id = $result->fetch()['id']; - - $this->mapper->deleteById('user1', $id); - $this->assertEquals(2, $this->getNumberOfTokens()); - } - - public function testDeleteByIdWrongUser() { - $id = 33; - - $this->mapper->deleteById('user1000', $id); - $this->assertEquals(3, $this->getNumberOfTokens()); - } - - public function testDeleteByName() { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->select('name') - ->from('authtoken') - ->where($qb->expr()->eq('token', $qb->createNamedParameter('9c5a2e661482b65597408a6bb6c4a3d1af36337381872ac56e445a06cdb7fea2b1039db707545c11027a4966919918b19d875a8b774840b18c6cbb7ae56fe206'))); - $result = $qb->execute(); - $name = $result->fetch()['name']; - $this->mapper->deleteByName($name); - $this->assertEquals(2, $this->getNumberOfTokens()); - } -} diff --git a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php deleted file mode 100644 index 7a8915a7c1471..0000000000000 --- a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php +++ /dev/null @@ -1,552 +0,0 @@ - - * - * @copyright Copyright (c) 2016, Lukas Reschke - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see - * - */ - -namespace Test\Authentication\Token; - -use OC\Authentication\Exceptions\ExpiredTokenException; -use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Token\DefaultToken; -use OC\Authentication\Token\DefaultTokenMapper; -use OC\Authentication\Token\DefaultTokenProvider; -use OC\Authentication\Token\IToken; -use OC\Authentication\Token\PublicKeyToken; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Utility\ITimeFactory; -use OCP\IConfig; -use OCP\Security\ICrypto; -use Psr\Log\LoggerInterface; -use Test\TestCase; - -class DefaultTokenProviderTest extends TestCase { - - /** @var DefaultTokenProvider|\PHPUnit\Framework\MockObject\MockObject */ - private $tokenProvider; - /** @var DefaultTokenMapper|\PHPUnit\Framework\MockObject\MockObject */ - private $mapper; - /** @var ICrypto|\PHPUnit\Framework\MockObject\MockObject */ - private $crypto; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - /** @var int */ - private $time; - - protected function setUp(): void { - parent::setUp(); - - $this->mapper = $this->createMock(DefaultTokenMapper::class); - $this->crypto = $this->createMock(ICrypto::class); - $this->config = $this->createMock(IConfig::class); - $this->logger = $this->createMock(LoggerInterface::class); - $this->timeFactory = $this->createMock(ITimeFactory::class); - $this->time = 1313131; - $this->timeFactory->expects($this->any()) - ->method('getTime') - ->willReturn($this->time); - - $this->tokenProvider = new DefaultTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger, - $this->timeFactory); - } - - public function testGenerateToken() { - $token = 'token'; - $uid = 'user'; - $user = 'User'; - $password = 'passme'; - $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12' - . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12' - . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12' - . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; - $type = IToken::PERMANENT_TOKEN; - - $toInsert = new DefaultToken(); - $toInsert->setUid($uid); - $toInsert->setLoginName($user); - $toInsert->setPassword('encryptedpassword'); - $toInsert->setName($name); - $toInsert->setToken(hash('sha512', $token . '1f4h9s')); - $toInsert->setType($type); - $toInsert->setRemember(IToken::DO_NOT_REMEMBER); - $toInsert->setLastActivity($this->time); - $toInsert->setLastCheck($this->time); - $toInsert->setVersion(DefaultToken::VERSION); - - $this->config->expects($this->any()) - ->method('getSystemValue') - ->with('secret') - ->willReturn('1f4h9s'); - $this->crypto->expects($this->once()) - ->method('encrypt') - ->with($password, $token . '1f4h9s') - ->willReturn('encryptedpassword'); - $this->mapper->expects($this->once()) - ->method('insert') - ->with($this->equalTo($toInsert)); - - $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); - - $this->assertEquals($toInsert, $actual); - } - - public function testUpdateToken() { - $tk = new DefaultToken(); - $tk->setLastActivity($this->time - 200); - $this->mapper->expects($this->once()) - ->method('update') - ->with($tk); - - $this->tokenProvider->updateTokenActivity($tk); - - $this->assertEquals($this->time, $tk->getLastActivity()); - } - - public function testUpdateTokenDebounce() { - $tk = new DefaultToken(); - $tk->setLastActivity($this->time - 30); - $this->mapper->expects($this->never()) - ->method('update') - ->with($tk); - - $this->tokenProvider->updateTokenActivity($tk); - } - - public function testGetTokenByUser() { - $this->mapper->expects($this->once()) - ->method('getTokenByUser') - ->with('uid') - ->willReturn(['token']); - - $this->assertEquals(['token'], $this->tokenProvider->getTokenByUser('uid')); - } - - public function testGetPassword() { - $token = 'token1234'; - $tk = new DefaultToken(); - $tk->setPassword('someencryptedvalue'); - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('secret') - ->willReturn('1f4h9s'); - $this->crypto->expects($this->once()) - ->method('decrypt') - ->with('someencryptedvalue', $token . '1f4h9s') - ->willReturn('passme'); - - $actual = $this->tokenProvider->getPassword($tk, $token); - - $this->assertEquals('passme', $actual); - } - - - public function testGetPasswordPasswordLessToken() { - $this->expectException(\OC\Authentication\Exceptions\PasswordlessTokenException::class); - - $token = 'token1234'; - $tk = new DefaultToken(); - $tk->setPassword(null); - - $this->tokenProvider->getPassword($tk, $token); - } - - - public function testGetPasswordDeletesInvalidToken() { - $this->expectException(\OC\Authentication\Exceptions\InvalidTokenException::class); - - $token = 'token1234'; - $tk = new DefaultToken(); - $tk->setPassword('someencryptedvalue'); - /* @var $tokenProvider DefaultTokenProvider */ - $tokenProvider = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenProvider') - ->setMethods([ - 'invalidateToken' - ]) - ->setConstructorArgs([$this->mapper, $this->crypto, $this->config, $this->logger, - $this->timeFactory]) - ->getMock(); - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('secret') - ->willReturn('1f4h9s'); - $this->crypto->expects($this->once()) - ->method('decrypt') - ->with('someencryptedvalue', $token . '1f4h9s') - ->will($this->throwException(new \Exception('some crypto error occurred'))); - $tokenProvider->expects($this->once()) - ->method('invalidateToken') - ->with($token); - - $tokenProvider->getPassword($tk, $token); - } - - public function testSetPassword() { - $token = new DefaultToken(); - $tokenId = 'token123'; - $password = '123456'; - - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('secret') - ->willReturn('ocsecret'); - $this->crypto->expects($this->once()) - ->method('encrypt') - ->with($password, $tokenId . 'ocsecret') - ->willReturn('encryptedpassword'); - $this->mapper->expects($this->once()) - ->method('update') - ->with($token); - - $this->tokenProvider->setPassword($token, $tokenId, $password); - - $this->assertEquals('encryptedpassword', $token->getPassword()); - } - - - public function testSetPasswordInvalidToken() { - $this->expectException(\OC\Authentication\Exceptions\InvalidTokenException::class); - - $token = $this->createMock(IToken::class); - $tokenId = 'token123'; - $password = '123456'; - - $this->tokenProvider->setPassword($token, $tokenId, $password); - } - - public function testInvalidateToken() { - $this->mapper->expects($this->once()) - ->method('invalidate') - ->with(hash('sha512', 'token7')); - - $this->tokenProvider->invalidateToken('token7'); - } - - public function testInvaildateTokenById() { - $id = 123; - - $this->mapper->expects($this->once()) - ->method('deleteById') - ->with('uid', $id); - - $this->tokenProvider->invalidateTokenById('uid', $id); - } - - public function testInvalidateOldTokens() { - $defaultSessionLifetime = 60 * 60 * 24; - $defaultRememberMeLifetime = 60 * 60 * 24 * 15; - $this->config->expects($this->exactly(2)) - ->method('getSystemValue') - ->willReturnMap([ - ['session_lifetime', $defaultSessionLifetime, 150], - ['remember_login_cookie_lifetime', $defaultRememberMeLifetime, 300], - ]); - $this->mapper->expects($this->at(0)) - ->method('invalidateOld') - ->with($this->time - 150); - $this->mapper->expects($this->at(1)) - ->method('invalidateOld') - ->with($this->time - 300); - - $this->tokenProvider->invalidateOldTokens(); - } - - public function testRenewSessionTokenWithoutPassword() { - $token = $this->getMockBuilder(DefaultToken::class) - ->disableOriginalConstructor() - ->setMethods(['getUID', 'getLoginName', 'getPassword', 'getName', 'getRemember']) - ->getMock(); - $token - ->expects($this->at(0)) - ->method('getUID') - ->willReturn('UserUid'); - $token - ->expects($this->at(1)) - ->method('getLoginName') - ->willReturn('UserLoginName'); - $token - ->expects($this->at(2)) - ->method('getPassword') - ->willReturn(null); - $token - ->expects($this->at(3)) - ->method('getName') - ->willReturn('MyTokenName'); - $token - ->expects($this->at(4)) - ->method('getRemember') - ->willReturn(IToken::DO_NOT_REMEMBER); - $this->config - ->expects($this->exactly(2)) - ->method('getSystemValue') - ->with('secret') - ->willReturn('MyInstanceSecret'); - $this->mapper - ->expects($this->at(0)) - ->method('getToken') - ->with(hash('sha512', 'oldId' . 'MyInstanceSecret')) - ->willReturn($token); - $newToken = new DefaultToken(); - $newToken->setUid('UserUid'); - $newToken->setLoginName('UserLoginName'); - $newToken->setName('MyTokenName'); - $newToken->setToken(hash('sha512', 'newId' . 'MyInstanceSecret')); - $newToken->setType(IToken::TEMPORARY_TOKEN); - $newToken->setRemember(IToken::DO_NOT_REMEMBER); - $newToken->setLastActivity(1313131); - $this->mapper - ->expects($this->at(1)) - ->method('insert') - ->with($newToken); - $this->mapper - ->expects($this->at(2)) - ->method('delete') - ->with($token); - - $this->tokenProvider->renewSessionToken('oldId', 'newId'); - } - - public function testRenewSessionTokenWithPassword() { - $token = $this->getMockBuilder(DefaultToken::class) - ->disableOriginalConstructor() - ->setMethods(['getUID', 'getLoginName', 'getPassword', 'getName', 'getRemember']) - ->getMock(); - $token - ->expects($this->at(0)) - ->method('getUID') - ->willReturn('UserUid'); - $token - ->expects($this->at(1)) - ->method('getLoginName') - ->willReturn('UserLoginName'); - $token - ->expects($this->at(2)) - ->method('getPassword') - ->willReturn('EncryptedPassword'); - $token - ->expects($this->at(3)) - ->method('getPassword') - ->willReturn('EncryptedPassword'); - $token - ->expects($this->at(4)) - ->method('getName') - ->willReturn('MyTokenName'); - $token - ->expects($this->at(5)) - ->method('getRemember') - ->willReturn(IToken::REMEMBER); - $this->crypto - ->expects($this->any(0)) - ->method('decrypt') - ->with('EncryptedPassword', 'oldIdMyInstanceSecret') - ->willReturn('ClearTextPassword'); - $this->crypto - ->expects($this->any(1)) - ->method('encrypt') - ->with('ClearTextPassword', 'newIdMyInstanceSecret') - ->willReturn('EncryptedPassword'); - $this->config - ->expects($this->exactly(4)) - ->method('getSystemValue') - ->with('secret') - ->willReturn('MyInstanceSecret'); - $this->mapper - ->expects($this->at(0)) - ->method('getToken') - ->with(hash('sha512', 'oldId' . 'MyInstanceSecret')) - ->willReturn($token); - $newToken = new DefaultToken(); - $newToken->setUid('UserUid'); - $newToken->setLoginName('UserLoginName'); - $newToken->setName('MyTokenName'); - $newToken->setToken(hash('sha512', 'newId' . 'MyInstanceSecret')); - $newToken->setType(IToken::TEMPORARY_TOKEN); - $newToken->setRemember(IToken::REMEMBER); - $newToken->setLastActivity(1313131); - $newToken->setPassword('EncryptedPassword'); - $this->mapper - ->expects($this->at(1)) - ->method('insert') - ->with($this->equalTo($newToken)); - $this->mapper - ->expects($this->at(2)) - ->method('delete') - ->with($token); - - $this->tokenProvider->renewSessionToken('oldId', 'newId'); - } - - public function testGetToken() { - $token = new DefaultToken(); - - $this->config->method('getSystemValue') - ->with('secret') - ->willReturn('mysecret'); - - $this->mapper->method('getToken') - ->with( - $this->callback(function (string $token) { - return hash('sha512', 'unhashedTokenmysecret') === $token; - }) - )->willReturn($token); - - $this->assertSame($token, $this->tokenProvider->getToken('unhashedToken')); - } - - public function testGetInvalidToken() { - $this->expectException(InvalidTokenException::class); - - $this->config->method('getSystemValue') - ->with('secret') - ->willReturn('mysecret'); - - $this->mapper->method('getToken') - ->with( - $this->callback(function (string $token) { - return hash('sha512', 'unhashedTokenmysecret') === $token; - }) - )->willThrowException(new InvalidTokenException()); - - $this->tokenProvider->getToken('unhashedToken'); - } - - public function testGetExpiredToken() { - $token = new DefaultToken(); - $token->setExpires(42); - - $this->config->method('getSystemValue') - ->with('secret') - ->willReturn('mysecret'); - - $this->mapper->method('getToken') - ->with( - $this->callback(function (string $token) { - return hash('sha512', 'unhashedTokenmysecret') === $token; - }) - )->willReturn($token); - - try { - $this->tokenProvider->getToken('unhashedToken'); - } catch (ExpiredTokenException $e) { - $this->assertSame($token, $e->getToken()); - } - } - - public function testGetTokenById() { - $token = $this->createMock(DefaultToken::class); - - $this->mapper->expects($this->once()) - ->method('getTokenById') - ->with($this->equalTo(42)) - ->willReturn($token); - - $this->assertSame($token, $this->tokenProvider->getTokenById(42)); - } - - public function testGetInvalidTokenById() { - $this->expectException(InvalidTokenException::class); - - $this->mapper->expects($this->once()) - ->method('getTokenById') - ->with($this->equalTo(42)) - ->willThrowException(new DoesNotExistException('nope')); - - $this->tokenProvider->getTokenById(42); - } - - public function testGetExpiredTokenById() { - $token = new DefaultToken(); - $token->setExpires(42); - - $this->mapper->expects($this->once()) - ->method('getTokenById') - ->with($this->equalTo(42)) - ->willReturn($token); - - try { - $this->tokenProvider->getTokenById(42); - $this->fail(); - } catch (ExpiredTokenException $e) { - $this->assertSame($token, $e->getToken()); - } - } - - public function testRotate() { - $token = new DefaultToken(); - $token->setPassword('oldencryptedpassword'); - - $this->config->method('getSystemValue') - ->with('secret') - ->willReturn('mysecret'); - - $this->crypto->method('decrypt') - ->with('oldencryptedpassword', 'oldtokenmysecret') - ->willReturn('mypassword'); - $this->crypto->method('encrypt') - ->with('mypassword', 'newtokenmysecret') - ->willReturn('newencryptedpassword'); - - $this->mapper->expects($this->once()) - ->method('update') - ->with($this->callback(function (DefaultToken $token) { - return $token->getPassword() === 'newencryptedpassword' && - $token->getToken() === hash('sha512', 'newtokenmysecret'); - })); - - $this->tokenProvider->rotate($token, 'oldtoken', 'newtoken'); - } - - public function testRotateNoPassword() { - $token = new DefaultToken(); - - $this->config->method('getSystemValue') - ->with('secret') - ->willReturn('mysecret'); - - $this->mapper->expects($this->once()) - ->method('update') - ->with($this->callback(function (DefaultToken $token) { - return $token->getPassword() === null && - $token->getToken() === hash('sha512', 'newtokenmysecret'); - })); - - $this->tokenProvider->rotate($token, 'oldtoken', 'newtoken'); - } - - public function testMarkPasswordInvalidInvalidToken() { - $token = $this->createMock(PublicKeyToken::class); - - $this->expectException(InvalidTokenException::class); - - $this->tokenProvider->markPasswordInvalid($token, 'tokenId'); - } - - public function testMarkPasswordInvalid() { - $token = $this->createMock(DefaultToken::class); - - $this->mapper->expects($this->once()) - ->method('invalidate') - ->with('0c7db0098fe8ddba6032b22719ec18867c69a1820fa36d71c28bf96d52843bdc44a112bd24093b049be5bb54769bcb72d67190a4a9690e51aac263cba38186fb'); - - $this->tokenProvider->markPasswordInvalid($token, 'tokenId'); - } -} diff --git a/tests/lib/Authentication/Token/DefaultTokenTest.php b/tests/lib/Authentication/Token/DefaultTokenTest.php deleted file mode 100644 index 76b976586a987..0000000000000 --- a/tests/lib/Authentication/Token/DefaultTokenTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * @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\Token; - -use OC\Authentication\Token\DefaultToken; -use Test\TestCase; - -class DefaultTokenTest extends TestCase { - public function testSetScopeAsArray() { - $scope = ['filesystem' => false]; - $token = new DefaultToken(); - $token->setScope($scope); - $this->assertEquals(json_encode($scope), $token->getScope()); - $this->assertEquals($scope, $token->getScopeAsArray()); - } - - public function testDefaultScope() { - $scope = ['filesystem' => true]; - $token = new DefaultToken(); - $this->assertEquals($scope, $token->getScopeAsArray()); - } -} diff --git a/tests/lib/Authentication/Token/ManagerTest.php b/tests/lib/Authentication/Token/ManagerTest.php index fb92b3e50186a..8b40fb9b66932 100644 --- a/tests/lib/Authentication/Token/ManagerTest.php +++ b/tests/lib/Authentication/Token/ManagerTest.php @@ -28,9 +28,6 @@ use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Exceptions\PasswordlessTokenException; -use OC\Authentication\Token\DefaultToken; -use OC\Authentication\Token\DefaultTokenProvider; use OC\Authentication\Token\IToken; use OC\Authentication\Token\Manager; use OC\Authentication\Token\PublicKeyToken; @@ -39,11 +36,8 @@ use Test\TestCase; class ManagerTest extends TestCase { - /** @var PublicKeyTokenProvider|MockObject */ private $publicKeyTokenProvider; - /** @var DefaultTokenProvider|MockObject */ - private $defaultTokenProvider; /** @var Manager */ private $manager; @@ -51,17 +45,12 @@ protected function setUp(): void { parent::setUp(); $this->publicKeyTokenProvider = $this->createMock(PublicKeyTokenProvider::class); - $this->defaultTokenProvider = $this->createMock(DefaultTokenProvider::class); $this->manager = new Manager( - $this->defaultTokenProvider, $this->publicKeyTokenProvider ); } public function testGenerateToken() { - $this->defaultTokenProvider->expects($this->never()) - ->method('generateToken'); - $token = new PublicKeyToken(); $this->publicKeyTokenProvider->expects($this->once()) @@ -92,8 +81,6 @@ public function testGenerateToken() { public function testGenerateConflictingToken() { /** @var MockObject|UniqueConstraintViolationException $exception */ $exception = $this->createMock(UniqueConstraintViolationException::class); - $this->defaultTokenProvider->expects($this->never()) - ->method('generateToken'); $token = new PublicKeyToken(); $token->setUid('uid'); @@ -129,18 +116,12 @@ public function testGenerateConflictingToken() { public function tokenData(): array { return [ - [new DefaultToken()], [new PublicKeyToken()], [$this->createMock(IToken::class)], ]; } protected function setNoCall(IToken $token) { - if (!($token instanceof DefaultToken)) { - $this->defaultTokenProvider->expects($this->never()) - ->method($this->anything()); - } - if (!($token instanceof PublicKeyToken)) { $this->publicKeyTokenProvider->expects($this->never()) ->method($this->anything()); @@ -148,13 +129,6 @@ protected function setNoCall(IToken $token) { } protected function setCall(IToken $token, string $function, $return = null) { - if ($token instanceof DefaultToken) { - $this->defaultTokenProvider->expects($this->once()) - ->method($function) - ->with($token) - ->willReturn($return); - } - if ($token instanceof PublicKeyToken) { $this->publicKeyTokenProvider->expects($this->once()) ->method($function) @@ -164,7 +138,7 @@ protected function setCall(IToken $token, string $function, $return = null) { } protected function setException(IToken $token) { - if (!($token instanceof DefaultToken) && !($token instanceof PublicKeyToken)) { + if (!($token instanceof PublicKeyToken)) { $this->expectException(InvalidTokenException::class); } } @@ -216,10 +190,6 @@ public function testSetPassword(IToken $token) { } public function testInvalidateTokens() { - $this->defaultTokenProvider->expects($this->once()) - ->method('invalidateToken') - ->with('token'); - $this->publicKeyTokenProvider->expects($this->once()) ->method('invalidateToken') ->with('token'); @@ -228,10 +198,6 @@ public function testInvalidateTokens() { } public function testInvalidateTokenById() { - $this->defaultTokenProvider->expects($this->once()) - ->method('invalidateTokenById') - ->with('uid', 42); - $this->publicKeyTokenProvider->expects($this->once()) ->method('invalidateTokenById') ->with('uid', 42); @@ -240,9 +206,6 @@ public function testInvalidateTokenById() { } public function testInvalidateOldTokens() { - $this->defaultTokenProvider->expects($this->once()) - ->method('invalidateOldTokens'); - $this->publicKeyTokenProvider->expects($this->once()) ->method('invalidateOldTokens'); @@ -250,42 +213,20 @@ public function testInvalidateOldTokens() { } public function testGetTokenByUser() { - $t1 = new DefaultToken(); - $t2 = new DefaultToken(); - $t3 = new PublicKeyToken(); - $t4 = new PublicKeyToken(); - - $this->defaultTokenProvider - ->method('getTokenByUser') - ->willReturn([$t1, $t2]); + $t1 = new PublicKeyToken(); + $t2 = new PublicKeyToken(); $this->publicKeyTokenProvider ->method('getTokenByUser') - ->willReturn([$t3, $t4]); + ->willReturn([$t1, $t2]); $result = $this->manager->getTokenByUser('uid'); - $this->assertEquals([$t1, $t2, $t3, $t4], $result); + $this->assertEquals([$t1, $t2], $result); } public function testRenewSessionTokenPublicKey() { - $this->defaultTokenProvider->expects($this->never()) - ->method($this->anything()); - - $this->publicKeyTokenProvider->expects($this->once()) - ->method('renewSessionToken') - ->with('oldId', 'newId'); - - $this->manager->renewSessionToken('oldId', 'newId'); - } - - public function testRenewSessionTokenDefault() { $this->publicKeyTokenProvider->expects($this->once()) - ->method('renewSessionToken') - ->with('oldId', 'newId') - ->willThrowException(new InvalidTokenException()); - - $this->defaultTokenProvider->expects($this->once()) ->method('renewSessionToken') ->with('oldId', 'newId'); @@ -298,11 +239,6 @@ public function testRenewSessionInvalid() { ->with('oldId', 'newId') ->willThrowException(new InvalidTokenException()); - $this->defaultTokenProvider->expects($this->once()) - ->method('renewSessionToken') - ->with('oldId', 'newId') - ->willThrowException(new InvalidTokenException()); - $this->expectException(InvalidTokenException::class); $this->manager->renewSessionToken('oldId', 'newId'); } @@ -315,26 +251,6 @@ public function testGetTokenByIdPublicKey() { ->with(42) ->willReturn($token); - $this->defaultTokenProvider->expects($this->never()) - ->method($this->anything()); - - - $this->assertSame($token, $this->manager->getTokenById(42)); - } - - public function testGetTokenByIdDefault() { - $token = $this->createMock(IToken::class); - - $this->publicKeyTokenProvider->expects($this->once()) - ->method('getTokenById') - ->with(42) - ->willThrowException(new InvalidTokenException()); - - $this->defaultTokenProvider->expects($this->once()) - ->method('getTokenById') - ->with(42) - ->willReturn($token); - $this->assertSame($token, $this->manager->getTokenById(42)); } @@ -344,11 +260,6 @@ public function testGetTokenByIdInvalid() { ->with(42) ->willThrowException(new InvalidTokenException()); - $this->defaultTokenProvider->expects($this->once()) - ->method('getTokenById') - ->with(42) - ->willThrowException(new InvalidTokenException()); - $this->expectException(InvalidTokenException::class); $this->manager->getTokenById(42); } @@ -356,9 +267,6 @@ public function testGetTokenByIdInvalid() { public function testGetTokenPublicKey() { $token = new PublicKeyToken(); - $this->defaultTokenProvider->expects($this->never()) - ->method($this->anything()); - $this->publicKeyTokenProvider ->method('getToken') ->with('tokenId') @@ -368,11 +276,6 @@ public function testGetTokenPublicKey() { } public function testGetTokenInvalid() { - $this->defaultTokenProvider - ->method('getToken') - ->with('tokenId') - ->willThrowException(new InvalidTokenException()); - $this->publicKeyTokenProvider ->method('getToken') ->with('tokenId') @@ -382,58 +285,6 @@ public function testGetTokenInvalid() { $this->manager->getToken('tokenId'); } - public function testGetTokenConvertPassword() { - $oldToken = new DefaultToken(); - $newToken = new PublicKeyToken(); - - $this->publicKeyTokenProvider - ->method('getToken') - ->with('tokenId') - ->willThrowException(new InvalidTokenException()); - - $this->defaultTokenProvider - ->method('getToken') - ->willReturn($oldToken); - - $this->defaultTokenProvider - ->method('getPassword') - ->with($oldToken, 'tokenId') - ->willReturn('password'); - - $this->publicKeyTokenProvider - ->method('convertToken') - ->with($oldToken, 'tokenId', 'password') - ->willReturn($newToken); - - $this->assertSame($newToken, $this->manager->getToken('tokenId')); - } - - public function testGetTokenConvertNoPassword() { - $oldToken = new DefaultToken(); - $newToken = new PublicKeyToken(); - - $this->publicKeyTokenProvider - ->method('getToken') - ->with('tokenId') - ->willThrowException(new InvalidTokenException()); - - $this->defaultTokenProvider - ->method('getToken') - ->willReturn($oldToken); - - $this->defaultTokenProvider - ->method('getPassword') - ->with($oldToken, 'tokenId') - ->willThrowException(new PasswordlessTokenException()); - - $this->publicKeyTokenProvider - ->method('convertToken') - ->with($oldToken, 'tokenId', null) - ->willReturn($newToken); - - $this->assertSame($newToken, $this->manager->getToken('tokenId')); - } - public function testRotateInvalid() { $this->expectException(InvalidTokenException::class); $this->manager->rotate($this->createMock(IToken::class), 'oldId', 'newId'); @@ -450,60 +301,12 @@ public function testRotatePublicKey() { $this->assertSame($token, $this->manager->rotate($token, 'oldId', 'newId')); } - public function testRotateConvertPassword() { - $oldToken = new DefaultToken(); - $newToken = new PublicKeyToken(); - - $this->defaultTokenProvider - ->method('getPassword') - ->with($oldToken, 'oldId') - ->willReturn('password'); - - $this->publicKeyTokenProvider - ->method('convertToken') - ->with($oldToken, 'newId', 'password') - ->willReturn($newToken); - - $this->assertSame($newToken, $this->manager->rotate($oldToken, 'oldId', 'newId')); - } - - public function testRotateConvertNoPassword() { - $oldToken = new DefaultToken(); - $newToken = new PublicKeyToken(); - - $this->defaultTokenProvider - ->method('getPassword') - ->with($oldToken, 'oldId') - ->willThrowException(new PasswordlessTokenException()); - - $this->publicKeyTokenProvider - ->method('convertToken') - ->with($oldToken, 'newId', null) - ->willReturn($newToken); - - $this->assertSame($newToken, $this->manager->rotate($oldToken, 'oldId', 'newId')); - } - - public function testMarkPasswordInvalidDefault() { - $token = $this->createMock(DefaultToken::class); - - $this->defaultTokenProvider->expects($this->once()) - ->method('markPasswordInvalid') - ->with($token, 'tokenId'); - $this->publicKeyTokenProvider->expects($this->never()) - ->method($this->anything()); - - $this->manager->markPasswordInvalid($token, 'tokenId'); - } - public function testMarkPasswordInvalidPublicKey() { $token = $this->createMock(PublicKeyToken::class); $this->publicKeyTokenProvider->expects($this->once()) ->method('markPasswordInvalid') ->with($token, 'tokenId'); - $this->defaultTokenProvider->expects($this->never()) - ->method($this->anything()); $this->manager->markPasswordInvalid($token, 'tokenId'); } @@ -515,9 +318,6 @@ public function testMarkPasswordInvalidInvalidToken() { } public function testUpdatePasswords() { - $this->defaultTokenProvider->expects($this->once()) - ->method('updatePasswords') - ->with('uid', 'pass'); $this->publicKeyTokenProvider->expects($this->once()) ->method('updatePasswords') ->with('uid', 'pass'); diff --git a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php index 486660f17c65f..062d1840a5f67 100644 --- a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php +++ b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php @@ -25,7 +25,6 @@ use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\IToken; use OC\Authentication\Token\PublicKeyToken; use OC\Authentication\Token\PublicKeyTokenMapper; @@ -38,7 +37,6 @@ use Test\TestCase; class PublicKeyTokenProviderTest extends TestCase { - /** @var PublicKeyTokenProvider|\PHPUnit\Framework\MockObject\MockObject */ private $tokenProvider; /** @var PublicKeyTokenMapper|\PHPUnit\Framework\MockObject\MockObject */ @@ -476,39 +474,8 @@ public function testRotateNoPassword() { $this->assertNull($new->getPassword()); } - public function testConvertToken() { - $defaultToken = new DefaultToken(); - $defaultToken->setId(42); - $defaultToken->setPassword('oldPass'); - $defaultToken->setExpires(1337); - $defaultToken->setToken('oldToken'); - $defaultToken->setUid('uid'); - $defaultToken->setLoginName('loginName'); - $defaultToken->setLastActivity(999); - $defaultToken->setName('name'); - $defaultToken->setRemember(IToken::REMEMBER); - $defaultToken->setType(IToken::PERMANENT_TOKEN); - - $this->mapper->expects($this->once()) - ->method('update') - ->willReturnArgument(0); - - $newToken = $this->tokenProvider->convertToken($defaultToken, 'newToken', 'newPassword'); - - $this->assertSame(42, $newToken->getId()); - $this->assertSame('newPassword', $this->tokenProvider->getPassword($newToken, 'newToken')); - $this->assertSame(1337, $newToken->getExpires()); - $this->assertSame('uid', $newToken->getUID()); - $this->assertSame('loginName', $newToken->getLoginName()); - $this->assertSame(1313131, $newToken->getLastActivity()); - $this->assertSame(1313131, $newToken->getLastCheck()); - $this->assertSame('name', $newToken->getName()); - $this->assertSame(IToken::REMEMBER, $newToken->getRemember()); - $this->assertSame(IToken::PERMANENT_TOKEN, $newToken->getType()); - } - public function testMarkPasswordInvalidInvalidToken() { - $token = $this->createMock(DefaultToken::class); + $token = $this->createMock(IToken::class); $this->expectException(InvalidTokenException::class); diff --git a/tests/lib/Lockdown/Filesystem/NoFSTest.php b/tests/lib/Lockdown/Filesystem/NoFSTest.php index 28bdb08c4a4af..4c0645447ece6 100644 --- a/tests/lib/Lockdown/Filesystem/NoFSTest.php +++ b/tests/lib/Lockdown/Filesystem/NoFSTest.php @@ -23,7 +23,7 @@ namespace Test\Lockdown\Filesystem; -use OC\Authentication\Token\DefaultToken; +use OC\Authentication\Token\PublicKeyToken; use OC\Files\Filesystem; use OC\Lockdown\Filesystem\NullStorage; use Test\Traits\UserTrait; @@ -35,7 +35,7 @@ class NoFSTest extends \Test\TestCase { use UserTrait; protected function tearDown(): void { - $token = new DefaultToken(); + $token = new PublicKeyToken(); $token->setScope([ 'filesystem' => true ]); @@ -45,7 +45,7 @@ protected function tearDown(): void { protected function setUp(): void { parent::setUp(); - $token = new DefaultToken(); + $token = new PublicKeyToken(); $token->setScope([ 'filesystem' => false ]); diff --git a/tests/lib/Lockdown/LockdownManagerTest.php b/tests/lib/Lockdown/LockdownManagerTest.php index 2f9a410b7e35f..9b05ea0e6a5ad 100644 --- a/tests/lib/Lockdown/LockdownManagerTest.php +++ b/tests/lib/Lockdown/LockdownManagerTest.php @@ -21,7 +21,7 @@ namespace Test\Lockdown; -use OC\Authentication\Token\DefaultToken; +use OC\Authentication\Token\PublicKeyToken; use OC\Lockdown\LockdownManager; use OCP\ISession; use Test\TestCase; @@ -43,7 +43,7 @@ public function testCanAccessFilesystemDisabled() { } public function testCanAccessFilesystemAllowed() { - $token = new DefaultToken(); + $token = new PublicKeyToken(); $token->setScope(['filesystem' => true]); $manager = new LockdownManager($this->sessionCallback); $manager->setToken($token); @@ -51,7 +51,7 @@ public function testCanAccessFilesystemAllowed() { } public function testCanAccessFilesystemNotAllowed() { - $token = new DefaultToken(); + $token = new PublicKeyToken(); $token->setScope(['filesystem' => false]); $manager = new LockdownManager($this->sessionCallback); $manager->setToken($token); diff --git a/tests/lib/User/ManagerTest.php b/tests/lib/User/ManagerTest.php index 51a739994a66d..c8c1430d583e4 100644 --- a/tests/lib/User/ManagerTest.php +++ b/tests/lib/User/ManagerTest.php @@ -643,15 +643,15 @@ public function testCallForSeenUsers() { $countBefore = $count; //Add test users - $user1 = $manager->createUser('testseen1', 'testseen1'); + $user1 = $manager->createUser('testseen1', 'testseen10'); $user1->updateLastLoginTimestamp(); - $user2 = $manager->createUser('testseen2', 'testseen2'); + $user2 = $manager->createUser('testseen2', 'testseen20'); $user2->updateLastLoginTimestamp(); - $user3 = $manager->createUser('testseen3', 'testseen3'); + $user3 = $manager->createUser('testseen3', 'testseen30'); - $user4 = $manager->createUser('testseen4', 'testseen4'); + $user4 = $manager->createUser('testseen4', 'testseen40'); $user4->updateLastLoginTimestamp(); $count = 0; diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 334c3d9065fa1..8913e2f99c1c5 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -9,8 +9,6 @@ namespace Test\User; use OC\AppFramework\Http\Request; -use OC\Authentication\Token\DefaultTokenMapper; -use OC\Authentication\Token\DefaultTokenProvider; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; use OC\Security\Bruteforce\Throttler; @@ -28,11 +26,9 @@ use OCP\ISession; use OCP\IUser; use OCP\Lockdown\ILockdownManager; -use OCP\Security\ICrypto; use OCP\Security\ISecureRandom; use OCP\User\Events\PostLoginEvent; use PHPUnit\Framework\MockObject\MockObject; -use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -42,8 +38,6 @@ class SessionTest extends \Test\TestCase { /** @var ITimeFactory|MockObject */ private $timeFactory; - /** @var DefaultTokenProvider|MockObject */ - protected $tokenProvider; /** @var IConfig|MockObject */ private $config; /** @var Throttler|MockObject */ @@ -99,63 +93,6 @@ protected function setUp(): void { \OC_User::setIncognitoMode(false); } - public function testGetUser() { - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setLoginName('User123'); - $token->setLastCheck(200); - - $expectedUser = $this->createMock(IUser::class); - $expectedUser->expects($this->any()) - ->method('getUID') - ->willReturn('user123'); - $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); - $session->expects($this->at(0)) - ->method('get') - ->with('user_id') - ->willReturn($expectedUser->getUID()); - $sessionId = 'abcdef12345'; - - $manager = $this->getMockBuilder('\OC\User\Manager') - ->disableOriginalConstructor() - ->getMock(); - $session->expects($this->at(1)) - ->method('get') - ->with('app_password') - ->willReturn(null); // No password set -> browser session - $session->expects($this->once()) - ->method('getId') - ->willReturn($sessionId); - $this->tokenProvider->expects($this->once()) - ->method('getToken') - ->with($sessionId) - ->willReturn($token); - $this->tokenProvider->expects($this->once()) - ->method('getPassword') - ->with($token, $sessionId) - ->willReturn('passme'); - $manager->expects($this->once()) - ->method('checkPassword') - ->with('User123', 'passme') - ->willReturn(true); - $expectedUser->expects($this->once()) - ->method('isEnabled') - ->willReturn(true); - - $this->tokenProvider->expects($this->once()) - ->method('updateTokenActivity') - ->with($token); - - $manager->expects($this->once()) - ->method('get') - ->with($expectedUser->getUID()) - ->willReturn($expectedUser); - - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - $user = $userSession->getUser(); - $this->assertSame($expectedUser, $user); - $this->assertSame(10000, $token->getLastCheck()); - } - public function isLoggedInData() { return [ [true], @@ -390,36 +327,6 @@ public function testLoginNonExisting() { $userSession->login('foo', 'bar'); } - /** - * When using a device token, the loginname must match the one that was used - * when generating the token on the browser. - */ - public function testLoginWithDifferentTokenLoginName() { - $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); - $manager = $this->createMock(Manager::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - $username = 'user123'; - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setLoginName($username); - - $session->expects($this->never()) - ->method('set'); - $session->expects($this->once()) - ->method('regenerateId'); - $this->tokenProvider->expects($this->once()) - ->method('getToken') - ->with('bar') - ->willReturn($token); - - $manager->expects($this->once()) - ->method('checkPasswordNoLogging') - ->with('foo', 'bar') - ->willReturn(false); - - $userSession->login('foo', 'bar'); - } - - public function testLogClientInNoTokenPasswordWith2fa() { $this->expectException(\OC\Authentication\Exceptions\PasswordLoginForbiddenException::class); @@ -1008,335 +915,6 @@ public function testCreateSessionTokenWithNonExistentUser() { $this->assertFalse($userSession->createSessionToken($request, $uid, $loginName, $password)); } - - public function testTryTokenLoginWithDisabledUser() { - $this->expectException(\OC\User\LoginException::class); - - $manager = $this->getMockBuilder('\OC\User\Manager') - ->disableOriginalConstructor() - ->getMock(); - $session = new Memory(''); - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setLoginName('fritz'); - $token->setUid('fritz0'); - $token->setLastCheck(100); // Needs check - $user = $this->createMock(IUser::class); - $userSession = $this->getMockBuilder(Session::class) - ->setMethods(['logout']) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher]) - ->getMock(); - $request = $this->createMock(IRequest::class); - - $request->expects($this->once()) - ->method('getHeader') - ->with('Authorization') - ->willReturn('Bearer xxxxx'); - $this->tokenProvider->expects($this->once()) - ->method('getToken') - ->with('xxxxx') - ->willReturn($token); - $manager->expects($this->once()) - ->method('get') - ->with('fritz0') - ->willReturn($user); - $user->expects($this->once()) - ->method('isEnabled') - ->willReturn(false); - - $userSession->tryTokenLogin($request); - } - - public function testValidateSessionDisabledUser() { - $userManager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $timeFactory = $this->createMock(ITimeFactory::class); - $tokenProvider = $this->createMock(IProvider::class); - $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher]) - ->setMethods(['logout']) - ->getMock(); - - $user = $this->createMock(IUser::class); - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setLoginName('susan'); - $token->setLastCheck(20); - - $session->expects($this->once()) - ->method('get') - ->with('app_password') - ->willReturn('APP-PASSWORD'); - $tokenProvider->expects($this->once()) - ->method('getToken') - ->with('APP-PASSWORD') - ->willReturn($token); - $timeFactory->expects($this->once()) - ->method('getTime') - ->willReturn(1000); // more than 5min since last check - $tokenProvider->expects($this->once()) - ->method('getPassword') - ->with($token, 'APP-PASSWORD') - ->willReturn('123456'); - $userManager->expects($this->never()) - ->method('checkPassword'); - $user->expects($this->once()) - ->method('isEnabled') - ->willReturn(false); - $tokenProvider->expects($this->once()) - ->method('invalidateToken') - ->with('APP-PASSWORD'); - $userSession->expects($this->once()) - ->method('logout'); - - $userSession->setUser($user); - $this->invokePrivate($userSession, 'validateSession'); - } - - public function testValidateSessionNoPassword() { - $userManager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $timeFactory = $this->createMock(ITimeFactory::class); - $tokenProvider = $this->createMock(IProvider::class); - $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher]) - ->setMethods(['logout']) - ->getMock(); - - $user = $this->createMock(IUser::class); - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setLastCheck(20); - - $session->expects($this->once()) - ->method('get') - ->with('app_password') - ->willReturn('APP-PASSWORD'); - $tokenProvider->expects($this->once()) - ->method('getToken') - ->with('APP-PASSWORD') - ->willReturn($token); - $timeFactory->expects($this->once()) - ->method('getTime') - ->willReturn(1000); // more than 5min since last check - $tokenProvider->expects($this->once()) - ->method('getPassword') - ->with($token, 'APP-PASSWORD') - ->will($this->throwException(new \OC\Authentication\Exceptions\PasswordlessTokenException())); - - $this->invokePrivate($userSession, 'validateSession', [$user]); - - $this->assertEquals(1000, $token->getLastCheck()); - } - - public function testValidateSessionInvalidPassword() { - $userManager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $timeFactory = $this->createMock(ITimeFactory::class); - $tokenProvider = $this->createMock(IProvider::class); - $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher]) - ->setMethods(['logout']) - ->getMock(); - - $user = $this->createMock(IUser::class); - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setLoginName('susan'); - $token->setLastCheck(20); - - $session->expects($this->once()) - ->method('get') - ->with('app_password') - ->willReturn('APP-PASSWORD'); - $tokenProvider->expects($this->once()) - ->method('getToken') - ->with('APP-PASSWORD') - ->willReturn($token); - $timeFactory->expects($this->once()) - ->method('getTime') - ->willReturn(1000); // more than 5min since last check - $tokenProvider->expects($this->once()) - ->method('getPassword') - ->with($token, 'APP-PASSWORD') - ->willReturn('123456'); - $userManager->expects($this->once()) - ->method('checkPassword') - ->with('susan', '123456') - ->willReturn(false); - $user->expects($this->once()) - ->method('isEnabled') - ->willReturn(true); - $tokenProvider->expects($this->never()) - ->method('invalidateToken'); - $tokenProvider->expects($this->once()) - ->method('markPasswordInvalid') - ->with($token, 'APP-PASSWORD'); - $userSession->expects($this->once()) - ->method('logout'); - - $userSession->setUser($user); - $this->invokePrivate($userSession, 'validateSession'); - } - - public function testUpdateSessionTokenPassword() { - $userManager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $timeFactory = $this->createMock(ITimeFactory::class); - $tokenProvider = $this->createMock(IProvider::class); - $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - - $password = '123456'; - $sessionId = 'session1234'; - $token = new \OC\Authentication\Token\DefaultToken(); - - $session->expects($this->once()) - ->method('getId') - ->willReturn($sessionId); - $tokenProvider->expects($this->once()) - ->method('getToken') - ->with($sessionId) - ->willReturn($token); - $tokenProvider->expects($this->once()) - ->method('setPassword') - ->with($token, $sessionId, $password); - - $userSession->updateSessionTokenPassword($password); - } - - public function testUpdateSessionTokenPasswordNoSessionAvailable() { - $userManager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $timeFactory = $this->createMock(ITimeFactory::class); - $tokenProvider = $this->createMock(IProvider::class); - $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - - $session->expects($this->once()) - ->method('getId') - ->will($this->throwException(new \OCP\Session\Exceptions\SessionNotAvailableException())); - - $userSession->updateSessionTokenPassword('1234'); - } - - public function testUpdateSessionTokenPasswordInvalidTokenException() { - $userManager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $timeFactory = $this->createMock(ITimeFactory::class); - $tokenProvider = $this->createMock(IProvider::class); - $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - - $password = '123456'; - $sessionId = 'session1234'; - $token = new \OC\Authentication\Token\DefaultToken(); - - $session->expects($this->once()) - ->method('getId') - ->willReturn($sessionId); - $tokenProvider->expects($this->once()) - ->method('getToken') - ->with($sessionId) - ->willReturn($token); - $tokenProvider->expects($this->once()) - ->method('setPassword') - ->with($token, $sessionId, $password) - ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); - - $userSession->updateSessionTokenPassword($password); - } - - public function testUpdateAuthTokenLastCheck() { - $manager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $request = $this->createMock(IRequest::class); - - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setUid('john'); - $token->setLoginName('john'); - $token->setLastActivity(100); - $token->setLastCheck(100); - - $mapper = $this->getMockBuilder(DefaultTokenMapper::class) - ->disableOriginalConstructor() - ->getMock(); - $crypto = $this->createMock(ICrypto::class); - $logger = $this->createMock(LoggerInterface::class); - $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory); - - /** @var \OC\User\Session $userSession */ - $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - - $mapper->expects($this->any()) - ->method('getToken') - ->willReturn($token); - $mapper->expects($this->exactly(2)) - ->method('update'); - $request - ->expects($this->any()) - ->method('getRemoteAddress') - ->willReturn('192.168.0.1'); - $this->throttler - ->expects($this->once()) - ->method('sleepDelay') - ->with('192.168.0.1') - ->willReturn(5); - $this->timeFactory - ->expects($this->any()) - ->method('getTime') - ->willReturn(100); - - $manager->method('getByEmail') - ->with('john') - ->willReturn([]); - - $userSession->logClientIn('john', 'doe', $request, $this->throttler); - - $this->assertEquals(10000, $token->getLastActivity()); - $this->assertEquals(10000, $token->getLastCheck()); - } - - public function testNoUpdateAuthTokenLastCheckRecent() { - $manager = $this->createMock(Manager::class); - $session = $this->createMock(ISession::class); - $request = $this->createMock(IRequest::class); - - $token = new \OC\Authentication\Token\DefaultToken(); - $token->setUid('john'); - $token->setLoginName('john'); - $token->setLastActivity(10000); - $token->setLastCheck(100); - - $mapper = $this->getMockBuilder(DefaultTokenMapper::class) - ->disableOriginalConstructor() - ->getMock(); - $crypto = $this->createMock(ICrypto::class); - $logger = $this->createMock(LoggerInterface::class); - $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory); - - /** @var \OC\User\Session $userSession */ - $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher); - - $mapper->expects($this->any()) - ->method('getToken') - ->willReturn($token); - $mapper->expects($this->once()) - ->method('update'); - $request - ->expects($this->any()) - ->method('getRemoteAddress') - ->willReturn('192.168.0.1'); - $this->throttler - ->expects($this->once()) - ->method('sleepDelay') - ->with('192.168.0.1') - ->willReturn(5); - $this->timeFactory - ->expects($this->any()) - ->method('getTime') - ->willReturn(100); - - $manager->method('getByEmail') - ->with('john') - ->willReturn([]); - - $userSession->logClientIn('john', 'doe', $request, $this->throttler); - } - public function testCreateRememberMeToken() { $user = $this->createMock(IUser::class); $user