Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions lib/Service/TokenService.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use OC\Authentication\Token\IProvider;
use OCA\UserOIDC\AppInfo\Application;
use OCA\UserOIDC\Db\ProviderMapper;
use OCA\UserOIDC\Exception\TokenExchangeFailedException;
Expand All @@ -19,6 +20,10 @@
use OCP\App\IAppManager;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\Authentication\Exceptions\ExpiredTokenException;
use OCP\Authentication\Exceptions\InvalidTokenException;
use OCP\Authentication\Exceptions\WipeTokenException;
use OCP\Authentication\Token\IToken;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Http\Client\IClient;
use OCP\IConfig;
Expand All @@ -28,6 +33,7 @@
use OCP\IUserSession;
use OCP\PreConditionNotMetException;
use OCP\Security\ICrypto;
use OCP\Session\Exceptions\SessionNotAvailableException;
use Psr\Log\LoggerInterface;

/**
Expand All @@ -45,6 +51,7 @@ public function __construct(
public HttpClientHelper $clientService,
private ISession $session,
private IUserSession $userSession,
private IProvider $tokenProvider,
private IConfig $config,
private LoggerInterface $logger,
private ICrypto $crypto,
Expand Down Expand Up @@ -111,6 +118,7 @@ public function checkLoginToken(): void {
if (!$storeLoginTokenEnabled) {
return;
}
$this->logger->debug('[TokenService] checkLoginToken: store_login_token is enabled');

$currentUser = $this->userSession->getUser();
if (!$this->userSession->isLoggedIn() || $currentUser === null) {
Expand All @@ -122,6 +130,27 @@ public function checkLoginToken(): void {
return;
}

// Do not check the OIDC login token when not logged in via user_oidc (app password or direct login for example)
// Inspired from https://github.com/nextcloud/server/pull/43942/files#diff-c5cef03f925f97933ff9b3eb10217d21ef6516342e5628762756f1ba0469ac84R81-R92
try {
$sessionId = $this->session->getId();
$sessionAuthToken = $this->tokenProvider->getToken($sessionId);
} catch (SessionNotAvailableException|InvalidTokenException|WipeTokenException|ExpiredTokenException $e) {
// States we do not deal with here.
$this->logger->debug('[TokenService] checkLoginToken: error getting the session auth token', ['exception' => $e]);
return;
}
$scope = $sessionAuthToken->getScopeAsArray();
if (defined(IToken::class . '::SCOPE_SKIP_PASSWORD_VALIDATION')
&& (
!isset($scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION])
|| $scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION] === false
)
) {
$this->logger->debug('[TokenService] checkLoginToken: most likely not using user_oidc, the session auth token does not have the "skip pwd validation" scope');
return;
}

$token = $this->getToken();
if ($token === null) {
$this->logger->debug('[TokenService] checkLoginToken: token is null');
Expand All @@ -130,11 +159,14 @@ public function checkLoginToken(): void {
// so we need to reauthenticate
$this->logger->debug('[TokenService] checkLoginToken: token is null and user had_token_once -> logout');
$this->userSession->logout();
return;
} elseif ($token->isExpired()) {
$this->logger->debug('[TokenService] checkLoginToken: token is still expired -> reauthenticate');
// if the token is not valid, it means we couldn't refresh it so we need to reauthenticate to get a fresh token
$this->reauthenticate($token->getProviderId());
return;
}
$this->logger->debug('[TokenService] checkLoginToken: all good');
}

public function reauthenticate(int $providerId) {
Expand Down
Loading