diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index dbd7cb5ac8be2..147cd8834d616 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -3110,7 +3110,6 @@ - diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index 5c11c4bba83dc..c358d21733feb 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -11,11 +11,11 @@ namespace OC\Core\Controller; use OC\AppFramework\Http\Request; +use OC\Authentication\Login\AlternativeLoginService; use OC\Authentication\Login\Chain; use OC\Authentication\Login\LoginData; use OC\Authentication\WebAuthn\Manager as WebAuthnManager; use OC\User\Session; -use OC_App; use OCA\User_LDAP\Configuration; use OCA\User_LDAP\Helper; use OCP\App\IAppManager; @@ -30,9 +30,10 @@ use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; +use OCP\Authentication\IAlternativeLogin; +use OCP\Config\IUserConfig; use OCP\Defaults; use OCP\IConfig; use OCP\IL10N; @@ -48,41 +49,40 @@ use OCP\Util; class LoginController extends Controller { - public const LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword'; - public const LOGIN_MSG_USERDISABLED = 'userdisabled'; - public const LOGIN_MSG_CSRFCHECKFAILED = 'csrfCheckFailed'; - public const LOGIN_MSG_INVALID_ORIGIN = 'invalidOrigin'; + public const string LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword'; + public const string LOGIN_MSG_USERDISABLED = 'userdisabled'; + public const string LOGIN_MSG_CSRFCHECKFAILED = 'csrfCheckFailed'; + public const string LOGIN_MSG_INVALID_ORIGIN = 'invalidOrigin'; public function __construct( - ?string $appName, + string $appName, IRequest $request, - private IUserManager $userManager, - private IConfig $config, - private ISession $session, - private Session $userSession, - private IURLGenerator $urlGenerator, - private Defaults $defaults, - private IThrottler $throttler, - private IInitialState $initialState, - private WebAuthnManager $webAuthnManager, - private IManager $manager, - private IL10N $l10n, - private IAppManager $appManager, + private readonly IUserManager $userManager, + private readonly IConfig $config, + private readonly IUserConfig $userConfig, + private readonly ISession $session, + private readonly Session $userSession, + private readonly IURLGenerator $urlGenerator, + private readonly Defaults $defaults, + private readonly IThrottler $throttler, + private readonly IInitialState $initialState, + private readonly WebAuthnManager $webAuthnManager, + private readonly IManager $manager, + private readonly IL10N $l10n, + private readonly IAppManager $appManager, + private readonly AlternativeLoginService $alternativeLoginService, ) { parent::__construct($appName, $request); } - /** - * @return RedirectResponse - */ #[NoAdminRequired] #[UseSession] #[FrontpageRoute(verb: 'GET', url: '/logout')] - public function logout() { + public function logout(): RedirectResponse { $loginToken = $this->request->getCookie('nc_token'); $uid = $this->userSession->getUser()?->getUID(); if ($loginToken !== null && $uid !== null) { - $this->config->deleteUserValue($uid, 'login_token', $loginToken); + $this->userConfig->deleteUserConfig($uid, 'login_token', $loginToken); } $this->userSession->logout(); @@ -107,22 +107,17 @@ public function logout() { return $response; } - /** - * @param string $user - * @param string $redirect_url - * - * @return TemplateResponse|RedirectResponse - */ #[NoCSRFRequired] #[PublicPage] #[UseSession] #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] #[FrontpageRoute(verb: 'GET', url: '/login')] - public function showLoginForm(?string $user = null, ?string $redirect_url = null): Response { + public function showLoginForm(?string $user = null, ?string $redirect_url = null): TemplateResponse|RedirectResponse { if ($this->userSession->isLoggedIn()) { return new RedirectResponse($this->urlGenerator->linkToDefaultPageUrl()); } + /** @var array|string $loginMessages */ $loginMessages = $this->session->get('loginMessages'); if (!$this->manager->isFairUseOfFreePushService()) { if (!is_array($loginMessages)) { @@ -153,13 +148,14 @@ public function showLoginForm(?string $user = null, ?string $redirect_url = null $this->config->getSystemValueInt('remember_login_cookie_lifetime', 60 * 60 * 24 * 15) > 0 ); - if (!empty($redirect_url)) { + if ($redirect_url !== null && $redirect_url !== '') { [$url, ] = explode('?', $redirect_url); if ($url !== $this->urlGenerator->linkToRoute('core.login.logout')) { $this->initialState->provideInitialState('loginRedirectUrl', $redirect_url); } } + /** @psalm-suppress */ $this->initialState->provideInitialState( 'loginThrottleDelay', $this->throttler->getDelay($this->request->getRemoteAddress()) @@ -185,7 +181,11 @@ public function showLoginForm(?string $user = null, ?string $redirect_url = null Util::addHeader('meta', ['name' => 'referrer', 'content' => 'same-origin']); $parameters = [ - 'alt_login' => OC_App::getAlternativeLogIns(), + 'alt_login' => array_map(static fn (IAlternativeLogin $alternativeLogin): array => [ + 'name' => $alternativeLogin->getLabel(), + 'href' => $alternativeLogin->getLink(), + 'class' => $alternativeLogin->getClass(), + ], $this->alternativeLoginService->getAlternativeLogins()), 'pageTitle' => $this->l10n->t('Login'), ]; @@ -203,8 +203,6 @@ public function showLoginForm(?string $user = null, ?string $redirect_url = null /** * Sets the password reset state - * - * @param string $username */ private function setPasswordResetInitialState(?string $username): void { if ($username !== null && $username !== '') { @@ -227,15 +225,14 @@ private function setPasswordResetInitialState(?string $username): void { } /** - * Sets the initial state of whether or not a user is allowed to login with their email + * Sets the initial state of whether a user is allowed to log in with their email * initial state is passed in the array of 1 for email allowed and 0 for not allowed */ private function setEmailStates(): void { - $emailStates = []; // true: can login with email, false otherwise - default to true + $emailStates = []; // true: can log in with email, false otherwise - default to true // check if user_ldap is enabled, and the required classes exist - if ($this->appManager->isAppLoaded('user_ldap') - && class_exists(Helper::class)) { + if ($this->appManager->isAppLoaded('user_ldap') && class_exists(Helper::class)) { $helper = Server::get(Helper::class); $allPrefixes = $helper->getServerConfigurationPrefixes(); // check each LDAP server the user is connected too @@ -248,15 +245,10 @@ private function setEmailStates(): void { } /** - * @param string|null $passwordLink - * @param IUser|null $user - * * Users may not change their passwords if: * - The account is disabled * - The backend doesn't support password resets * - The password reset function is disabled - * - * @return bool */ private function canResetPassword(?string $passwordLink, ?IUser $user): bool { if ($passwordLink === 'disabled') { @@ -366,29 +358,23 @@ public function tryLogin( ); } - if ($result->getRedirectUrl() !== null) { - return new RedirectResponse($result->getRedirectUrl()); + $redirectUrl = $result->getRedirectUrl(); + if ($redirectUrl !== null) { + return new RedirectResponse($redirectUrl); } return $this->generateRedirect($redirect_url); } /** * Creates a login failed response. - * - * @param string $user - * @param string $originalUser - * @param string $redirect_url - * @param string $loginMessage - * - * @return RedirectResponse */ private function createLoginFailedResponse( - $user, - $originalUser, - $redirect_url, + ?string $user, + string $originalUser, + ?string $redirect_url, string $loginMessage, bool $throttle = true, - ) { + ): RedirectResponse { // Read current user and append if possible we need to // return the unmodified user otherwise we will leak the login name $args = $user !== null ? ['user' => $originalUser, 'direct' => 1] : []; @@ -399,7 +385,7 @@ private function createLoginFailedResponse( $this->urlGenerator->linkToRoute('core.login.showLoginForm', $args) ); if ($throttle) { - $response->throttle(['user' => substr($user, 0, 64)]); + $response->throttle(['user' => substr($user ?? '', 0, 64)]); } $this->session->set('loginMessages', [ [$loginMessage], [] @@ -428,6 +414,9 @@ private function createLoginFailedResponse( #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT)] public function confirmPassword(string $password): DataResponse { $loginName = $this->userSession->getLoginName(); + if ($loginName === null) { + throw new \RuntimeException('Login name not set'); + } $loginResult = $this->userManager->checkPassword($loginName, $password); if ($loginResult === false) { $response = new DataResponse([], Http::STATUS_FORBIDDEN); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 06e2bba45eb35..5eafc8a84dbf6 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -1263,6 +1263,7 @@ 'OC\\Authentication\\LoginCredentials\\Credentials' => $baseDir . '/lib/private/Authentication/LoginCredentials/Credentials.php', 'OC\\Authentication\\LoginCredentials\\Store' => $baseDir . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Login\\ALoginCommand' => $baseDir . '/lib/private/Authentication/Login/ALoginCommand.php', + 'OC\\Authentication\\Login\\AlternativeLoginService' => $baseDir . '/lib/private/Authentication/Login/AlternativeLoginService.php', 'OC\\Authentication\\Login\\Chain' => $baseDir . '/lib/private/Authentication/Login/Chain.php', 'OC\\Authentication\\Login\\ClearLostPasswordTokensCommand' => $baseDir . '/lib/private/Authentication/Login/ClearLostPasswordTokensCommand.php', 'OC\\Authentication\\Login\\CompleteLoginCommand' => $baseDir . '/lib/private/Authentication/Login/CompleteLoginCommand.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 04b041895cca8..ff750bdc97072 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -1304,6 +1304,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Authentication\\LoginCredentials\\Credentials' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Credentials.php', 'OC\\Authentication\\LoginCredentials\\Store' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Store.php', 'OC\\Authentication\\Login\\ALoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/ALoginCommand.php', + 'OC\\Authentication\\Login\\AlternativeLoginService' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/AlternativeLoginService.php', 'OC\\Authentication\\Login\\Chain' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/Chain.php', 'OC\\Authentication\\Login\\ClearLostPasswordTokensCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/ClearLostPasswordTokensCommand.php', 'OC\\Authentication\\Login\\CompleteLoginCommand' => __DIR__ . '/../../..' . '/lib/private/Authentication/Login/CompleteLoginCommand.php', diff --git a/lib/private/Authentication/Login/AlternativeLoginService.php b/lib/private/Authentication/Login/AlternativeLoginService.php new file mode 100644 index 0000000000000..414eaf2d13939 --- /dev/null +++ b/lib/private/Authentication/Login/AlternativeLoginService.php @@ -0,0 +1,113 @@ + + */ + public function getAlternativeLogins(): array { + $result = []; + + foreach ($this->coordinator->getRegistrationContext()->getAlternativeLoginProviders() as $registration) { + if (!in_array(IAlternativeLoginProvider::class, class_implements($registration->getService()), true)) { + $this->logger->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [ + 'option' => $registration->getService(), + 'interface' => IAlternativeLoginProvider::class, + 'app' => $registration->getAppId(), + ]); + continue; + } + + try { + /** @var IAlternativeLoginProvider $provider */ + $provider = $this->container->get($registration->getService()); + } catch (ContainerExceptionInterface $e) { + $this->logger->error('Alternative login option {option} can not be initialized.', + [ + 'exception' => $e, + 'option' => $registration->getService(), + 'app' => $registration->getAppId(), + ]); + continue; + } + + foreach ($provider->getAlternativeLogins() as $alternativeLogin) { + try { + $alternativeLogin->load(); + + $result[] = $alternativeLogin; + } catch (Throwable $e) { + $this->logger->error('Alternative login option {option} had an error while loading.', + [ + 'exception' => $e, + 'option' => $registration->getService(), + 'app' => $registration->getAppId(), + ]); + } + } + } + + foreach ($this->coordinator->getRegistrationContext()->getAlternativeLogins() as $registration) { + if (!in_array(IAlternativeLogin::class, class_implements($registration->getService()), true)) { + $this->logger->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [ + 'option' => $registration->getService(), + 'interface' => IAlternativeLogin::class, + 'app' => $registration->getAppId(), + ]); + continue; + } + + try { + /** @var IAlternativeLogin $provider */ + $provider = $this->container->get($registration->getService()); + } catch (ContainerExceptionInterface $e) { + $this->logger->error('Alternative login option {option} can not be initialized.', + [ + 'exception' => $e, + 'option' => $registration->getService(), + 'app' => $registration->getAppId(), + ]); + } + + try { + $provider->load(); + + $result[] = $provider; + } catch (Throwable $e) { + $this->logger->error('Alternative login option {option} had an error while loading.', + [ + 'exception' => $e, + 'option' => $registration->getService(), + 'app' => $registration->getAppId(), + ]); + } + } + + return $result; + } +} diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php index 39c067e57304f..154a2934acfcf 100644 --- a/lib/private/legacy/OC_App.php +++ b/lib/private/legacy/OC_App.php @@ -8,14 +8,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ use OC\App\AppManager; -use OC\AppFramework\Bootstrap\Coordinator; use OC\Installer; use OC\NeedsUpdateException; use OC\SystemConfig; use OCP\App\AppPathNotFoundException; use OCP\App\IAppManager; -use OCP\Authentication\IAlternativeLogin; -use OCP\Authentication\IAlternativeLoginProvider; use OCP\BackgroundJob\IJobList; use OCP\IAppConfig; use OCP\IConfig; @@ -28,7 +25,6 @@ use OCP\L10N\IFactory; use OCP\Server; use OCP\Support\Subscription\IRegistry; -use Psr\Container\ContainerExceptionInterface; use Psr\Log\LoggerInterface; /** @@ -37,9 +33,6 @@ * upgrading and removing apps. */ class OC_App { - - /** @var list */ - private static array $altLogin = []; private static array $alreadyRegistered = []; public const supportedApp = 300; public const officialApp = 200; @@ -48,7 +41,6 @@ class OC_App { * @internal */ public static function reset(): void { - self::$altLogin = []; self::$alreadyRegistered = []; } @@ -270,107 +262,6 @@ public static function getCurrentApp(): string { } } - /** - * @deprecated 20.0.0 Please register your alternative login option using the registerAlternativeLogin() on the RegistrationContext in your Application class implementing the OCP\Authentication\IAlternativeLogin interface - */ - public static function registerLogIn(array $entry): void { - Server::get(LoggerInterface::class)->debug('OC_App::registerLogIn() is deprecated, please register your alternative login option using the registerAlternativeLogin() on the RegistrationContext in your Application class implementing the OCP\Authentication\IAlternativeLogin interface'); - self::$altLogin[] = $entry; - } - - /** - * @return list - */ - public static function getAlternativeLogIns(): array { - /** @var Coordinator $bootstrapCoordinator */ - $bootstrapCoordinator = Server::get(Coordinator::class); - - foreach ($bootstrapCoordinator->getRegistrationContext()->getAlternativeLoginProviders() as $registration) { - if (!in_array(IAlternativeLoginProvider::class, class_implements($registration->getService()), true)) { - Server::get(LoggerInterface::class)->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [ - 'option' => $registration->getService(), - 'interface' => IAlternativeLoginProvider::class, - 'app' => $registration->getAppId(), - ]); - continue; - } - - try { - /** @var IAlternativeLoginProvider $provider */ - $provider = Server::get($registration->getService()); - } catch (ContainerExceptionInterface $e) { - Server::get(LoggerInterface::class)->error('Alternative login option {option} can not be initialized.', - [ - 'exception' => $e, - 'option' => $registration->getService(), - 'app' => $registration->getAppId(), - ]); - continue; - } - - foreach ($provider->getAlternativeLogins() as $alternativeLogin) { - try { - $alternativeLogin->load(); - - self::$altLogin[] = [ - 'name' => $alternativeLogin->getLabel(), - 'href' => $alternativeLogin->getLink(), - 'class' => $alternativeLogin->getClass(), - ]; - } catch (Throwable $e) { - Server::get(LoggerInterface::class)->error('Alternative login option {option} had an error while loading.', - [ - 'exception' => $e, - 'option' => $registration->getService(), - 'app' => $registration->getAppId(), - ]); - } - } - } - - foreach ($bootstrapCoordinator->getRegistrationContext()->getAlternativeLogins() as $registration) { - if (!in_array(IAlternativeLogin::class, class_implements($registration->getService()), true)) { - Server::get(LoggerInterface::class)->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [ - 'option' => $registration->getService(), - 'interface' => IAlternativeLogin::class, - 'app' => $registration->getAppId(), - ]); - continue; - } - - try { - /** @var IAlternativeLogin $provider */ - $provider = Server::get($registration->getService()); - } catch (ContainerExceptionInterface $e) { - Server::get(LoggerInterface::class)->error('Alternative login option {option} can not be initialized.', - [ - 'exception' => $e, - 'option' => $registration->getService(), - 'app' => $registration->getAppId(), - ]); - } - - try { - $provider->load(); - - self::$altLogin[] = [ - 'name' => $provider->getLabel(), - 'href' => $provider->getLink(), - 'class' => $provider->getClass(), - ]; - } catch (Throwable $e) { - Server::get(LoggerInterface::class)->error('Alternative login option {option} had an error while loading.', - [ - 'exception' => $e, - 'option' => $registration->getService(), - 'app' => $registration->getAppId(), - ]); - } - } - - return self::$altLogin; - } - /** * get a list of all apps in the apps folder * diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php index 3c8fbd849b936..aab340ca2d7ce 100644 --- a/tests/Core/Controller/LoginControllerTest.php +++ b/tests/Core/Controller/LoginControllerTest.php @@ -10,6 +10,7 @@ namespace Tests\Core\Controller; +use OC\Authentication\Login\AlternativeLoginService; use OC\Authentication\Login\Chain as LoginChain; use OC\Authentication\Login\LoginData; use OC\Authentication\Login\LoginResult; @@ -20,6 +21,7 @@ use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; +use OCP\Config\IUserConfig; use OCP\Defaults; use OCP\IConfig; use OCP\IL10N; @@ -36,50 +38,22 @@ use Test\TestCase; class LoginControllerTest extends TestCase { - /** @var LoginController */ - private $loginController; - - /** @var IRequest|MockObject */ - private $request; - - /** @var IUserManager|MockObject */ - private $userManager; - - /** @var IConfig|MockObject */ - private $config; - - /** @var ISession|MockObject */ - private $session; - - /** @var Session|MockObject */ - private $userSession; - - /** @var IURLGenerator|MockObject */ - private $urlGenerator; - - /** @var Manager|MockObject */ - private $twoFactorManager; - - /** @var Defaults|MockObject */ - private $defaults; - - /** @var IThrottler|MockObject */ - private $throttler; - - /** @var IInitialState|MockObject */ - private $initialState; - - /** @var \OC\Authentication\WebAuthn\Manager|MockObject */ - private $webAuthnManager; - - /** @var IManager|MockObject */ - private $notificationManager; - - /** @var IL10N|MockObject */ - private $l; - - /** @var IAppManager|MockObject */ - private $appManager; + private LoginController $loginController; + private IRequest&MockObject $request; + private IUserManager&MockObject $userManager; + private IConfig&MockObject $config; + private IUserConfig&MockObject $userConfig; + private ISession&MockObject $session; + private Session&MockObject $userSession; + private IURLGenerator&MockObject $urlGenerator; + private Defaults&MockObject $defaults; + private IThrottler&MockObject $throttler; + private IInitialState&MockObject $initialState; + private \OC\Authentication\WebAuthn\Manager&MockObject $webAuthnManager; + private IManager&MockObject $notificationManager; + private IL10N&MockObject $l; + private IAppManager&MockObject $appManager; + private AlternativeLoginService&MockObject $alternativeLoginService; #[\Override] protected function setUp(): void { @@ -87,6 +61,7 @@ protected function setUp(): void { $this->request = $this->createMock(IRequest::class); $this->userManager = $this->createMock(\OC\User\Manager::class); $this->config = $this->createMock(IConfig::class); + $this->userConfig = $this->createMock(IUserConfig::class); $this->session = $this->createMock(ISession::class); $this->userSession = $this->createMock(Session::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); @@ -98,10 +73,11 @@ protected function setUp(): void { $this->notificationManager = $this->createMock(IManager::class); $this->l = $this->createMock(IL10N::class); $this->appManager = $this->createMock(IAppManager::class); + $this->alternativeLoginService = $this->createMock(AlternativeLoginService::class); $this->l->expects($this->any()) ->method('t') - ->willReturnCallback(function ($text, $parameters = []) { + ->willReturnCallback(function (string $text, array $parameters = []): string { return vsprintf($text, $parameters); }); @@ -121,6 +97,7 @@ protected function setUp(): void { $this->request, $this->userManager, $this->config, + $this->userConfig, $this->session, $this->userSession, $this->urlGenerator, @@ -131,6 +108,7 @@ protected function setUp(): void { $this->notificationManager, $this->l, $this->appManager, + $this->alternativeLoginService, ); } @@ -147,9 +125,9 @@ public function testLogoutWithoutToken(): void { ->expects($this->once()) ->method('isUserAgent') ->willReturn(false); - $this->config + $this->userConfig ->expects($this->never()) - ->method('deleteUserValue'); + ->method('deleteUserConfig'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') @@ -206,9 +184,9 @@ public function testLogoutWithToken(): void { ->expects($this->once()) ->method('getUser') ->willReturn($user); - $this->config + $this->userConfig ->expects($this->once()) - ->method('deleteUserValue') + ->method('deleteUserConfig') ->with('JohnDoe', 'login_token', 'MyLoginToken'); $this->urlGenerator ->expects($this->once()) @@ -341,25 +319,13 @@ public function testShowLoginFormForFlowAuth(): void { $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', 'login/flow')); } - /** - * @return array - */ - public static function passwordResetDataProvider(): array { - return [ - [ - true, - true, - ], - [ - false, - false, - ], - ]; + public static function passwordResetDataProvider(): \Generator { + yield [true, true]; + yield [false, false]; } #[DataProvider('passwordResetDataProvider')] - public function testShowLoginFormWithPasswordResetOption($canChangePassword, - $expectedResult): void { + public function testShowLoginFormWithPasswordResetOption(bool $canChangePassword, bool $expectedResult): void { $this->userSession ->expects($this->once()) ->method('isLoggedIn') @@ -486,15 +452,9 @@ public function testShowLoginFormForUserNamed0(): void { $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('0', '')); } - public static function remembermeProvider(): array { - return [ - [ - true, - ], - [ - false, - ], - ]; + public static function remembermeProvider(): \Generator { + yield [true]; + yield [false]; } #[DataProvider('remembermeProvider')] @@ -570,7 +530,6 @@ public function testLoginWithValidCredentials(bool $rememberme): void { #[DataProvider('remembermeProvider')] public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn(bool $rememberme): void { - /** @var IUser|MockObject $user */ $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') @@ -588,8 +547,8 @@ public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn(bool $rememberme): ->method('isLoggedIn') ->with() ->willReturn(false); - $this->config->expects($this->never()) - ->method('deleteUserValue'); + $this->userConfig->expects($this->never()) + ->method('deleteUserConfig'); $this->userSession->expects($this->never()) ->method('createRememberMeToken'); @@ -601,7 +560,6 @@ public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn(bool $rememberme): #[DataProvider('remembermeProvider')] public function testLoginWithoutPassedCsrfCheckAndLoggedIn(bool $rememberme): void { - /** @var IUser|MockObject $user */ $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') @@ -624,8 +582,8 @@ public function testLoginWithoutPassedCsrfCheckAndLoggedIn(bool $rememberme): vo ->method('getAbsoluteURL') ->with(urldecode($originalUrl)) ->willReturn($redirectUrl); - $this->config->expects($this->never()) - ->method('deleteUserValue'); + $this->userConfig->expects($this->never()) + ->method('deleteUserConfig'); $this->userSession->expects($this->never()) ->method('createRememberMeToken'); $this->config