mirror of
https://github.com/nextcloud/server.git
synced 2024-08-05 08:15:54 +02:00
Merge pull request #43942 from nextcloud/fix/43612/avoid-pwd-confirm-sso
fix(Session): avoid password confirmation on SSO
This commit is contained in:
commit
98b5cdc43d
@ -217,8 +217,8 @@ class AuthSettingsController extends Controller {
|
||||
$currentName = $token->getName();
|
||||
|
||||
if ($scope !== $token->getScopeAsArray()) {
|
||||
$token->setScope(['filesystem' => $scope['filesystem']]);
|
||||
$this->publishActivity($scope['filesystem'] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
|
||||
$token->setScope([IToken::SCOPE_FILESYSTEM => $scope[IToken::SCOPE_FILESYSTEM]]);
|
||||
$this->publishActivity($scope[IToken::SCOPE_FILESYSTEM] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
|
||||
}
|
||||
|
||||
if (mb_strlen($name) > 128) {
|
||||
|
@ -244,7 +244,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
|
||||
$token->expects($this->once())
|
||||
->method('getScopeAsArray')
|
||||
->willReturn(['filesystem' => true]);
|
||||
->willReturn([IToken::SCOPE_FILESYSTEM => true]);
|
||||
|
||||
$token->expects($this->once())
|
||||
->method('setName')
|
||||
@ -254,7 +254,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
->method('updateToken')
|
||||
->with($this->equalTo($token));
|
||||
|
||||
$this->assertSame([], $this->controller->update($tokenId, ['filesystem' => true], $newName));
|
||||
$this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], $newName));
|
||||
}
|
||||
|
||||
public function dataUpdateFilesystemScope(): array {
|
||||
@ -287,17 +287,17 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
|
||||
$token->expects($this->once())
|
||||
->method('getScopeAsArray')
|
||||
->willReturn(['filesystem' => $filesystem]);
|
||||
->willReturn([IToken::SCOPE_FILESYSTEM => $filesystem]);
|
||||
|
||||
$token->expects($this->once())
|
||||
->method('setScope')
|
||||
->with($this->equalTo(['filesystem' => $newFilesystem]));
|
||||
->with($this->equalTo([IToken::SCOPE_FILESYSTEM => $newFilesystem]));
|
||||
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('updateToken')
|
||||
->with($this->equalTo($token));
|
||||
|
||||
$this->assertSame([], $this->controller->update($tokenId, ['filesystem' => $newFilesystem], 'App password'));
|
||||
$this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => $newFilesystem], 'App password'));
|
||||
}
|
||||
|
||||
public function testUpdateNoChange(): void {
|
||||
@ -316,7 +316,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
|
||||
$token->expects($this->once())
|
||||
->method('getScopeAsArray')
|
||||
->willReturn(['filesystem' => true]);
|
||||
->willReturn([IToken::SCOPE_FILESYSTEM => true]);
|
||||
|
||||
$token->expects($this->never())
|
||||
->method('setName');
|
||||
@ -328,7 +328,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
->method('updateToken')
|
||||
->with($this->equalTo($token));
|
||||
|
||||
$this->assertSame([], $this->controller->update($tokenId, ['filesystem' => true], 'App password'));
|
||||
$this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], 'App password'));
|
||||
}
|
||||
|
||||
public function testUpdateExpired() {
|
||||
@ -348,7 +348,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
->method('updateToken')
|
||||
->with($this->equalTo($token));
|
||||
|
||||
$this->assertSame([], $this->controller->update($tokenId, ['filesystem' => true], 'App password'));
|
||||
$this->assertSame([], $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], 'App password'));
|
||||
}
|
||||
|
||||
public function testUpdateTokenWrongUser() {
|
||||
@ -366,7 +366,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
$this->tokenProvider->expects($this->never())
|
||||
->method('updateToken');
|
||||
|
||||
$response = $this->controller->update($tokenId, ['filesystem' => true], 'App password');
|
||||
$response = $this->controller->update($tokenId, [IToken::SCOPE_FILESYSTEM => true], 'App password');
|
||||
$this->assertSame([], $response->getData());
|
||||
$this->assertSame(\OCP\AppFramework\Http::STATUS_NOT_FOUND, $response->getStatus());
|
||||
}
|
||||
@ -380,7 +380,7 @@ class AuthSettingsControllerTest extends TestCase {
|
||||
$this->tokenProvider->expects($this->never())
|
||||
->method('updateToken');
|
||||
|
||||
$response = $this->controller->update(42, ['filesystem' => true], 'App password');
|
||||
$response = $this->controller->update(42, [IToken::SCOPE_FILESYSTEM => true], 'App password');
|
||||
$this->assertSame([], $response->getData());
|
||||
$this->assertSame(\OCP\AppFramework\Http::STATUS_NOT_FOUND, $response->getStatus());
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use OC\Authentication\Token\PublicKeyToken;
|
||||
use OCA\Settings\Settings\Personal\Security\Authtokens;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Services\IInitialState;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use OCP\ISession;
|
||||
use OCP\IUserSession;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
@ -91,7 +92,7 @@ class AuthtokensTest extends TestCase {
|
||||
'type' => 0,
|
||||
'canDelete' => false,
|
||||
'current' => true,
|
||||
'scope' => ['filesystem' => true],
|
||||
'scope' => [IToken::SCOPE_FILESYSTEM => true],
|
||||
'canRename' => false,
|
||||
],
|
||||
[
|
||||
@ -100,7 +101,7 @@ class AuthtokensTest extends TestCase {
|
||||
'lastActivity' => 0,
|
||||
'type' => 0,
|
||||
'canDelete' => true,
|
||||
'scope' => ['filesystem' => true],
|
||||
'scope' => [IToken::SCOPE_FILESYSTEM => true],
|
||||
'canRename' => true,
|
||||
],
|
||||
]
|
||||
|
@ -6,6 +6,7 @@
|
||||
namespace OC\Core\Controller;
|
||||
|
||||
use bantu\IniGetWrapper\IniGetWrapper;
|
||||
use OC\Authentication\Token\IProvider;
|
||||
use OC\CapabilitiesManager;
|
||||
use OC\Template\JSConfigHelper;
|
||||
use OCP\App\IAppManager;
|
||||
@ -42,6 +43,7 @@ class OCJSController extends Controller {
|
||||
IURLGenerator $urlGenerator,
|
||||
CapabilitiesManager $capabilitiesManager,
|
||||
IInitialStateService $initialStateService,
|
||||
IProvider $tokenProvider,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
@ -56,7 +58,8 @@ class OCJSController extends Controller {
|
||||
$iniWrapper,
|
||||
$urlGenerator,
|
||||
$capabilitiesManager,
|
||||
$initialStateService
|
||||
$initialStateService,
|
||||
$tokenProvider
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,8 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
||||
$c->get(IControllerMethodReflector::class),
|
||||
$c->get(ISession::class),
|
||||
$c->get(IUserSession::class),
|
||||
$c->get(ITimeFactory::class)
|
||||
$c->get(ITimeFactory::class),
|
||||
$c->get(\OC\Authentication\Token\IProvider::class),
|
||||
)
|
||||
);
|
||||
$dispatcher->registerMiddleware(
|
||||
|
@ -7,12 +7,18 @@ namespace OC\AppFramework\Middleware\Security;
|
||||
|
||||
use OC\AppFramework\Middleware\Security\Exceptions\NotConfirmedException;
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use OC\Authentication\Token\IProvider;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Authentication\Exceptions\ExpiredTokenException;
|
||||
use OCP\Authentication\Exceptions\InvalidTokenException;
|
||||
use OCP\Authentication\Exceptions\WipeTokenException;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use OCP\ISession;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Session\Exceptions\SessionNotAvailableException;
|
||||
use OCP\User\Backend\IPasswordConfirmationBackend;
|
||||
use ReflectionMethod;
|
||||
|
||||
@ -27,6 +33,7 @@ class PasswordConfirmationMiddleware extends Middleware {
|
||||
private $timeFactory;
|
||||
/** @var array */
|
||||
private $excludedUserBackEnds = ['user_saml' => true, 'user_globalsiteselector' => true];
|
||||
private IProvider $tokenProvider;
|
||||
|
||||
/**
|
||||
* PasswordConfirmationMiddleware constructor.
|
||||
@ -39,11 +46,14 @@ class PasswordConfirmationMiddleware extends Middleware {
|
||||
public function __construct(ControllerMethodReflector $reflector,
|
||||
ISession $session,
|
||||
IUserSession $userSession,
|
||||
ITimeFactory $timeFactory) {
|
||||
ITimeFactory $timeFactory,
|
||||
IProvider $tokenProvider,
|
||||
) {
|
||||
$this->reflector = $reflector;
|
||||
$this->session = $session;
|
||||
$this->userSession = $userSession;
|
||||
$this->timeFactory = $timeFactory;
|
||||
$this->tokenProvider = $tokenProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,8 +78,21 @@ class PasswordConfirmationMiddleware extends Middleware {
|
||||
$backendClassName = $user->getBackendClassName();
|
||||
}
|
||||
|
||||
try {
|
||||
$sessionId = $this->session->getId();
|
||||
$token = $this->tokenProvider->getToken($sessionId);
|
||||
} catch (SessionNotAvailableException|InvalidTokenException|WipeTokenException|ExpiredTokenException) {
|
||||
// States we do not deal with here.
|
||||
return;
|
||||
}
|
||||
$scope = $token->getScopeAsArray();
|
||||
if (isset($scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION]) && $scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION] === true) {
|
||||
// Users logging in from SSO backends cannot confirm their password by design
|
||||
return;
|
||||
}
|
||||
|
||||
$lastConfirm = (int) $this->session->get('last-password-confirm');
|
||||
// we can't check the password against a SAML backend, so skip password confirmation in this case
|
||||
// TODO: confirm excludedUserBackEnds can go away and remove it
|
||||
if (!isset($this->excludedUserBackEnds[$backendClassName]) && $lastConfirm < ($this->timeFactory->getTime() - (30 * 60 + 15))) { // allow 15 seconds delay
|
||||
throw new NotConfirmedException();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
||||
namespace OC\Authentication\Token;
|
||||
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
|
||||
/**
|
||||
* @method void setId(int $id)
|
||||
@ -162,7 +163,7 @@ class PublicKeyToken extends Entity implements INamedToken, IWipeableToken {
|
||||
$scope = json_decode($this->getScope(), true);
|
||||
if (!$scope) {
|
||||
return [
|
||||
'filesystem' => true
|
||||
IToken::SCOPE_FILESYSTEM => true
|
||||
];
|
||||
}
|
||||
return $scope;
|
||||
|
@ -243,6 +243,7 @@ class PublicKeyTokenProvider implements IProvider {
|
||||
OCPIToken::TEMPORARY_TOKEN,
|
||||
$token->getRemember()
|
||||
);
|
||||
$newToken->setScope($token->getScopeAsArray());
|
||||
$this->cacheToken($newToken);
|
||||
|
||||
$this->cacheInvalidHash($token->getToken());
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
namespace OC\Lockdown;
|
||||
|
||||
use OC\Authentication\Token\IToken;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use OCP\ISession;
|
||||
use OCP\Lockdown\ILockdownManager;
|
||||
|
||||
@ -60,6 +60,6 @@ class LockdownManager implements ILockdownManager {
|
||||
|
||||
public function canAccessFilesystem() {
|
||||
$scope = $this->getScopeAsArray();
|
||||
return !$scope || $scope['filesystem'];
|
||||
return !$scope || $scope[IToken::SCOPE_FILESYSTEM];
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,15 @@ 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\Authentication\Token\IToken;
|
||||
use OCP\Constants;
|
||||
use OCP\Defaults;
|
||||
use OCP\Files\FileInfo;
|
||||
@ -23,48 +28,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 +117,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 +278,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[IToken::SCOPE_SKIP_PASSWORD_VALIDATION]) || $scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION] === false;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
namespace OC;
|
||||
|
||||
use bantu\IniGetWrapper\IniGetWrapper;
|
||||
use OC\Authentication\Token\IProvider;
|
||||
use OC\Search\SearchQuery;
|
||||
use OC\Template\CSSResourceLocator;
|
||||
use OC\Template\JSConfigHelper;
|
||||
@ -225,7 +226,8 @@ class TemplateLayout extends \OC_Template {
|
||||
\OC::$server->get(IniGetWrapper::class),
|
||||
\OC::$server->getURLGenerator(),
|
||||
\OC::$server->get(CapabilitiesManager::class),
|
||||
\OCP\Server::get(IInitialStateService::class)
|
||||
\OCP\Server::get(IInitialStateService::class),
|
||||
\OCP\Server::get(IProvider::class),
|
||||
);
|
||||
$config = $jsConfigHelper->getConfig();
|
||||
if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
|
||||
|
@ -5,7 +5,9 @@
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
use OC\Authentication\Token\IProvider;
|
||||
use OC\User\LoginException;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\ISession;
|
||||
@ -166,6 +168,14 @@ class OC_User {
|
||||
|
||||
$userSession->createSessionToken($request, $uid, $uid, $password);
|
||||
$userSession->createRememberMeToken($userSession->getUser());
|
||||
|
||||
if (empty($password)) {
|
||||
$tokenProvider = \OC::$server->get(IProvider::class);
|
||||
$token = $tokenProvider->getToken($userSession->getSession()->getId());
|
||||
$token->setScope([IToken::SCOPE_SKIP_PASSWORD_VALIDATION => true]);
|
||||
$tokenProvider->updateToken($token);
|
||||
}
|
||||
|
||||
// setup the filesystem
|
||||
OC_Util::setupFS($uid);
|
||||
// first call the post_login hooks, the login-process needs to be
|
||||
|
@ -34,6 +34,15 @@ interface IToken extends JsonSerializable {
|
||||
*/
|
||||
public const REMEMBER = 1;
|
||||
|
||||
/**
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public const SCOPE_FILESYSTEM = 'filesystem';
|
||||
/**
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public const SCOPE_SKIP_PASSWORD_VALIDATION = 'password-unconfirmable';
|
||||
|
||||
/**
|
||||
* Get the token ID
|
||||
* @since 28.0.0
|
||||
|
@ -30,4 +30,8 @@ class PasswordConfirmationMiddlewareController extends \OCP\AppFramework\Control
|
||||
#[PasswordConfirmationRequired]
|
||||
public function testAttribute() {
|
||||
}
|
||||
|
||||
#[PasswordConfirmationRequired]
|
||||
public function testSSO() {
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ namespace Test\AppFramework\Middleware\Security;
|
||||
use OC\AppFramework\Middleware\Security\Exceptions\NotConfirmedException;
|
||||
use OC\AppFramework\Middleware\Security\PasswordConfirmationMiddleware;
|
||||
use OC\AppFramework\Utility\ControllerMethodReflector;
|
||||
use OC\Authentication\Token\IProvider;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
use OCP\IUser;
|
||||
@ -32,6 +34,7 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
private $controller;
|
||||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $timeFactory;
|
||||
private IProvider|\PHPUnit\Framework\MockObject\MockObject $tokenProvider;
|
||||
|
||||
protected function setUp(): void {
|
||||
$this->reflector = new ControllerMethodReflector();
|
||||
@ -39,6 +42,7 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->user = $this->createMock(IUser::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->tokenProvider = $this->createMock(IProvider::class);
|
||||
$this->controller = new PasswordConfirmationMiddlewareController(
|
||||
'test',
|
||||
$this->createMock(IRequest::class)
|
||||
@ -48,7 +52,8 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
$this->reflector,
|
||||
$this->session,
|
||||
$this->userSession,
|
||||
$this->timeFactory
|
||||
$this->timeFactory,
|
||||
$this->tokenProvider,
|
||||
);
|
||||
}
|
||||
|
||||
@ -90,6 +95,13 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
$this->timeFactory->method('getTime')
|
||||
->willReturn($currentTime);
|
||||
|
||||
$token = $this->createMock(IToken::class);
|
||||
$token->method('getScopeAsArray')
|
||||
->willReturn([]);
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->willReturn($token);
|
||||
|
||||
$thrown = false;
|
||||
try {
|
||||
$this->middleware->beforeController($this->controller, __FUNCTION__);
|
||||
@ -118,6 +130,13 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
$this->timeFactory->method('getTime')
|
||||
->willReturn($currentTime);
|
||||
|
||||
$token = $this->createMock(IToken::class);
|
||||
$token->method('getScopeAsArray')
|
||||
->willReturn([]);
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->willReturn($token);
|
||||
|
||||
$thrown = false;
|
||||
try {
|
||||
$this->middleware->beforeController($this->controller, __FUNCTION__);
|
||||
@ -128,6 +147,8 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
$this->assertSame($exception, $thrown);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function dataProvider() {
|
||||
return [
|
||||
['foo', 2000, 4000, true],
|
||||
@ -138,4 +159,41 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
|
||||
['foo', 2000, 3816, true],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSSO() {
|
||||
static $sessionId = 'mySession1d';
|
||||
|
||||
$this->reflector->reflect($this->controller, __FUNCTION__);
|
||||
|
||||
$this->user->method('getBackendClassName')
|
||||
->willReturn('fictional_backend');
|
||||
$this->userSession->method('getUser')
|
||||
->willReturn($this->user);
|
||||
|
||||
$this->session->method('get')
|
||||
->with('last-password-confirm')
|
||||
->willReturn(0);
|
||||
$this->session->method('getId')
|
||||
->willReturn($sessionId);
|
||||
|
||||
$this->timeFactory->method('getTime')
|
||||
->willReturn(9876);
|
||||
|
||||
$token = $this->createMock(IToken::class);
|
||||
$token->method('getScopeAsArray')
|
||||
->willReturn([IToken::SCOPE_SKIP_PASSWORD_VALIDATION => true]);
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->with($sessionId)
|
||||
->willReturn($token);
|
||||
|
||||
$thrown = false;
|
||||
try {
|
||||
$this->middleware->beforeController($this->controller, __FUNCTION__);
|
||||
} catch (NotConfirmedException) {
|
||||
$thrown = true;
|
||||
}
|
||||
|
||||
$this->assertSame(false, $thrown);
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,12 @@ declare(strict_types=1);
|
||||
namespace Test\Authentication\Token;
|
||||
|
||||
use OC\Authentication\Token\PublicKeyToken;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use Test\TestCase;
|
||||
|
||||
class PublicKeyTokenTest extends TestCase {
|
||||
public function testSetScopeAsArray() {
|
||||
$scope = ['filesystem' => false];
|
||||
$scope = [IToken::SCOPE_FILESYSTEM => false];
|
||||
$token = new PublicKeyToken();
|
||||
$token->setScope($scope);
|
||||
$this->assertEquals(json_encode($scope), $token->getScope());
|
||||
@ -21,7 +22,7 @@ class PublicKeyTokenTest extends TestCase {
|
||||
}
|
||||
|
||||
public function testDefaultScope() {
|
||||
$scope = ['filesystem' => true];
|
||||
$scope = [IToken::SCOPE_FILESYSTEM => true];
|
||||
$token = new PublicKeyToken();
|
||||
$this->assertEquals($scope, $token->getScopeAsArray());
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ namespace Test\Lockdown\Filesystem;
|
||||
use OC\Authentication\Token\PublicKeyToken;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Lockdown\Filesystem\NullStorage;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use Test\Traits\UserTrait;
|
||||
|
||||
/**
|
||||
@ -20,7 +21,7 @@ class NoFSTest extends \Test\TestCase {
|
||||
protected function tearDown(): void {
|
||||
$token = new PublicKeyToken();
|
||||
$token->setScope([
|
||||
'filesystem' => true
|
||||
IToken::SCOPE_FILESYSTEM => true
|
||||
]);
|
||||
\OC::$server->get('LockdownManager')->setToken($token);
|
||||
parent::tearDown();
|
||||
@ -30,7 +31,7 @@ class NoFSTest extends \Test\TestCase {
|
||||
parent::setUp();
|
||||
$token = new PublicKeyToken();
|
||||
$token->setScope([
|
||||
'filesystem' => false
|
||||
IToken::SCOPE_FILESYSTEM => false
|
||||
]);
|
||||
|
||||
\OC::$server->get('LockdownManager')->setToken($token);
|
||||
|
@ -8,6 +8,7 @@ namespace Test\Lockdown;
|
||||
|
||||
use OC\Authentication\Token\PublicKeyToken;
|
||||
use OC\Lockdown\LockdownManager;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
use OCP\ISession;
|
||||
use Test\TestCase;
|
||||
|
||||
@ -29,7 +30,7 @@ class LockdownManagerTest extends TestCase {
|
||||
|
||||
public function testCanAccessFilesystemAllowed() {
|
||||
$token = new PublicKeyToken();
|
||||
$token->setScope(['filesystem' => true]);
|
||||
$token->setScope([IToken::SCOPE_FILESYSTEM => true]);
|
||||
$manager = new LockdownManager($this->sessionCallback);
|
||||
$manager->setToken($token);
|
||||
$this->assertTrue($manager->canAccessFilesystem());
|
||||
@ -37,7 +38,7 @@ class LockdownManagerTest extends TestCase {
|
||||
|
||||
public function testCanAccessFilesystemNotAllowed() {
|
||||
$token = new PublicKeyToken();
|
||||
$token->setScope(['filesystem' => false]);
|
||||
$token->setScope([IToken::SCOPE_FILESYSTEM => false]);
|
||||
$manager = new LockdownManager($this->sessionCallback);
|
||||
$manager->setToken($token);
|
||||
$this->assertFalse($manager->canAccessFilesystem());
|
||||
|
Loading…
Reference in New Issue
Block a user