diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php index 18adbe48d7..9f17357127 100644 --- a/lib/private/Authentication/Token/DefaultTokenMapper.php +++ b/lib/private/Authentication/Token/DefaultTokenMapper.php @@ -26,6 +26,7 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Mapper; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; +use OCP\IUser; class DefaultTokenMapper extends Mapper { @@ -83,4 +84,31 @@ class DefaultTokenMapper extends Mapper { return DefaultToken::fromRow($data); } + /** + * Get all token 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 IUser $user + * @return DefaultToken[] + */ + public function getTokenByUser(IUser $user) { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('id', 'uid', 'password', 'name', 'type', 'token', 'last_activity') + ->from('authtoken') + ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID()))) + ->setMaxResults(1000); + $result = $qb->execute(); + $data = $result->fetchAll(); + $result->closeCursor(); + + $entities = array_map(function ($row) { + return DefaultToken::fromRow($row); + }, $data); + + return $entities; + } + } diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index a335b79e33..6c69d852d7 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -28,6 +28,7 @@ use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; use OCP\ILogger; +use OCP\IUser; use OCP\Security\ICrypto; class DefaultTokenProvider implements IProvider { @@ -102,6 +103,19 @@ class DefaultTokenProvider implements IProvider { $this->mapper->update($token); } + /** + * Get all token 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 IUser $user + * @return IToken[] + */ + public function getTokenByUser(IUser $user) { + return $this->mapper->getTokenByUser($user); + } + /** * Get a token by token id * diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index 1fd3a70fbb..a5c5faa563 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -23,6 +23,7 @@ namespace OC\Authentication\Token; use OC\Authentication\Exceptions\InvalidTokenException; +use OCP\IUser; interface IProvider { @@ -68,6 +69,17 @@ interface IProvider { */ public function updateToken(IToken $token); + /** + * Get all token 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 IUser $user + * @return IToken[] + */ + public function getTokenByUser(IUser $user); + /** * Get the (unencrypted) password of the given token * diff --git a/tests/lib/authentication/token/defaulttokenmappertest.php b/tests/lib/authentication/token/defaulttokenmappertest.php index 9a21e143fb..e17149a5c1 100644 --- a/tests/lib/authentication/token/defaulttokenmappertest.php +++ b/tests/lib/authentication/token/defaulttokenmappertest.php @@ -141,4 +141,22 @@ class DefaultTokenMapperTest extends TestCase { $this->mapper->getToken($token); } + public function testGetTokenByUser() { + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('user1')); + + $this->assertCount(2, $this->mapper->getTokenByUser($user)); + } + + public function testGetTokenByUserNotFound() { + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('user1000')); + + $this->assertCount(0, $this->mapper->getTokenByUser($user)); + } + } diff --git a/tests/lib/authentication/token/defaulttokenprovidertest.php b/tests/lib/authentication/token/defaulttokenprovidertest.php index 1902227a4f..eeb249cfa8 100644 --- a/tests/lib/authentication/token/defaulttokenprovidertest.php +++ b/tests/lib/authentication/token/defaulttokenprovidertest.php @@ -103,6 +103,16 @@ class DefaultTokenProviderTest extends TestCase { $this->assertEquals($this->time, $tk->getLastActivity()); } + + public function testGetTokenByUser() { + $user = $this->getMock('\OCP\IUser'); + $this->mapper->expects($this->once()) + ->method('getTokenByUser') + ->with($user) + ->will($this->returnValue(['token'])); + + $this->assertEquals(['token'], $this->tokenProvider->getTokenByUser($user)); + } public function testGetPassword() { $token = 'token1234';