|
35 | 35 | use OCP\AppFramework\Http; |
36 | 36 | use OCP\AppFramework\Utility\ITimeFactory; |
37 | 37 | use OCP\Authentication\Exceptions\InvalidTokenException; |
| 38 | +use OCP\Authentication\Token\IToken; |
38 | 39 | use OCP\DB\QueryBuilder\IQueryBuilder; |
39 | 40 | use OCP\Http\Client\IClientService; |
40 | 41 | use OCP\ICache; |
@@ -581,27 +582,61 @@ protected function sendNotificationsToProxies(): void { |
581 | 582 |
|
582 | 583 | protected function validateToken(int $tokenId, int $maxAge): bool { |
583 | 584 | $age = $this->cache->get('t' . $tokenId); |
584 | | - if ($age !== null) { |
585 | | - return $age > $maxAge; |
| 585 | + |
| 586 | + if ($age === null) { |
| 587 | + try { |
| 588 | + // Check if the token is still valid... |
| 589 | + $token = $this->tokenProvider->getTokenById($tokenId); |
| 590 | + $type = $this->callSafelyForToken($token, 'getType'); |
| 591 | + if ($type === IToken::WIPE_TOKEN) { |
| 592 | + // Token does not exist any more, should drop the push device entry |
| 593 | + $this->printInfo('Device token is marked for remote wipe'); |
| 594 | + $this->deletePushToken($tokenId); |
| 595 | + $this->cache->set('t' . $tokenId, 0, 600); |
| 596 | + return false; |
| 597 | + } |
| 598 | + |
| 599 | + $age = $token->getLastCheck(); |
| 600 | + $lastActivity = $this->callSafelyForToken($token, 'getLastActivity'); |
| 601 | + if ($lastActivity) { |
| 602 | + $age = max($age, $lastActivity); |
| 603 | + } |
| 604 | + $this->cache->set('t' . $tokenId, $age, 600); |
| 605 | + } catch (InvalidTokenException) { |
| 606 | + // Token does not exist any more, should drop the push device entry |
| 607 | + $this->printInfo('InvalidTokenException is thrown'); |
| 608 | + $this->deletePushToken($tokenId); |
| 609 | + $this->cache->set('t' . $tokenId, 0, 600); |
| 610 | + return false; |
| 611 | + } |
586 | 612 | } |
587 | 613 |
|
588 | | - try { |
589 | | - // Check if the token is still valid... |
590 | | - $token = $this->tokenProvider->getTokenById($tokenId); |
591 | | - $this->cache->set('t' . $tokenId, $token->getLastCheck(), 600); |
592 | | - if ($token->getLastCheck() > $maxAge) { |
593 | | - $this->printInfo('Device token is valid'); |
594 | | - } else { |
595 | | - $this->printInfo('Device token "last checked" is older than 60 days: ' . $token->getLastCheck()); |
| 614 | + if ($age > $maxAge) { |
| 615 | + $this->printInfo('Device token is valid'); |
| 616 | + return true; |
| 617 | + } |
| 618 | + |
| 619 | + $this->printInfo('Device token "last checked" is older than 60 days: ' . $age); |
| 620 | + return false; |
| 621 | + } |
| 622 | + |
| 623 | + /** |
| 624 | + * The functions are not part of public API so we are a bit more careful |
| 625 | + * @param IToken $token |
| 626 | + * @param 'getLastActivity'|'getType' $method |
| 627 | + * @return int|null |
| 628 | + */ |
| 629 | + protected function callSafelyForToken(IToken $token, string $method): ?int { |
| 630 | + if (method_exists($token, $method) || method_exists($token, '__call')) { |
| 631 | + try { |
| 632 | + $result = $token->$method(); |
| 633 | + if (is_int($result)) { |
| 634 | + return $result; |
| 635 | + } |
| 636 | + } catch (\BadFunctionCallException) { |
596 | 637 | } |
597 | | - return $token->getLastCheck() > $maxAge; |
598 | | - } catch (InvalidTokenException $e) { |
599 | | - // Token does not exist anymore, should drop the push device entry |
600 | | - $this->printInfo('InvalidTokenException is thrown'); |
601 | | - $this->deletePushToken($tokenId); |
602 | | - $this->cache->set('t' . $tokenId, 0, 600); |
603 | | - return false; |
604 | 638 | } |
| 639 | + return null; |
605 | 640 | } |
606 | 641 |
|
607 | 642 | /** |
|
0 commit comments