publishSingle(); } } /** * Helper: FunctionalTest is only able to follow redirection once, we want to go all the way. * @param string $url * @return \SilverStripe\Control\HTTPResponse */ public function getAndFollowAll($url) { $response = $this->get($url); while ($location = $response->getHeader('Location')) { $response = $this->mainSession->followRedirection(); } echo $response->getHeader('Location'); return $response; } /** * Anonymous user cannot access anything. */ public function testAnonymousIsForbiddenAdminAccess() { $this->logOut(); $response = $this->getAndFollowAll('admin/pages/?SubsiteID=0'); $this->assertStringContainsString('Security/login', $this->mainSession->lastUrl(), 'Admin is disallowed'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $response = $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}"); $this->assertStringContainsString('Security/login', $this->mainSession->lastUrl(), 'Admin is disallowed'); $response = $this->getAndFollowAll('admin/subsite_xhr'); $this->assertStringContainsString( 'Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is disallowed' ); } /** * Admin should be able to access all subsites and the main site */ public function testAdminCanAccessAllSubsites() { $this->logInAs('admin'); $this->getAndFollowAll('admin/pages/?SubsiteID=0'); $this->assertEquals(0, $this->session()->get('SubsiteID'), 'Can access main site.'); $this->assertStringContainsString('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}"); // Check the session manually, since the state is unique to the request, not this test $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Can access other subsite.'); $this->assertStringContainsString('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section'); $response = $this->getAndFollowAll('admin/subsite_xhr'); $this->assertStringNotContainsString( 'Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is reachable' ); } public function testAdminIsRedirectedToObjectsSubsite() { $this->logInAs('admin'); $mainSubsitePage = $this->objFromFixture(Page::class, 'mainSubsitePage'); $subsite1Home = $this->objFromFixture(Page::class, 'subsite1_home'); // Requesting a page from another subsite will redirect to that subsite Config::modify()->set(CMSPageEditController::class, 'treats_subsite_0_as_global', false); $response = $this->get("admin/pages/edit/show/$subsite1Home->ID"); $this->assertEquals(302, $response->getStatusCode()); $this->assertStringContainsString( 'admin/pages/edit/show/' . $subsite1Home->ID . '?SubsiteID=' . $subsite1Home->SubsiteID, $response->getHeader('Location') ); // Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global Config::modify()->set(CMSPageEditController::class, 'treats_subsite_0_as_global', true); $response = $this->get("admin/pages/edit/show/$subsite1Home->ID"); $this->assertEquals(302, $response->getStatusCode()); $this->assertStringContainsString( 'admin/pages/edit/show/' . $subsite1Home->ID . '?SubsiteID=' . $subsite1Home->SubsiteID, $response->getHeader('Location') ); // Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global $response = $this->get("admin/pages/edit/show/$mainSubsitePage->ID"); $this->assertEquals(200, $response->getStatusCode()); } /** * User which has AccessAllSubsites set to 1 should be able to access all subsites and main site, * even though he does not have the ADMIN permission. */ public function testEditorCanAccessAllSubsites() { $this->logInAs('editor'); $this->get('admin/pages/?SubsiteID=0'); $this->assertEquals(0, $this->session()->get('SubsiteID'), 'Can access main site.'); $this->assertStringContainsString('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $this->get("admin/pages/?SubsiteID={$subsite1->ID}"); $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Can access other subsite.'); $this->assertStringContainsString('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section'); $response = $this->get('admin/subsite_xhr'); $this->assertStringNotContainsString( 'Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is reachable' ); } /** * Test a member who only has access to one subsite (subsite1) and only some sections (pages and security). */ public function testSubsiteAdmin() { $this->markTestSkipped('wip'); $this->logInAs('subsite1member'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); // Check allowed URL. $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}"); $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Can access own subsite.'); $this->assertStringContainsString( 'admin/pages', $this->mainSession->lastUrl(), 'Can access permitted section.' ); // Check forbidden section in allowed subsite. $this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}"); $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Is redirected within subsite.'); $this->assertNotContains( 'admin/assets', $this->mainSession->lastUrl(), 'Is redirected away from forbidden section' ); // Check forbidden site, on a section that's allowed on another subsite $this->getAndFollowAll('admin/pages/?SubsiteID=0'); $this->assertEquals( $this->session()->get('SubsiteID'), $subsite1->ID, 'Is redirected to permitted subsite.' ); // Check forbidden site, on a section that's not allowed on any other subsite $this->getAndFollowAll('admin/assets/?SubsiteID=0'); $this->assertEquals( $this->session()->get('SubsiteID'), $subsite1->ID, 'Is redirected to first permitted subsite.' ); $this->assertStringNotContainsString('Security/login', $this->mainSession->lastUrl(), 'Is not denied access'); // Check the standalone XHR controller. $response = $this->getAndFollowAll('admin/subsite_xhr'); $this->assertStringNotContainsString( 'Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is reachable' ); } }