From 171720b9cc4e77c52ab444e8fa36f7b4c8ddb6ba Mon Sep 17 00:00:00 2001 From: Tim van Dijen <tvdijen@gmail.com> Date: Wed, 23 Mar 2022 19:10:11 +0100 Subject: [PATCH] Add as much tests as we can right now i3x PSR012 --- composer.lock | 22 +-- lib/SimpleSAML/IdP/IFrameLogoutHandler.php | 1 - modules/core/lib/Controller/Logout.php | 23 ++- .../core/lib/Controller/LogoutTest.php | 168 +++++++++++++++++- 4 files changed, 196 insertions(+), 18 deletions(-) diff --git a/composer.lock b/composer.lock index f2ea7b063..b964c40c6 100644 --- a/composer.lock +++ b/composer.lock @@ -601,16 +601,16 @@ }, { "name": "simplesamlphp/saml2", - "version": "v4.5.0", + "version": "v4.5.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/saml2.git", - "reference": "d98020c3d7f7331409959eab286ca3a010e5a868" + "reference": "88586eb071476a74cd92d50cb789ad45c0b62f1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/d98020c3d7f7331409959eab286ca3a010e5a868", - "reference": "d98020c3d7f7331409959eab286ca3a010e5a868", + "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/88586eb071476a74cd92d50cb789ad45c0b62f1e", + "reference": "88586eb071476a74cd92d50cb789ad45c0b62f1e", "shasum": "" }, "require": { @@ -653,9 +653,9 @@ "description": "SAML2 PHP library from SimpleSAMLphp", "support": { "issues": "https://github.com/simplesamlphp/saml2/issues", - "source": "https://github.com/simplesamlphp/saml2/tree/v4.5.0" + "source": "https://github.com/simplesamlphp/saml2/tree/v4.5.1" }, - "time": "2022-02-17T15:46:12+00:00" + "time": "2022-03-22T12:02:23+00:00" }, { "name": "symfony/cache", @@ -6174,16 +6174,16 @@ }, { "name": "simplesamlphp/simplesamlphp-test-framework", - "version": "v1.1.6", + "version": "v1.1.7", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-test-framework.git", - "reference": "6e2d9a2eb98365d5c3b4faa66e0ea4a95833abd7" + "reference": "ffd6f5d68833482cb4473dfa4c26e8be272cbcbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-test-framework/zipball/6e2d9a2eb98365d5c3b4faa66e0ea4a95833abd7", - "reference": "6e2d9a2eb98365d5c3b4faa66e0ea4a95833abd7", + "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-test-framework/zipball/ffd6f5d68833482cb4473dfa4c26e8be272cbcbc", + "reference": "ffd6f5d68833482cb4473dfa4c26e8be272cbcbc", "shasum": "" }, "require": { @@ -6227,7 +6227,7 @@ "issues": "https://github.com/simplesamlphp/simplesamlphp-test-framework/issues", "source": "https://github.com/simplesamlphp/simplesamlphp-test-framework" }, - "time": "2022-02-13T14:45:14+00:00" + "time": "2022-03-22T12:04:35+00:00" }, { "name": "simplesamlphp/xml-common", diff --git a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php index 5ed469a0b..7541fa268 100644 --- a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php +++ b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php @@ -48,7 +48,6 @@ class IFrameLogoutHandler implements LogoutHandlerInterface */ public function startLogout(array &$state, ?string $assocId): void { -\SimpleSAML\Logger::debug("DEBUG"); $associations = $this->idp->getAssociations(); if (count($associations) === 0) { diff --git a/modules/core/lib/Controller/Logout.php b/modules/core/lib/Controller/Logout.php index 039cf98cc..3e3ab60ff 100644 --- a/modules/core/lib/Controller/Logout.php +++ b/modules/core/lib/Controller/Logout.php @@ -41,6 +41,12 @@ class Logout /** @var \SimpleSAML\Configuration */ protected Configuration $config; + /** + * @var \SimpleSAML\Auth\State|string + * @psalm-var \SimpleSAML\Auth\State|class-string + */ + protected $authState = Auth\State::class; + /** * Controller constructor. @@ -56,6 +62,17 @@ class Logout } + /** + * Inject the \SimpleSAML\Auth\State dependency. + * + * @param \SimpleSAML\Auth\State $authState + */ + public function setAuthState(Auth\State $authState): void + { + $this->authState = $authState; + } + + /** * Log the user out of a given authentication source. * @@ -110,7 +127,7 @@ class Logout $id = $request->query->get('id'); /** @psalm-var array $state */ - $state = Auth\State::loadState($id, 'core:Logout-IFrame'); + $state = $this->authState::loadState($id, 'core:Logout-IFrame'); $idp = IdP::getByState($state); $associations = $idp->getAssociations(); @@ -258,7 +275,7 @@ class Logout } /** @psalm-var array $state */ - $state = Auth\State::loadState($id, 'core:Logout-IFrame'); + $state = $this->authState::loadState($id, 'core:Logout-IFrame'); $idp = IdP::getByState($state); $mdh = MetaDataStorageHandler::getMetadataHandler(); @@ -391,7 +408,7 @@ class Logout $id = $request->query->get('id'); /** @psalm-var array $state */ - $state = Auth\State::loadState($id, 'core:Logout:afterbridge'); + $state = $this->authState::loadState($id, 'core:Logout:afterbridge'); $idp = IdP::getByState($state); $assocId = $state['core:TerminatedAssocId']; diff --git a/tests/modules/core/lib/Controller/LogoutTest.php b/tests/modules/core/lib/Controller/LogoutTest.php index 6fb32b175..0877b03a2 100644 --- a/tests/modules/core/lib/Controller/LogoutTest.php +++ b/tests/modules/core/lib/Controller/LogoutTest.php @@ -8,11 +8,8 @@ use SimpleSAML\Auth; use SimpleSAML\Configuration; use SimpleSAML\Error; use SimpleSAML\HTTP\RunnableResponse; -//use SimpleSAML\Locale\Localization; use SimpleSAML\Module\core\Controller; use SimpleSAML\TestUtils\ClearStateTestCase; -//use SimpleSAML\XHTML\Template; -//use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; /** @@ -43,6 +40,7 @@ class LogoutTest extends ClearStateTestCase [ 'baseurlpath' => 'https://example.org/simplesaml', 'module.enable' => ['exampleauth' => true], + 'enable.saml20-idp' => true, ], '[ARRAY]', 'simplesaml' @@ -105,4 +103,168 @@ class LogoutTest extends ClearStateTestCase $this->assertInstanceOf(RunnableResponse::class, $response); $this->assertEquals('https://example.org/something', $response->getArguments()[0]); } + + + public function testLogoutIframeDoneUnknownEntityThrowsException(): void + { + $request = Request::create( + '/logout-iframe-done', + 'GET', + ['id' => 'someState'], + ); + + $c = new Controller\Logout($this->config); + $c->setAuthState(new class () extends Auth\State { + public static function loadState(string $id, string $stage, bool $allowMissing = false): ?array + { + return ['core:IdP' => 'saml2:something']; + } + }); + + $this->expectException(Error\MetadataNotFound::class); + $c->logoutIframeDone($request); + } + + + public function testLogoutIframeDoneWithoutStateThrowsException(): void + { + $request = Request::create( + '/logout-iframe-done', + 'GET', + ['id' => 'someState'], + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\NoState::class); + $c->logoutIframeDone($request); + } + + + public function testLogoutIframeDoneWithoutIdThrowsException(): void + { + $request = Request::create( + '/logout-iframe-done', + 'GET', + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\BadRequest::class); + $c->logoutIframeDone($request); + } + + + public function testLogoutIframePostWithoutIdpThrowsException(): void + { + $request = Request::create( + '/logout-iframe-post', + 'GET', + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\BadRequest::class); + $c->logoutIframePost($request); + } + + + public function testLogoutIframePostUnknownEntityThrowsException(): void + { + $request = Request::create( + '/logout-iframe-post', + 'GET', + ['idp' => 'saml2:something'], + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\MetadataNotFound::class); + $c->logoutIframePost($request); + } + + + public function testLogoutIframeWithoutIdThrowsException(): void + { + $request = Request::create( + '/logout-iframe', + 'GET', + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\BadRequest::class); + $c->logoutIframe($request); + } + + + public function testLogoutIframeWithUnknownTypeThrowsException(): void + { + $request = Request::create( + '/logout-iframe', + 'GET', + ['id' => 'abc123', 'type' => 'foobar'], + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\BadRequest::class); + $c->logoutIframe($request); + } + + + public function testLogoutIframeUnknownEntityThrowsException(): void + { + $request = Request::create( + '/logout-iframe-post', + 'GET', + ['id' => 'abc123', 'type' => 'nojs'], + ); + + $c = new Controller\Logout($this->config); + $c->setAuthState(new class () extends Auth\State { + public static function loadState(string $id, string $stage, bool $allowMissing = false): ?array + { + return ['core:IdP' => 'saml2:something']; + } + }); + + $this->expectException(Error\MetadataNotFound::class); + $c->logoutIframe($request); + } + + + public function testResumeLogoutWithoutIdThrowsException(): void + { + $request = Request::create( + '/logout-resume', + 'GET', + ); + + $c = new Controller\Logout($this->config); + + $this->expectException(Error\BadRequest::class); + $c->resumeLogout($request); + } + + + public function testResumeLogoutWithUnknownEntityThrowsException(): void + { + $request = Request::create( + '/logout-resume', + 'GET', + ['id' => 'abc123'], + ); + + $c = new Controller\Logout($this->config); + $c->setAuthState(new class () extends Auth\State { + public static function loadState(string $id, string $stage, bool $allowMissing = false): ?array + { + return ['core:IdP' => 'saml2:something']; + } + }); + + $this->expectException(Error\MetadataNotFound::class); + $c->resumeLogout($request); + } } -- GitLab