Skip to content

Commit

Permalink
Merge pull request #2240 from nextcloud/backport/2235/stable31
Browse files Browse the repository at this point in the history
[stable31] fix(push): Check last activity and last check for age
  • Loading branch information
nickvergessen authored Mar 3, 2025
2 parents 8763fa8 + 1f964b5 commit 3dff510
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
37 changes: 35 additions & 2 deletions lib/Push.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use OCP\AppFramework\Http;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Authentication\Exceptions\InvalidTokenException;
use OCP\Authentication\Token\IToken;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Http\Client\IClientService;
use OCP\ICache;
Expand Down Expand Up @@ -537,10 +538,23 @@ protected function validateToken(int $tokenId, int $maxAge): bool {
try {
// Check if the token is still valid...
$token = $this->tokenProvider->getTokenById($tokenId);
$this->cache->set('t' . $tokenId, $token->getLastCheck(), 600);
$type = $this->callSafelyForToken($token, 'getType');
if ($type === IToken::WIPE_TOKEN) {
// Token does not exist any more, should drop the push device entry
$this->printInfo('Device token is marked for remote wipe');
$this->deletePushToken($tokenId);
$this->cache->set('t' . $tokenId, 0, 600);
return false;
}

$age = $token->getLastCheck();
$lastActivity = $this->callSafelyForToken($token, 'getLastActivity');
if ($lastActivity) {
$age = max($age, $lastActivity);
}
$this->cache->set('t' . $tokenId, $age, 600);
} catch (InvalidTokenException) {
// Token does not exist anymore, should drop the push device entry
// Token does not exist any more, should drop the push device entry
$this->printInfo('InvalidTokenException is thrown');
$this->deletePushToken($tokenId);
$this->cache->set('t' . $tokenId, 0, 600);
Expand All @@ -557,6 +571,25 @@ protected function validateToken(int $tokenId, int $maxAge): bool {
return false;
}

/**
* The functions are not part of public API so we are a bit more careful
* @param IToken $token
* @param 'getLastActivity'|'getType' $method
* @return int|null
*/
protected function callSafelyForToken(IToken $token, string $method): ?int {
if (method_exists($token, $method) || method_exists($token, '__call')) {
try {
$result = $token->$method();
if (is_int($result)) {
return $result;
}
} catch (\BadFunctionCallException) {
}
}
return null;
}

/**
* @param Key $userKey
* @param array $device
Expand Down
29 changes: 29 additions & 0 deletions tests/Unit/PushTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
use GuzzleHttp\Exception\ServerException;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\PublicKeyToken;
use OC\Security\IdentityProof\Key;
use OC\Security\IdentityProof\Manager;
use OCA\Notifications\Push;
use OCP\AppFramework\Http;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Authentication\Token\IToken as OCPIToken;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\IResponse;
Expand Down Expand Up @@ -783,4 +785,31 @@ public function testPushToDeviceTalkNotification(array $deviceTypes, bool $isTal

$push->pushToDevice(200718, $notification);
}

public static function dataValidateToken(): array {
return [
[1239999999, 1230000000, OCPIToken::WIPE_TOKEN, false],
[1230000000, 1239999999, OCPIToken::WIPE_TOKEN, false],
[1230000000, 1239999999, OCPIToken::PERMANENT_TOKEN, true],
[1239999999, 1230000000, OCPIToken::PERMANENT_TOKEN, true],
[1230000000, 1230000000, OCPIToken::PERMANENT_TOKEN, false],
];
}

/**
* @dataProvider dataValidateToken
*/
public function testValidateToken(int $lastCheck, int $lastActivity, int $type, bool $expected): void {
$token = PublicKeyToken::fromParams([
'lastCheck' => $lastCheck,
'lastActivity' => $lastActivity,
'type' => $type,
]);

$this->tokenProvider->method('getTokenById')
->willReturn($token);

$push = $this->getPush();
$this->assertSame($expected, self::invokePrivate($push, 'validateToken', [42, 1234567890]));
}
}

0 comments on commit 3dff510

Please sign in to comment.