Skip to content
This repository has been archived by the owner on Aug 21, 2021. It is now read-only.

Commit

Permalink
Implementing a way to provide useful information about why something …
Browse files Browse the repository at this point in the history
…was blackholed
  • Loading branch information
Florian Krämer committed Oct 27, 2014
1 parent 5b32fd7 commit 9d8f6b4
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 6 deletions.
28 changes: 26 additions & 2 deletions lib/Cake/Controller/Component/SecurityComponent.php
Expand Up @@ -204,6 +204,13 @@ class SecurityComponent extends Component {
*/
protected $_action = null;

/**
* Collection of blackhole information
*
* @var array
*/
protected $_blackHoleData = array();

/**
* Request object
*
Expand Down Expand Up @@ -328,11 +335,12 @@ public function requireAuth() {
* @return mixed If specified, controller blackHoleCallback's response, or no return otherwise
* @see SecurityComponent::$blackHoleCallback
* @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#handling-blackhole-callbacks
* @throws BadRequestException
* @throws BlackHoleException
*/
public function blackHole(Controller $controller, $error = '') {
if (!$this->blackHoleCallback) {
throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
$this->_blackHoleData['error'] = $error;
throw new BlackHoleException(__d('cake_dev', 'The request has been black-holed'), 400, $this->_blackHoleData);
}
return $this->_callback($controller, $this->blackHoleCallback, array($error));
}
Expand Down Expand Up @@ -517,6 +525,22 @@ protected function _validatePost(Controller $controller) {
Configure::read('Security.salt')
);
$check = Security::hash(implode('', $hashParts), 'sha1');

if (Configure::read('debug') > 0) {
$blackholeFile = TMP . 'blackhole';
if (file_exists($blackholeFile)) {
$formData = file_get_contents($blackholeFile);
$formData = json_decode($formData, true);
$this->_blackHoleData['beforeSubmit'] = $formData;
$this->_blackHoleData['afterSubmit'] = array(
'fields' => $fieldList,
'unlocked' => $unlocked,
'hash' => $check
);
$this->_blackHoleData['dirtyFields'] = array_diff($formData['fields'], $fieldList);
}
}

return ($token === $check);
}

Expand Down
24 changes: 24 additions & 0 deletions lib/Cake/Error/ExceptionRenderer.php
Expand Up @@ -109,6 +109,9 @@ public function __construct(Exception $exception) {
$method = 'pdoError';
$template = 'pdo_error';
$code = 500;
} elseif ($exception instanceof BlackHoleException) {
$method = 'blackholeError';
$template = 'blackhole_error';
} elseif (!$methodExists) {
$method = 'error500';
if ($code >= 400 && $code < 500) {
Expand Down Expand Up @@ -199,6 +202,27 @@ protected function _cakeError(CakeException $error) {
$this->_outputMessage($this->template);
}

/**
* Generic handler for the internal framework errors CakePHP can generate.
*
* @param BlackHoleException $error
* @return void
*/
protected function blackholeError(BlackHoleException $error) {
$url = $this->controller->request->here();
$code = $error->getCode();
$this->controller->response->statusCode($code);
$this->controller->set(array(
'code' => $code,
'url' => h($url),
'name' => h($error->getMessage()),
'error' => $error,
'blackHoleData' => $error->getAttributes(),
'_serialize' => array('code', 'url', 'name', 'blackHoleData')
));
$this->_outputMessage($this->template);
}

/**
* Convenience method to display a 400 series page.
*
Expand Down
32 changes: 32 additions & 0 deletions lib/Cake/Error/exceptions.php
Expand Up @@ -87,6 +87,38 @@ public function __construct($message = null, $code = 400) {

}

/**
* Represents an HTTP 400 error.
*
* @package Cake.Error
*/
class BlackHoleException extends BadRequestException {

/**
* Constructor
*
* @param string $message If no message is given 'Bad Request' will be the message
* @param integer $code Status code, defaults to 400
*/
public function __construct($message = null, $code = 400, $blackHoleData = array()) {
debug($blackHoleData);
if (empty($message)) {
$message = 'Bad Request';
}
$this->_attributes = $blackHoleData;
parent::__construct($message, $code);
}

/**
* Get the passed in attributes
*
* @return array
*/
public function getAttributes() {
return $this->_attributes;
}
}

/**
* Represents an HTTP 401 error.
*
Expand Down
7 changes: 3 additions & 4 deletions lib/Cake/Model/Model.php
Expand Up @@ -2992,19 +2992,18 @@ public function buildQuery($type = 'first', $query = array()) {
}

$query['order'] = array($query['order']);

if ($query['callbacks'] === true || $query['callbacks'] === 'before') {
//if ($type === 'search') { debug($query['fields']); }
if ($query['callbacks'] === true || $query['callbacks'] === 'before' && $type !== 'search') {
$event = new CakeEvent('Model.beforeFind', $this, array($query));
list($event->break, $event->breakOn, $event->modParams) = array(true, array(false, null), 0);
$this->getEventManager()->dispatch($event);

if ($event->isStopped()) {
return null;
}

$query = $event->result === true ? $event->data[0] : $event->result;
}

//if ($type === 'search') { debug($query['fields']); }
return $query;
}

Expand Down
45 changes: 45 additions & 0 deletions lib/Cake/View/Errors/blackhole_error.ctp
@@ -0,0 +1,45 @@
<?php
/**
*
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Errors
* @since CakePHP(tm) v 2.2.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/

?>
<h2><?php echo __d('cake_dev', 'Blackhole Error'); ?></h2>
<p class="error">
<strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
<?php echo h($error->getMessage()); ?>
<br>

<strong><?php echo __d('cake_dev', 'File'); ?>: </strong>
<?php echo h($error->getFile()); ?>
<br>

<strong><?php echo __d('cake_dev', 'Line'); ?>: </strong>
<?php echo h($error->getLine()); ?>
</p>
<p class="notice">
<strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
<?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'fatal_error.ctp'); ?>
</p>

<h3><?php echo __d('cake_dev', 'Dirty Fields'); ?></h3>
<ul>
<?php foreach ($blackHoleData['dirtyFields'] as $key => $value) : ?>
<li>
<?php echo $key . ' => ' . $value; ?>
</li>
<?php endforeach; ?>
</ul>
9 changes: 9 additions & 0 deletions lib/Cake/View/Helper/FormHelper.php
Expand Up @@ -592,7 +592,16 @@ public function secure($fields = array(), $secureAttributes = array()) {
$unlocked,
Configure::read('Security.salt')
);

$debugData = array();
$debugData['fields'] = $fields;
$fields = Security::hash(implode('', $hashParts), 'sha1');
$debugData['unlocked'] = $unlocked;
$debugData['hash'] = $fields;

if (Configure::read('debug') > 0) {
file_put_contents(TMP . 'blackhole', json_encode($debugData, true));
}

$tokenFields = array_merge($secureAttributes, array(
'value' => urlencode($fields . ':' . $locked),
Expand Down

0 comments on commit 9d8f6b4

Please sign in to comment.