diff --git a/modules/core/config/routes/routes.yaml b/modules/core/config/routes/routes.yaml index 75e62afa7d4a90ad26c29fd3515272cf62f3524f..11bfa24cccd864bd870965fa17554cadbce0dae4 100644 --- a/modules/core/config/routes/routes.yaml +++ b/modules/core/config/routes/routes.yaml @@ -1,3 +1,9 @@ +core-account: + path: /account/{as} + defaults: { _controller: 'SimpleSAML\Module\core\Controller\LoginController:account' } +core-account-disco-clearchoices: + path: /account/disco/clearchoices + defaults: { _controller: 'SimpleSAML\Module\core\Controller\LoginController:cleardiscochoices' } core-login: path: /login/{as} defaults: { _controller: 'SimpleSAML\Module\core\Controller\LoginController:login', as: null } diff --git a/modules/core/lib/Controller/LoginController.php b/modules/core/lib/Controller/LoginController.php index 94f3e7928d5ba4ef5caf991fef44f7bca2339fe2..c41d7e0539f01f62ec76db2c47c81f2e5500c07a 100644 --- a/modules/core/lib/Controller/LoginController.php +++ b/modules/core/lib/Controller/LoginController.php @@ -119,7 +119,7 @@ class LoginController */ public function login(Request $request, $as = null) { - //delete admin + // delete admin if (isset($this->sources['admin'])) { unset($this->sources['admin']); } @@ -184,4 +184,39 @@ class LoginController $auth = new Auth\Simple($as); return new RunnableResponse([$auth, 'logout'], [$this->config->getBasePath() . 'logout.php']); } + + + /** + * This clears the user's IdP discovery choices. + * + * @param Request $request The request that lead to this login operation. + * @return void + */ + public function cleardiscochoices(Request $request) + { + // The base path for cookies. This should be the installation directory for SimpleSAMLphp. + $cookiePath = $this->config->getBasePath(); + + // We delete all cookies which starts with 'idpdisco_' + foreach ($request->cookies->all() as $cookieName => $value) { + if (substr($cookieName, 0, 9) !== 'idpdisco_') { + // Not a idpdisco cookie. + continue; + } + + Utils\HTTP::setCookie($cookieName, null, ['path' => $cookiePath, 'httponly' => false], false); + } + + // Find where we should go now. + $returnTo = $request->get('ReturnTo', false); + if ($returnTo !== false) { + $returnTo = Utils\HTTP::checkURLAllowed($returnTo); + } else { + // Return to the front page if no other destination is given. This is the same as the base cookie path. + $returnTo = $cookiePath; + } + + // Redirect to destination. + Utils\HTTP::redirectTrustedURL($returnTo); + } } diff --git a/tests/modules/core/lib/Controller/LoginControllerTest.php b/tests/modules/core/lib/Controller/LoginControllerTest.php index 9e7c99513e40b8529ff985256a8dd7b068a9a135..4d4c989f266db4db5d55637e30088687fd35c64b 100644 --- a/tests/modules/core/lib/Controller/LoginControllerTest.php +++ b/tests/modules/core/lib/Controller/LoginControllerTest.php @@ -79,8 +79,8 @@ class LoginControllerTest extends ClearStateTestCase $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); - /** @var \SimpleSAML\HTTP\RunnableResponse $response */ $c = new LoginController($this->config, $session, $factory); + /** @var \SimpleSAML\HTTP\RunnableResponse $response */ $response = $c->login($request); $this->assertInstanceOf(RunnableResponse::class, $response); @@ -118,8 +118,8 @@ class LoginControllerTest extends ClearStateTestCase $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); - /** @var \SimpleSAML\XHTML\Template $response */ $c = new LoginController($this->config, $session, $factory); + /** @var \SimpleSAML\XHTML\Template $response */ $response = $c->login($request); $this->assertInstanceOf(Template::class, $response); @@ -142,7 +142,7 @@ class LoginControllerTest extends ClearStateTestCase $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); $c = new LoginController($this->config, $session, $factory); - $this->setExpectedException(Exception::class); + $this->expectException(Exception::class); $c->login($request, 'invalid-auth-source'); } @@ -176,8 +176,8 @@ class LoginControllerTest extends ClearStateTestCase $factory = new AuthenticationFactory($this->config, $session); $request = new Request(); - /** @var \Symfony\Component\HttpFoundation\RedirectResponse $response */ $c = new LoginController($this->config, $session, $factory); + /** @var \Symfony\Component\HttpFoundation\RedirectResponse $response */ $response = $c->login($request); $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertEquals(