diff options
author | Roeland Jago Douma <roeland@famdouma.nl> | 2019-10-08 13:57:36 +0200 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2019-10-08 13:57:36 +0200 |
commit | 3fccc7dc47359ec31cb25252b9793c45f873064f (patch) | |
tree | 5d26b671532be3a798811fead39dfa699b172bff /lib/private | |
parent | b7803665c1c030378511161dd51c10ac17e6cf6b (diff) | |
download | nextcloud-server-3fccc7dc47359ec31cb25252b9793c45f873064f.tar.gz nextcloud-server-3fccc7dc47359ec31cb25252b9793c45f873064f.zip |
Cache the public key tokens
Sometimes (esp with token auth) we query the same token multiple times.
While this is properly indexed and fast it is still a bit of a waste.
Right now it is doing very stupid caching. Which gets invalidate on any
update.
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/Authentication/Token/PublicKeyTokenProvider.php | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index 318d4468ddc..4ef9afb3442 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -27,6 +27,7 @@ use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Exceptions\WipeTokenException; +use OC\Cache\CappedMemoryCache; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; @@ -49,6 +50,9 @@ class PublicKeyTokenProvider implements IProvider { /** @var ITimeFactory $time */ private $time; + /** @var CappedMemoryCache */ + private $cache; + public function __construct(PublicKeyTokenMapper $mapper, ICrypto $crypto, IConfig $config, @@ -59,6 +63,8 @@ class PublicKeyTokenProvider implements IProvider { $this->config = $config; $this->logger = $logger; $this->time = $time; + + $this->cache = new CappedMemoryCache(); } /** @@ -72,17 +78,26 @@ class PublicKeyTokenProvider implements IProvider { int $type = IToken::TEMPORARY_TOKEN, int $remember = IToken::DO_NOT_REMEMBER): IToken { $dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember); - $this->mapper->insert($dbToken); + // Add the token to the cache + $this->cache[$dbToken->getToken()] = $dbToken; + return $dbToken; } public function getToken(string $tokenId): IToken { - try { - $token = $this->mapper->getToken($this->hashToken($tokenId)); - } catch (DoesNotExistException $ex) { - throw new InvalidTokenException(); + $tokenHash = $this->hashToken($tokenId); + + if (isset($this->cache[$tokenHash])) { + $token = $this->cache[$tokenHash]; + } else { + try { + $token = $this->mapper->getToken($this->hashToken($tokenId)); + $this->cache[$token->getToken()] = $token; + } catch (DoesNotExistException $ex) { + throw new InvalidTokenException(); + } } if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) { @@ -115,6 +130,8 @@ class PublicKeyTokenProvider implements IProvider { } public function renewSessionToken(string $oldSessionId, string $sessionId) { + $this->cache->clear(); + $token = $this->getToken($oldSessionId); if (!($token instanceof PublicKeyToken)) { @@ -141,14 +158,20 @@ class PublicKeyTokenProvider implements IProvider { } public function invalidateToken(string $token) { + $this->cache->clear(); + $this->mapper->invalidate($this->hashToken($token)); } public function invalidateTokenById(string $uid, int $id) { + $this->cache->clear(); + $this->mapper->deleteById($uid, $id); } public function invalidateOldTokens() { + $this->cache->clear(); + $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); @@ -158,6 +181,8 @@ class PublicKeyTokenProvider implements IProvider { } public function updateToken(IToken $token) { + $this->cache->clear(); + if (!($token instanceof PublicKeyToken)) { throw new InvalidTokenException(); } @@ -165,6 +190,8 @@ class PublicKeyTokenProvider implements IProvider { } public function updateTokenActivity(IToken $token) { + $this->cache->clear(); + if (!($token instanceof PublicKeyToken)) { throw new InvalidTokenException(); } @@ -198,6 +225,8 @@ class PublicKeyTokenProvider implements IProvider { } public function setPassword(IToken $token, string $tokenId, string $password) { + $this->cache->clear(); + if (!($token instanceof PublicKeyToken)) { throw new InvalidTokenException(); } @@ -215,6 +244,8 @@ class PublicKeyTokenProvider implements IProvider { } public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken { + $this->cache->clear(); + if (!($token instanceof PublicKeyToken)) { throw new InvalidTokenException(); } @@ -274,6 +305,8 @@ class PublicKeyTokenProvider implements IProvider { * @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(), @@ -344,6 +377,8 @@ class PublicKeyTokenProvider implements IProvider { } public function markPasswordInvalid(IToken $token, string $tokenId) { + $this->cache->clear(); + if (!($token instanceof PublicKeyToken)) { throw new InvalidTokenException(); } @@ -353,6 +388,8 @@ class PublicKeyTokenProvider implements IProvider { } public function updatePasswords(string $uid, string $password) { + $this->cache->clear(); + if (!$this->mapper->hasExpiredTokens($uid)) { // Nothing to do here return; |