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());
}
/**