Merge pull request #898 from dnadesign/errorpagepermissions

FIX: ErrorPage generating empty responses for 403/401 requests
This commit is contained in:
Ingo Schommer 2013-11-22 11:49:37 -08:00
commit 6804461539
3 changed files with 46 additions and 18 deletions

View File

@ -42,7 +42,9 @@ class ErrorPage extends Page {
/** /**
* Get a {@link SS_HTTPResponse} to response to a HTTP error code if an * Get a {@link SS_HTTPResponse} to response to a HTTP error code if an
* {@link ErrorPage} for that code is present. * {@link ErrorPage} for that code is present. First tries to serve it
* through the standard SilverStripe request method. Falls back to a static
* file generated when the user hit's save and publish in the CMS
* *
* @param int $statusCode * @param int $statusCode
* *
@ -50,11 +52,17 @@ class ErrorPage extends Page {
*/ */
public static function response_for($statusCode) { public static function response_for($statusCode) {
// first attempt to dynamically generate the error page // first attempt to dynamically generate the error page
if($errorPage = DataObject::get_one('ErrorPage', "\"ErrorPage\".\"ErrorCode\" = $statusCode")) { $errorPage = ErrorPage::get()->filter(array(
"ErrorCode" => $statusCode
))->first();
if($errorPage) {
Requirements::clear(); Requirements::clear();
Requirements::clear_combined_files(); Requirements::clear_combined_files();
return ModelAsController::controller_for($errorPage)->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst()); return ModelAsController::controller_for($errorPage)->handleRequest(
new SS_HTTPRequest('GET', ''), DataModel::inst()
);
} }
// then fall back on a cached version // then fall back on a cached version
@ -62,13 +70,13 @@ class ErrorPage extends Page {
$statusCode, $statusCode,
class_exists('Translatable') ? Translatable::get_current_locale() : null class_exists('Translatable') ? Translatable::get_current_locale() : null
); );
if(file_exists($cachedPath)) { if(file_exists($cachedPath)) {
$response = new SS_HTTPResponse(); $response = new SS_HTTPResponse();
$response->setStatusCode($statusCode); $response->setStatusCode($statusCode);
$response->setBody(file_get_contents($cachedPath)); $response->setBody(file_get_contents($cachedPath));
return $response; return $response;
} }
} }
@ -129,13 +137,12 @@ class ErrorPage extends Page {
} }
} }
} }
} }
} }
/** /**
* Returns an array of arrays, each of which defines * Returns an array of arrays, each of which defines properties for a new
* properties for a new ErrorPage record. * ErrorPage record.
* *
* @return array * @return array
*/ */
@ -159,6 +166,7 @@ class ErrorPage extends Page {
) )
) )
); );
$this->extend('getDefaultRecords', $data); $this->extend('getDefaultRecords', $data);
return $data; return $data;
@ -316,14 +324,20 @@ class ErrorPage extends Page {
*/ */
class ErrorPage_Controller extends Page_Controller { class ErrorPage_Controller extends Page_Controller {
public function init() { /**
parent::init(); * Overload the provided {@link Controller::handleRequest()} to append the
* correct status code post request since otherwise permission related error
* pages such as 401 and 403 pages won't be rendered due to
* {@link SS_HTTPResponse::isFinished() ignoring the response body.
*
* @param SS_HTTPRequest
* @param DataModel
*/
public function handleRequest(SS_HTTPRequest $request, DataModel $model = NULL) {
$body = parent::handleRequest($request, $model);
$this->response->setStatusCode($this->ErrorCode);
$action = $this->request->param('Action'); return $this->response;
if(!$action || $action == 'index') {
$this->getResponse()->setStatusCode($this->failover->ErrorCode ? $this->failover->ErrorCode : 404);
}
} }
} }

View File

@ -60,5 +60,14 @@ class ErrorPageTest extends FunctionalTest {
/* Don't show the error page in the search */ /* Don't show the error page in the search */
$this->assertEquals($page->ShowInSearch, 0, 'Don\'t show the error page in search'); $this->assertEquals($page->ShowInSearch, 0, 'Don\'t show the error page in search');
} }
} public function testBehaviourOf403() {
$page = $this->objFromFixture('ErrorPage', '403');
$page->publish('Stage', 'Live');
$response = $this->get($page->Link());
$this->assertEquals($response->getStatusCode(), '403');
$this->assertNotNull($response->getBody(), 'We have body text from the error page');
}
}

View File

@ -3,4 +3,9 @@ ErrorPage:
Title: Page Not Found Title: Page Not Found
URLSegment: page-not-found URLSegment: page-not-found
Content: My error page body Content: My error page body
ErrorCode: 404 ErrorCode: 404
403:
Title: Permission Failure
URLSegment: permission-denied
Content: You do not have permission to view this page
ErrorCode: 403