X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/fe07cdaa06d4a922c83c90fd373ca132a6098637..refs/pull/4467/head:/tests/Auth/Saml2Test.php diff --git a/tests/Auth/Saml2Test.php b/tests/Auth/Saml2Test.php index 7fb8d6ddb..801682a00 100644 --- a/tests/Auth/Saml2Test.php +++ b/tests/Auth/Saml2Test.php @@ -2,13 +2,13 @@ namespace Tests\Auth; -use BookStack\Auth\Role; -use BookStack\Auth\User; +use BookStack\Users\Models\Role; +use BookStack\Users\Models\User; use Tests\TestCase; class Saml2Test extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); // Set default config for SAML2 @@ -41,6 +41,20 @@ class Saml2Test extends TestCase $req->assertSee(url('/saml2/acs')); } + public function test_metadata_endpoint_loads_when_autoloading_with_bad_url_set() + { + config()->set([ + 'saml2.autoload_from_metadata' => true, + 'saml2.onelogin.idp.entityId' => 'http://192.168.1.1:9292', + 'saml2.onelogin.idp.singleSignOnService.url' => null, + ]); + + $req = $this->get('/saml2/metadata'); + $req->assertOk(); + $req->assertHeader('Content-Type', 'text/xml; charset=UTF-8'); + $req->assertSee('md:EntityDescriptor'); + } + public function test_onelogin_overrides_functions_as_expected() { $json = '{"sp": {"assertionConsumerService": {"url": "https://example.com/super-cats"}}, "contactPerson": {"technical": {"givenName": "Barry Scott", "emailAddress": "barry@example.com"}}}'; @@ -49,14 +63,14 @@ class Saml2Test extends TestCase $req = $this->get('/saml2/metadata'); $req->assertSee('https://example.com/super-cats'); $req->assertSee('md:ContactPerson'); - $req->assertSee('Barry Scott'); + $req->assertSee('Barry Scott', false); } public function test_login_option_shows_on_login_page() { $req = $this->get('/login'); $req->assertSeeText('SingleSignOn-Testing'); - $req->assertElementExists('form[action$="/saml2/login"][method=POST] button'); + $this->withHtml($req)->assertElementExists('form[action$="/saml2/login"][method=POST] button'); } public function test_login() @@ -119,7 +133,7 @@ class Saml2Test extends TestCase 'saml2.remove_from_groups' => false, ]); - $memberRole = factory(Role::class)->create(['external_auth_id' => 'member']); + $memberRole = Role::factory()->create(['external_auth_id' => 'member']); $adminRole = Role::getSystemRole('admin'); $this->followingRedirects()->post('/saml2/acs', ['SAMLResponse' => $this->acsPostData]); @@ -141,7 +155,7 @@ class Saml2Test extends TestCase $acsPost = $this->followingRedirects()->post('/saml2/acs', ['SAMLResponse' => $this->acsPostData]); $user = User::query()->where('external_auth_id', '=', 'user')->first(); - $randomRole = factory(Role::class)->create(['external_auth_id' => 'random']); + $randomRole = Role::factory()->create(['external_auth_id' => 'random']); $user->attachRole($randomRole); $this->assertContains($randomRole->id, $user->roles()->pluck('id')); @@ -156,9 +170,8 @@ class Saml2Test extends TestCase 'saml2.onelogin.strict' => false, ]); - $resp = $this->actingAs($this->getEditor())->get('/'); - $resp->assertElementExists('a[href$="/saml2/logout"]'); - $resp->assertElementContains('a[href$="/saml2/logout"]', 'Logout'); + $resp = $this->actingAs($this->users->editor())->get('/'); + $this->withHtml($resp)->assertElementContains('form[action$="/saml2/logout"] button', 'Logout'); } public function test_logout_sls_flow() @@ -177,9 +190,12 @@ class Saml2Test extends TestCase $this->followingRedirects()->post('/saml2/acs', ['SAMLResponse' => $this->acsPostData]); - $req = $this->get('/saml2/logout'); + $req = $this->post('/saml2/logout'); $redirect = $req->headers->get('location'); $this->assertStringStartsWith('http://saml.local/saml2/idp/SingleLogoutService.php', $redirect); + $sloData = $this->parseSamlDataFromUrl($redirect, 'SAMLRequest'); + $this->assertStringContainsString('_4fe7c0d1572d64b27f930aa6f236a6f42e930901cc', $sloData); + $this->withGet(['SAMLResponse' => $this->sloResponseData], $handleLogoutResponse); } @@ -193,7 +209,7 @@ class Saml2Test extends TestCase $this->followingRedirects()->post('/saml2/acs', ['SAMLResponse' => $this->acsPostData]); $this->assertTrue($this->isAuthenticated()); - $req = $this->get('/saml2/logout'); + $req = $this->post('/saml2/logout'); $req->assertRedirect('/'); $this->assertFalse($this->isAuthenticated()); } @@ -216,13 +232,13 @@ class Saml2Test extends TestCase public function test_saml_routes_are_only_active_if_saml_enabled() { config()->set(['auth.method' => 'standard']); - $getRoutes = ['/logout', '/metadata', '/sls']; + $getRoutes = ['/metadata', '/sls']; foreach ($getRoutes as $route) { $req = $this->get('/saml2' . $route); $this->assertPermissionError($req); } - $postRoutes = ['/login', '/acs']; + $postRoutes = ['/login', '/acs', '/logout']; foreach ($postRoutes as $route) { $req = $this->post('/saml2' . $route); $this->assertPermissionError($req); @@ -249,7 +265,7 @@ class Saml2Test extends TestCase $resp = $this->post('/login'); $this->assertPermissionError($resp); - $resp = $this->get('/logout'); + $resp = $this->post('/logout'); $this->assertPermissionError($resp); } @@ -295,7 +311,7 @@ class Saml2Test extends TestCase 'saml2.remove_from_groups' => false, ]); - $memberRole = factory(Role::class)->create(['external_auth_id' => 'member']); + $memberRole = Role::factory()->create(['external_auth_id' => 'member']); $adminRole = Role::getSystemRole('admin'); $acsPost = $this->followingRedirects()->post('/saml2/acs', ['SAMLResponse' => $this->acsPostData]); @@ -366,11 +382,16 @@ class Saml2Test extends TestCase { $req = $this->post('/saml2/login'); $location = $req->headers->get('Location'); - $query = explode('?', $location)[1]; + return $this->parseSamlDataFromUrl($location, 'SAMLRequest'); + } + + protected function parseSamlDataFromUrl(string $url, string $paramName): string + { + $query = explode('?', $url)[1]; $params = []; parse_str($query, $params); - return gzinflate(base64_decode($params['SAMLRequest'])); + return gzinflate(base64_decode($params[$paramName])); } protected function withGet(array $options, callable $callback)