diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 8862be06..8188aaff 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -87,6 +87,10 @@ public function boot(IBootContext $context): void { } private function registerRedirect(IRequest $request, IURLGenerator $urlGenerator, SettingsService $settings, ProviderMapper $providerMapper): void { + // TODO when min supported version is >=28 : + // run this in a listener of OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent + // to avoid doing useless stuff on data requests and template requests that are not the login page + $providers = $this->getCachedProviders($providerMapper); $redirectUrl = $request->getParam('redirect_url'); @@ -98,6 +102,16 @@ private function registerRedirect(IRequest $request, IURLGenerator $urlGenerator // in case any errors happen when checking for the path do not apply redirect logic as it is only needed for the login } if ($isDefaultLogin && !$settings->getAllowMultipleUserBackEnds() && count($providers) === 1) { + // To avoid login/logout loop if the IdP session is still alive: + // if the login page's redirect_url GET param is the logout page, just use the base URL instead + $logoutUrl = $urlGenerator->linkToRoute('core.login.logout'); + $userOidcLogoutUrl = $urlGenerator->linkToRoute(self::APP_ID . '.login.singleLogoutService'); + if ( + $redirectUrl + && (strpos($redirectUrl, $logoutUrl) !== false || strpos($redirectUrl, $userOidcLogoutUrl) !== false) + ) { + $redirectUrl = $urlGenerator->getBaseUrl(); + } $targetUrl = $urlGenerator->linkToRoute(self::APP_ID . '.login.login', [ 'providerId' => $providers[0]->getId(), 'redirectUrl' => $redirectUrl diff --git a/lib/Controller/LoginController.php b/lib/Controller/LoginController.php index 8e84c3fd..13a793ba 100644 --- a/lib/Controller/LoginController.php +++ b/lib/Controller/LoginController.php @@ -209,6 +209,16 @@ private function buildProtocolErrorResponse(?bool $throttle = null): TemplateRes * @return DataDisplayResponse|RedirectResponse|TemplateResponse */ public function login(int $providerId, string $redirectUrl = null) { + // to be safe, avoid redirecting to logout or single-logout + $logoutUrl = $this->urlGenerator->linkToRoute('core.login.logout'); + $userOidcLogoutUrl = $this->urlGenerator->linkToRoute(Application::APP_ID . '.login.singleLogoutService'); + if ( + $redirectUrl + && (strpos($redirectUrl, $logoutUrl) !== false || strpos($redirectUrl, $userOidcLogoutUrl) !== false) + ) { + $redirectUrl = $this->urlGenerator->getBaseUrl(); + } + if ($this->userSession->isLoggedIn()) { return new RedirectResponse($redirectUrl); }