From c49d40161b5d0d45c4e36bdc28e1c8aa13cee0ad Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Sun, 25 Jun 2017 15:13:19 +1200 Subject: [PATCH] API Update for HTTPMiddleware --- _config/versionedrequestprocessors.yml | 9 ++-- src/VersionedHTTPMiddleware.php | 66 ++++++++++++++++++++++++++ src/VersionedRequestFilter.php | 52 -------------------- tests/php/VersionedTest.php | 6 +-- 4 files changed, 73 insertions(+), 60 deletions(-) create mode 100644 src/VersionedHTTPMiddleware.php delete mode 100644 src/VersionedRequestFilter.php diff --git a/_config/versionedrequestprocessors.yml b/_config/versionedrequestprocessors.yml index 0fb6b83a0..87e691c88 100644 --- a/_config/versionedrequestprocessors.yml +++ b/_config/versionedrequestprocessors.yml @@ -2,11 +2,10 @@ Name: versionedrequestprocessors After: - 'requestprocessors' + - 'coresecurity' --- SilverStripe\Core\Injector\Injector: - VersionedRequestFilter: - class: SilverStripe\Versioned\VersionedRequestFilter - SilverStripe\Control\RequestProcessor: + SilverStripe\Control\Director: properties: - filters: - - '%$VersionedRequestFilter' + Middlewares: + VersionedMiddleware: %$SilverStripe\Versioned\VersionedHTTPMiddleware diff --git a/src/VersionedHTTPMiddleware.php b/src/VersionedHTTPMiddleware.php new file mode 100644 index 000000000..0465b94e4 --- /dev/null +++ b/src/VersionedHTTPMiddleware.php @@ -0,0 +1,66 @@ +setRequest($request); + $dummyController->pushCurrent(); + + // Permission check + try { + $result = $this->checkPermissions($request); + if ($result instanceof HTTPResponse) { + return $result; + } else { + // Set stage + Versioned::choose_site_stage($request); + } + } finally { + // Reset dummy controller + $dummyController->popCurrent(); + } + + // Process + return $next($request); + } + + /** + * @param HTTPRequest $request + * @return HTTPResponse|true True if ok, httpresponse if error + */ + protected function checkPermissions(HTTPRequest $request) + { + // Block non-authenticated users from setting the stage mode + if (Versioned::can_choose_site_stage($request)) { + return true; + } + + // Build error message + $link = Convert::raw2xml(Controller::join_links(Director::baseURL(), $request->getURL(), "?stage=Live")); + $permissionMessage = _t( + __CLASS__.'.DRAFT_SITE_ACCESS_RESTRICTION', + 'You must log in with your CMS password in order to view the draft or archived content. ' + . 'Click here to go back to the published site.', + [ 'link' => $link ] + ); + + // Force output since RequestFilter::preRequest doesn't support response overriding + return Security::permissionFailure(null, $permissionMessage); + } +} diff --git a/src/VersionedRequestFilter.php b/src/VersionedRequestFilter.php deleted file mode 100644 index 9a4fd5c40..000000000 --- a/src/VersionedRequestFilter.php +++ /dev/null @@ -1,52 +0,0 @@ -setRequest($request); - $dummyController->pushCurrent(); - - // Block non-authenticated users from setting the stage mode - if (!Versioned::can_choose_site_stage($request)) { - $link = Convert::raw2xml(Controller::join_links(Director::baseURL(), $request->getURL(), "?stage=Live")); - $permissionMessage = _t( - __CLASS__.'.DRAFT_SITE_ACCESS_RESTRICTION', - 'You must log in with your CMS password in order to view the draft or archived content. ' - . 'Click here to go back to the published site.', - [ 'link' => $link ] - ); - - // Force output since RequestFilter::preRequest doesn't support response overriding - $response = Security::permissionFailure($dummyController, $permissionMessage); - $request->getSession()->save(); - $dummyController->popCurrent(); - throw new HTTPResponse_Exception($response); - } - - Versioned::choose_site_stage($request); - $dummyController->popCurrent(); - return true; - } - - public function postRequest(HTTPRequest $request, HTTPResponse $response) - { - return true; - } -} diff --git a/tests/php/VersionedTest.php b/tests/php/VersionedTest.php index d7c676f55..d594ec17b 100644 --- a/tests/php/VersionedTest.php +++ b/tests/php/VersionedTest.php @@ -1026,14 +1026,14 @@ public function testReadingPersistent() /** * Test that stage parameter is blocked by non-administrative users - * - * @expectedException SilverStripe\Control\HTTPResponse_Exception */ public function testReadingModeSecurity() { $this->logOut(); $session = Injector::inst()->create(Session::class, []); - Director::test('/?stage=Stage', null, $session); + $result = Director::test('/?stage=Stage', null, $session); + // Redirects to login page + $this->assertEquals(302, $result->getStatusCode()); } /**