aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenMapper.php26
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php6
-rw-r--r--lib/private/User/Session.php1
3 files changed, 19 insertions, 14 deletions
diff --git a/lib/private/Authentication/Token/PublicKeyTokenMapper.php b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
index 0db5c4f53e7..5b97e557219 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenMapper.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
@@ -182,7 +182,7 @@ class PublicKeyTokenMapper extends QBMapper {
}
/**
- * Update the last activity timestamp
+ * Update the last activity timestamp and save all saved fields
*
* In highly concurrent setups it can happen that two parallel processes
* trigger the update at (nearly) the same time. In that special case it's
@@ -192,7 +192,7 @@ class PublicKeyTokenMapper extends QBMapper {
*
* Example:
* - process 1 (P1) reads the token at timestamp 1500
- * - process 1 (P2) reads the token at timestamp 1501
+ * - process 2 (P2) reads the token at timestamp 1501
* - activity update interval is 100
*
* This means
@@ -206,17 +206,21 @@ class PublicKeyTokenMapper extends QBMapper {
* but the comparison on last_activity will still not be truthy and the
* token row is not updated a second time
*
- * @param IToken $token
+ * @param PublicKeyToken $token
* @param int $now
*/
- public function updateActivity(IToken $token, int $now): void {
- $qb = $this->db->getQueryBuilder();
- $update = $qb->update($this->getTableName())
- ->set('last_activity', $qb->createNamedParameter($now, IQueryBuilder::PARAM_INT))
- ->where(
- $qb->expr()->eq('id', $qb->createNamedParameter($token->getId(), IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT),
- $qb->expr()->lt('last_activity', $qb->createNamedParameter($now - 15, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT)
- );
+ public function updateActivity(PublicKeyToken $token, int $now): void {
+ $token->setLastActivity($now);
+ $update = $this->createUpdateQuery($token);
+
+ $updatedFields = $token->getUpdatedFields();
+ unset($updatedFields['lastActivity']);
+
+ // if no other fields are updated, we add the extra filter to prevent duplicate updates
+ if (count($updatedFields) === 0) {
+ $update->andWhere($update->expr()->lt('last_activity', $update->createNamedParameter($now - 15, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
+ }
+
$update->executeStatement();
}
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 767ece1e551..809c39474e2 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -299,10 +299,12 @@ class PublicKeyTokenProvider implements IProvider {
$activityInterval = $this->config->getSystemValueInt('token_auth_activity_update', 60);
$activityInterval = min(max($activityInterval, 0), 300);
+ $updatedFields = $token->getUpdatedFields();
+ unset($updatedFields['lastActivity']);
+
/** @var PublicKeyToken $token */
$now = $this->time->getTime();
- if ($token->getLastActivity() < ($now - $activityInterval)) {
- $token->setLastActivity($now);
+ if ($token->getLastActivity() < ($now - $activityInterval) || count($updatedFields)) {
$this->mapper->updateActivity($token, $now);
$this->cacheToken($token);
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index e5d27172519..8226e3c95f5 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -757,7 +757,6 @@ class Session implements IUserSession, Emitter {
if ($dbToken instanceof PublicKeyToken) {
$dbToken->setLastActivity($now);
}
- $this->tokenProvider->updateToken($dbToken);
return true;
}