aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Template
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2024-03-01 18:37:47 +0100
committerArthur Schiwon <blizzz@arthur-schiwon.de>2024-06-05 19:01:13 +0200
commit340939e688fab5c52061bc9e358587fbd8ec9fc8 (patch)
tree8f26c43cfdb8be01684fec40fdabf3b10e000a76 /lib/private/Template
parent31b0a44cf65b6625636ea0fa15fb1a1122b525e1 (diff)
downloadnextcloud-server-340939e688fab5c52061bc9e358587fbd8ec9fc8.tar.gz
nextcloud-server-340939e688fab5c52061bc9e358587fbd8ec9fc8.zip
fix(Session): avoid password confirmation on SSO
SSO backends like SAML and OIDC tried a trick to suppress password confirmations as they are not possible by design. At least for SAML it was not reliable when existing user backends where used as user repositories. Now we are setting a special scope with the token, and also make sure that the scope is taken over when tokens are regenerated. Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'lib/private/Template')
-rw-r--r--lib/private/Template/JSConfigHelper.php73
1 files changed, 37 insertions, 36 deletions
diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php
index 2f2ff9d64e3..5c38ae4cc72 100644
--- a/lib/private/Template/JSConfigHelper.php
+++ b/lib/private/Template/JSConfigHelper.php
@@ -8,10 +8,14 @@ declare(strict_types=1);
namespace OC\Template;
use bantu\IniGetWrapper\IniGetWrapper;
+use OC\Authentication\Token\IProvider;
use OC\CapabilitiesManager;
use OC\Share\Share;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
+use OCP\Authentication\Exceptions\ExpiredTokenException;
+use OCP\Authentication\Exceptions\InvalidTokenException;
+use OCP\Authentication\Exceptions\WipeTokenException;
use OCP\Constants;
use OCP\Defaults;
use OCP\Files\FileInfo;
@@ -23,48 +27,30 @@ use OCP\ILogger;
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUser;
+use OCP\Session\Exceptions\SessionNotAvailableException;
use OCP\Share\IManager as IShareManager;
use OCP\User\Backend\IPasswordConfirmationBackend;
use OCP\Util;
class JSConfigHelper {
- protected IL10N $l;
- protected Defaults $defaults;
- protected IAppManager $appManager;
- protected ISession $session;
- protected ?IUser $currentUser;
- protected IConfig $config;
- protected IGroupManager $groupManager;
- protected IniGetWrapper $iniWrapper;
- protected IURLGenerator $urlGenerator;
- protected CapabilitiesManager $capabilitiesManager;
- protected IInitialStateService $initialStateService;
/** @var array user back-ends excluded from password verification */
private $excludedUserBackEnds = ['user_saml' => true, 'user_globalsiteselector' => true];
- public function __construct(IL10N $l,
- Defaults $defaults,
- IAppManager $appManager,
- ISession $session,
- ?IUser $currentUser,
- IConfig $config,
- IGroupManager $groupManager,
- IniGetWrapper $iniWrapper,
- IURLGenerator $urlGenerator,
- CapabilitiesManager $capabilitiesManager,
- IInitialStateService $initialStateService) {
- $this->l = $l;
- $this->defaults = $defaults;
- $this->appManager = $appManager;
- $this->session = $session;
- $this->currentUser = $currentUser;
- $this->config = $config;
- $this->groupManager = $groupManager;
- $this->iniWrapper = $iniWrapper;
- $this->urlGenerator = $urlGenerator;
- $this->capabilitiesManager = $capabilitiesManager;
- $this->initialStateService = $initialStateService;
+ public function __construct(
+ protected IL10N $l,
+ protected Defaults $defaults,
+ protected IAppManager $appManager,
+ protected ISession $session,
+ protected ?IUser $currentUser,
+ protected IConfig $config,
+ protected IGroupManager $groupManager,
+ protected IniGetWrapper $iniWrapper,
+ protected IURLGenerator $urlGenerator,
+ protected CapabilitiesManager $capabilitiesManager,
+ protected IInitialStateService $initialStateService,
+ protected IProvider $tokenProvider,
+ ) {
}
public function getConfig(): string {
@@ -130,9 +116,13 @@ class JSConfigHelper {
}
if ($this->currentUser instanceof IUser) {
- $lastConfirmTimestamp = $this->session->get('last-password-confirm');
- if (!is_int($lastConfirmTimestamp)) {
- $lastConfirmTimestamp = 0;
+ if ($this->canUserValidatePassword()) {
+ $lastConfirmTimestamp = $this->session->get('last-password-confirm');
+ if (!is_int($lastConfirmTimestamp)) {
+ $lastConfirmTimestamp = 0;
+ }
+ } else {
+ $lastConfirmTimestamp = PHP_INT_MAX;
}
} else {
$lastConfirmTimestamp = 0;
@@ -287,4 +277,15 @@ class JSConfigHelper {
return $result;
}
+
+ protected function canUserValidatePassword(): bool {
+ try {
+ $token = $this->tokenProvider->getToken($this->session->getId());
+ } catch (ExpiredTokenException|WipeTokenException|InvalidTokenException|SessionNotAvailableException) {
+ // actually we do not know, so we fall back to this statement
+ return true;
+ }
+ $scope = $token->getScopeAsArray();
+ return !isset($scope['sso-based-login']) || $scope['sso-based-login'] === false;
+ }
}