Merge branch 'master' into 2.6

This commit is contained in:
mark_story 2014-07-09 10:17:05 -04:00
commit 3a70d9c033
12 changed files with 138 additions and 29 deletions

View file

@ -29,7 +29,7 @@ class DbAclSchema extends CakeSchema {
* Before event. * Before event.
* *
* @param array $event The event data. * @param array $event The event data.
* @return bool success * @return bool Success
*/ */
public function before($event = array()) { public function before($event = array()) {
return true; return true;
@ -56,10 +56,10 @@ class DbAclSchema extends CakeSchema {
'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'indexes' => array( 'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1), 'PRIMARY' => array('column' => 'id', 'unique' => 1),
'idx_acos_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0), 'idx_acos_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0),
'idx_acos_alias' => array('column' => 'alias', 'unique' => 0) 'idx_acos_alias' => array('column' => 'alias', 'unique' => 0)
) )
); );
/** /**
@ -74,10 +74,10 @@ class DbAclSchema extends CakeSchema {
'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'indexes' => array( 'indexes' => array(
'PRIMARY' => array('column' => 'id','unique' => 1), 'PRIMARY' => array('column' => 'id', 'unique' => 1),
'idx_aros_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0), 'idx_aros_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0),
'idx_aros_alias' => array('column' => 'alias', 'unique' => 0) 'idx_aros_alias' => array('column' => 'alias', 'unique' => 0)
) )
); );
/** /**
@ -93,10 +93,10 @@ class DbAclSchema extends CakeSchema {
'_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), '_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
'_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), '_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
'indexes' => array( 'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1), 'PRIMARY' => array('column' => 'id', 'unique' => 1),
'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1),
'idx_aco_id' => array('column' => 'aco_id', 'unique' => 0) 'idx_aco_id' => array('column' => 'aco_id', 'unique' => 0)
) )
); );
} }

View file

@ -470,8 +470,8 @@ class SecurityComponent extends Component {
$multi = array(); $multi = array();
foreach ($fieldList as $i => $key) { foreach ($fieldList as $i => $key) {
if (preg_match('/(\.\d+)+$/', $key)) { if (preg_match('/(\.\d+){1,10}$/', $key)) {
$multi[$i] = preg_replace('/(\.\d+)+$/', '', $key); $multi[$i] = preg_replace('/(\.\d+){1,10}$/', '', $key);
unset($fieldList[$i]); unset($fieldList[$i]);
} }
} }
@ -554,7 +554,9 @@ class SecurityComponent extends Component {
} }
if (!$this->csrfUseOnce) { if (!$this->csrfUseOnce) {
$csrfTokens = array_keys($token['csrfTokens']); $csrfTokens = array_keys($token['csrfTokens']);
$token['key'] = $csrfTokens[0]; $authKey = $csrfTokens[0];
$token['key'] = $authKey;
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
} }
$this->Session->write('_Token', $token); $this->Session->write('_Token', $token);
$request->params['_Token'] = array( $request->params['_Token'] = array(

View file

@ -285,6 +285,12 @@ class ExceptionRenderer {
} else { } else {
$this->_outputMessage('error500'); $this->_outputMessage('error500');
} }
} catch (MissingPluginException $e) {
$attributes = $e->getAttributes();
if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->plugin) {
$this->controller->plugin = null;
}
$this->_outputMessageSafe('error500');
} catch (Exception $e) { } catch (Exception $e) {
$this->_outputMessageSafe('error500'); $this->_outputMessageSafe('error500');
} }

View file

@ -714,11 +714,10 @@ class CakeSession {
* @return void * @return void
*/ */
public static function renew() { public static function renew() {
$id = session_id(); if (!session_id()) {
if (!$id) {
return; return;
} }
if ($id || isset($_COOKIE[session_name()])) { if (isset($_COOKIE[session_name()])) {
setcookie(Configure::read('Session.cookie'), '', time() - 42000, self::$path); setcookie(Configure::read('Session.cookie'), '', time() - 42000, self::$path);
} }
session_regenerate_id(true); session_regenerate_id(true);

View file

@ -3538,7 +3538,12 @@ class Model extends Object implements CakeEventListener {
$this->tablePrefix = $db->config['prefix']; $this->tablePrefix = $db->config['prefix'];
} }
$this->schemaName = (empty($this->schemaName) ? $db->getSchemaName() : $this->schemaName); $schema = $db->getSchemaName();
$defaultProperties = get_class_vars(get_class($this));
if (isset($defaultProperties['schemaName'])) {
$schema = $defaultProperties['schemaName'];
}
$this->schemaName = $schema;
} }
/** /**

View file

@ -834,12 +834,12 @@ class CakeResponse {
if ($public) { if ($public) {
$this->_cacheDirectives['public'] = true; $this->_cacheDirectives['public'] = true;
unset($this->_cacheDirectives['private']); unset($this->_cacheDirectives['private']);
$this->sharedMaxAge($time);
} else { } else {
$this->_cacheDirectives['private'] = true; $this->_cacheDirectives['private'] = true;
unset($this->_cacheDirectives['public']); unset($this->_cacheDirectives['public']);
$this->maxAge($time);
} }
$this->maxAge($time);
if (!$time) { if (!$time) {
$this->_setCacheControl(); $this->_setCacheControl();
} }

View file

@ -1214,8 +1214,7 @@ class SecurityComponentTest extends CakeTestCase {
$token = $this->Security->Session->read('_Token'); $token = $this->Security->Session->read('_Token');
$this->assertEquals(2, count($token['csrfTokens']), 'Missing the csrf token.'); $this->assertEquals(2, count($token['csrfTokens']), 'Missing the csrf token.');
foreach ($token['csrfTokens'] as $expires) { foreach ($token['csrfTokens'] as $expires) {
$diff = $csrfExpires - $expires; $this->assertWithinMargin($expires, $csrfExpires, 2, 'Token expiry does not match');
$this->assertTrue($diff === 0 || $diff === 1, 'Token expiry does not match');
} }
} }
@ -1250,6 +1249,23 @@ class SecurityComponentTest extends CakeTestCase {
$this->assertFalse(isset($token['csrfTokens']['nonce1']), 'Token was not consumed'); $this->assertFalse(isset($token['csrfTokens']['nonce1']), 'Token was not consumed');
} }
/**
* tests that reusable CSRF-token expiry is renewed
*/
public function testCsrfReusableTokenRenewal() {
$this->Security->validatePost = false;
$this->Security->csrfCheck = true;
$this->Security->csrfUseOnce = false;
$csrfExpires = '+10 minutes';
$this->Security->csrfExpires = $csrfExpires;
$this->Security->Session->write('_Token.csrfTokens', array('token' => strtotime('+1 minutes')));
$this->Security->startup($this->Controller);
$tokens = $this->Security->Session->read('_Token.csrfTokens');
$this->assertWithinMargin($tokens['token'], strtotime($csrfExpires), 2, 'Token expiry was not renewed');
}
/** /**
* test that expired values in the csrfTokens are cleaned up. * test that expired values in the csrfTokens are cleaned up.
* *

View file

@ -764,6 +764,73 @@ class ExceptionRendererTest extends CakeTestCase {
$this->assertEquals('Errors', $ExceptionRenderer->controller->viewPath); $this->assertEquals('Errors', $ExceptionRenderer->controller->viewPath);
} }
/**
* Test that missing plugin disables Controller::$plugin if the two are the same plugin.
*
* @return void
*/
public function testMissingPluginRenderSafe() {
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller = $this->getMock('Controller', array('render'));
$ExceptionRenderer->controller->plugin = 'TestPlugin';
$ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
$exception = new MissingPluginException(array('plugin' => 'TestPlugin'));
$ExceptionRenderer->controller->expects($this->once())
->method('render')
->with('error400')
->will($this->throwException($exception));
$response = $this->getMock('CakeResponse');
$response->expects($this->once())
->method('body')
->with($this->logicalAnd(
$this->logicalNot($this->stringContains('test plugin error500')),
$this->stringContains('Not Found')
));
$ExceptionRenderer->controller->response = $response;
$ExceptionRenderer->render();
}
/**
* Test that missing plugin doesn't disable Controller::$plugin if the two aren't the same plugin.
*
* @return void
*/
public function testMissingPluginRenderSafeWithPlugin() {
App::build(array(
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
), App::RESET);
CakePlugin::load('TestPlugin');
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);
$ExceptionRenderer->controller = $this->getMock('Controller', array('render'));
$ExceptionRenderer->controller->plugin = 'TestPlugin';
$ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
$exception = new MissingPluginException(array('plugin' => 'TestPluginTwo'));
$ExceptionRenderer->controller->expects($this->once())
->method('render')
->with('error400')
->will($this->throwException($exception));
$response = $this->getMock('CakeResponse');
$response->expects($this->once())
->method('body')
->with($this->logicalAnd(
$this->stringContains('test plugin error500'),
$this->stringContains('Not Found')
));
$ExceptionRenderer->controller->response = $response;
$ExceptionRenderer->render();
CakePlugin::unload();
}
/** /**
* Test that exceptions can be rendered when an request hasn't been registered * Test that exceptions can be rendered when an request hasn't been registered
* with Router * with Router

View file

@ -751,7 +751,7 @@ class CakeResponseTest extends CakeTestCase {
$response = new CakeResponse; $response = new CakeResponse;
$response->sharable(true, 3600); $response->sharable(true, 3600);
$headers = $response->header(); $headers = $response->header();
$this->assertEquals('public, s-maxage=3600', $headers['Cache-Control']); $this->assertEquals('public, max-age=3600', $headers['Cache-Control']);
$response = new CakeResponse; $response = new CakeResponse;
$response->sharable(false, 3600); $response->sharable(false, 3600);

View file

@ -1979,6 +1979,10 @@ class ValidationTest extends CakeTestCase {
$this->assertFalse(Validation::inList(2, array('1', '2x', '3'))); $this->assertFalse(Validation::inList(2, array('1', '2x', '3')));
$this->assertFalse(Validation::inList('One', array('one', 'two'))); $this->assertFalse(Validation::inList('One', array('one', 'two')));
// No hexadecimal for numbers.
$this->assertFalse(Validation::inList('0x7B', array('ABC', '123')));
$this->assertFalse(Validation::inList('0x7B', array('ABC', 123)));
// case insensitive // case insensitive
$this->assertTrue(Validation::inList('one', array('One', 'Two'), true)); $this->assertTrue(Validation::inList('one', array('One', 'Two'), true));
$this->assertTrue(Validation::inList('Two', array('one', 'two'), true)); $this->assertTrue(Validation::inList('Two', array('one', 'two'), true));

View file

@ -0,0 +1,11 @@
test plugin error500
<h2><?php echo $message; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
?>

View file

@ -814,14 +814,13 @@ class Validation {
* @return bool Success. * @return bool Success.
*/ */
public static function inList($check, $list, $caseInsensitive = false) { public static function inList($check, $list, $caseInsensitive = false) {
$strict = !is_numeric($check);
if ($caseInsensitive) { if ($caseInsensitive) {
$list = array_map('mb_strtolower', $list); $list = array_map('mb_strtolower', $list);
$check = mb_strtolower($check); $check = mb_strtolower($check);
} else {
$list = array_map('strval', $list);
} }
return in_array((string)$check, $list, true);
return in_array((string)$check, $list, $strict);
} }
/** /**