Merge branch '2.x' into 2.next

This commit is contained in:
mark_story 2016-03-13 23:02:24 -04:00
commit c0a5d2b341
42 changed files with 807 additions and 101 deletions

View file

@ -133,11 +133,11 @@ class RedisEngine extends CacheEngine {
*/ */
public function read($key) { public function read($key) {
$value = $this->_Redis->get($key); $value = $this->_Redis->get($key);
if (ctype_digit($value)) { if (preg_match('/^[-]?\d+$/', $value)) {
$value = (int)$value; return (int)$value;
} }
if ($value !== false && is_string($value)) { if ($value !== false && is_string($value)) {
$value = unserialize($value); return unserialize($value);
} }
return $value; return $value;
} }

View file

@ -655,7 +655,7 @@ class AuthComponent extends Component {
* cookies + sessions will be used. * cookies + sessions will be used.
* *
* @param string|null $key field to retrieve. Leave null to get entire User record * @param string|null $key field to retrieve. Leave null to get entire User record
* @return array|null User record. or null if no user is logged in. * @return mixed|null User record. or null if no user is logged in.
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
*/ */
public static function user($key = null) { public static function user($key = null) {

View file

@ -92,6 +92,7 @@ class SecurityComponent extends Component {
* *
* @var array * @var array
* @see SecurityComponent::requireAuth() * @see SecurityComponent::requireAuth()
* @deprecated 2.8.1 This feature is confusing and not useful.
*/ */
public $requireAuth = array(); public $requireAuth = array();
@ -400,6 +401,7 @@ class SecurityComponent extends Component {
* *
* @param Controller $controller Instantiating controller * @param Controller $controller Instantiating controller
* @return bool|null True if authentication required * @return bool|null True if authentication required
* @deprecated 2.8.1 This feature is confusing and not useful.
*/ */
protected function _authRequired(Controller $controller) { protected function _authRequired(Controller $controller) {
if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($this->request->data)) { if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($this->request->data)) {
@ -532,7 +534,7 @@ class SecurityComponent extends Component {
} }
return false; return false;
} }
$authKey = Security::generateAuthKey(); $authKey = hash('sha512', Security::randomBytes(16), false);
$token = array( $token = array(
'key' => $authKey, 'key' => $authKey,
'allowedControllers' => $this->allowedControllers, 'allowedControllers' => $this->allowedControllers,

View file

@ -1006,7 +1006,7 @@ class Controller extends Object implements CakeEventListener {
* @param string $layout Layout you want to use, defaults to 'flash' * @param string $layout Layout you want to use, defaults to 'flash'
* @return void * @return void
* @link http://book.cakephp.org/2.0/en/controllers.html#Controller::flash * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::flash
* @deprecated 3.0.0 Will be removed in 3.0. Use Session::setFlash(). * @deprecated 3.0.0 Will be removed in 3.0. Use Flash::set() with version 2.7+ or Session::setFlash() prior to 2.7.
*/ */
public function flash($message, $url, $pause = 1, $layout = 'flash') { public function flash($message, $url, $pause = 1, $layout = 'flash') {
$this->autoRender = false; $this->autoRender = false;

View file

@ -568,7 +568,7 @@ class TreeBehavior extends ModelBehavior {
* @return array Options array * @return array Options array
*/ */
protected function _getOptions($arg) { protected function _getOptions($arg) {
return count(array_filter(array_keys($arg), 'is_string') > 0) ? return count(array_filter(array_keys($arg), 'is_string')) > 0 ?
$arg : $arg :
array(); array();
} }
@ -577,9 +577,9 @@ class TreeBehavior extends ModelBehavior {
* Get the path to the given node * Get the path to the given node
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param int|string $id The ID of the record to read * @param int|string|null $id The ID of the record to read
* @param string|array $fields Either a single string of a field name, or an array of field names * @param string|array|null $fields Either a single string of a field name, or an array of field names
* @param int $recursive The number of levels deep to fetch associated records * @param int|null $recursive The number of levels deep to fetch associated records
* @return array Array of nodes from top most parent to current node * @return array Array of nodes from top most parent to current node
* @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::getPath * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::getPath
*/ */
@ -639,7 +639,7 @@ class TreeBehavior extends ModelBehavior {
* If the node is the last child, or is a top level node with no subsequent node this method will return false * If the node is the last child, or is a top level node with no subsequent node this method will return false
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param int|string $id The ID of the record to move * @param int|string|null $id The ID of the record to move
* @param int|bool $number how many places to move the node or true to move to last position * @param int|bool $number how many places to move the node or true to move to last position
* @return bool true on success, false on failure * @return bool true on success, false on failure
* @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::moveDown * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::moveDown
@ -693,7 +693,7 @@ class TreeBehavior extends ModelBehavior {
* If the node is the first child, or is a top level node with no previous node this method will return false * If the node is the first child, or is a top level node with no previous node this method will return false
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param int|string $id The ID of the record to move * @param int|string|null $id The ID of the record to move
* @param int|bool $number how many places to move the node, or true to move to first position * @param int|bool $number how many places to move the node, or true to move to first position
* @return bool true on success, false on failure * @return bool true on success, false on failure
* @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::moveUp * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::moveUp
@ -751,7 +751,7 @@ class TreeBehavior extends ModelBehavior {
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param string $mode parent or tree * @param string $mode parent or tree
* @param string|int $missingParentAction 'return' to do nothing and return, 'delete' to * @param string|int|null $missingParentAction 'return' to do nothing and return, 'delete' to
* delete, or the id of the parent to set as the parent_id * delete, or the id of the parent to set as the parent_id
* @return bool true on success, false on failure * @return bool true on success, false on failure
* @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::recover * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::recover
@ -811,7 +811,7 @@ class TreeBehavior extends ModelBehavior {
* *
* @param Model $Model Model instance. * @param Model $Model Model instance.
* @param int $counter Counter * @param int $counter Counter
* @param mixed $parentId Parent record Id * @param int|string|null $parentId Parent record Id
* @return int counter * @return int counter
*/ */
protected function _recoverByParentId(Model $Model, $counter = 1, $parentId = null) { protected function _recoverByParentId(Model $Model, $counter = 1, $parentId = null) {
@ -929,7 +929,7 @@ class TreeBehavior extends ModelBehavior {
* after the children are reparented. * after the children are reparented.
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param int|string $id The ID of the record to remove * @param int|string|null $id The ID of the record to remove
* @param bool $delete whether to delete the node after reparenting children (if any) * @param bool $delete whether to delete the node after reparenting children (if any)
* @return bool true on success, false on failure * @return bool true on success, false on failure
* @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::removeFromTree * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::removeFromTree
@ -1064,7 +1064,7 @@ class TreeBehavior extends ModelBehavior {
* Returns the depth level of a node in the tree. * Returns the depth level of a node in the tree.
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param int|string $id The primary key for record to get the level of. * @param int|string|null $id The primary key for record to get the level of.
* @return int|bool Integer of the level or false if the node does not exist. * @return int|bool Integer of the level or false if the node does not exist.
*/ */
public function getLevel(Model $Model, $id = null) { public function getLevel(Model $Model, $id = null) {
@ -1103,7 +1103,7 @@ class TreeBehavior extends ModelBehavior {
* method could be private, since calling save with parent_id set also calls setParent * method could be private, since calling save with parent_id set also calls setParent
* *
* @param Model $Model Model using this behavior * @param Model $Model Model using this behavior
* @param int|string $parentId Parent record Id * @param int|string|null $parentId Parent record Id
* @param bool $created True if newly created record else false. * @param bool $created True if newly created record else false.
* @return bool true on success, false on failure * @return bool true on success, false on failure
*/ */

View file

@ -368,7 +368,7 @@ class DataSource extends Object {
} else { } else {
$found = false; $found = false;
foreach (array_reverse($stack) as $assocData) { foreach (array_reverse($stack) as $assocData) {
if (isset($data[$assocData]) && isset($data[$assocData][$insertKey])) { if (is_string($assocData) && isset($data[$assocData]) && isset($data[$assocData][$insertKey])) {
$val = $data[$assocData][$insertKey]; $val = $data[$assocData][$insertKey];
$found = true; $found = true;
break; break;

View file

@ -68,7 +68,8 @@ class Postgres extends DboSource {
'binary' => array('name' => 'bytea'), 'binary' => array('name' => 'bytea'),
'boolean' => array('name' => 'boolean'), 'boolean' => array('name' => 'boolean'),
'number' => array('name' => 'numeric'), 'number' => array('name' => 'numeric'),
'inet' => array('name' => 'inet') 'inet' => array('name' => 'inet'),
'uuid' => array('name' => 'uuid')
); );
/** /**
@ -216,6 +217,7 @@ class Postgres extends DboSource {
$length = null; $length = null;
$type = 'text'; $type = 'text';
} elseif ($c->type === 'uuid') { } elseif ($c->type === 'uuid') {
$type = 'uuid';
$length = 36; $length = 36;
} else { } else {
$length = (int)$c->oct_length; $length = (int)$c->oct_length;
@ -241,7 +243,10 @@ class Postgres extends DboSource {
if ($model instanceof Model) { if ($model instanceof Model) {
if ($c->name === $model->primaryKey) { if ($c->name === $model->primaryKey) {
$fields[$c->name]['key'] = 'primary'; $fields[$c->name]['key'] = 'primary';
if ($fields[$c->name]['type'] !== 'string') { if (
$fields[$c->name]['type'] !== 'string' &&
$fields[$c->name]['type'] !== 'uuid'
) {
$fields[$c->name]['length'] = 11; $fields[$c->name]['length'] = 11;
} }
} }
@ -698,8 +703,10 @@ class Postgres extends DboSource {
return 'biginteger'; return 'biginteger';
case (strpos($col, 'int') !== false && $col !== 'interval'): case (strpos($col, 'int') !== false && $col !== 'interval'):
return 'integer'; return 'integer';
case (strpos($col, 'char') !== false || $col === 'uuid'): case (strpos($col, 'char') !== false):
return 'string'; return 'string';
case (strpos($col, 'uuid') !== false):
return 'uuid';
case (strpos($col, 'text') !== false): case (strpos($col, 'text') !== false):
return 'text'; return 'text';
case (strpos($col, 'bytea') !== false): case (strpos($col, 'bytea') !== false):
@ -922,6 +929,17 @@ class Postgres extends DboSource {
return $join; return $join;
} }
/**
* {@inheritDoc}
*/
public function value($data, $column = null, $null = true) {
$value = parent::value($data, $column, $null);
if ($column === 'uuid' && is_scalar($data) && $data === '') {
return 'NULL';
}
return $value;
}
/** /**
* Overrides DboSource::renderStatement to handle schema generation with Postgres-style indexes * Overrides DboSource::renderStatement to handle schema generation with Postgres-style indexes
* *

View file

@ -1982,7 +1982,7 @@ class Model extends Object implements CakeEventListener {
*/ */
protected function _isUUIDField($field) { protected function _isUUIDField($field) {
$field = $this->schema($field); $field = $this->schema($field);
return $field['length'] == 36 && in_array($field['type'], array('string', 'binary')); return $field['length'] == 36 && in_array($field['type'], array('string', 'binary', 'uuid'));
} }
/** /**
@ -2937,7 +2937,7 @@ class Model extends Object implements CakeEventListener {
* 'conditions' => array('name' => 'Thomas Anderson'), * 'conditions' => array('name' => 'Thomas Anderson'),
* 'fields' => array('name', 'email'), * 'fields' => array('name', 'email'),
* 'order' => 'field3 DESC', * 'order' => 'field3 DESC',
* 'recursive' => 2, * 'recursive' => 1,
* 'group' => 'type', * 'group' => 'type',
* 'callbacks' => false, * 'callbacks' => false,
* )); * ));
@ -3011,15 +3011,15 @@ class Model extends Object implements CakeEventListener {
* *
* ``` * ```
* protected function _readDataSource($type, $query) { * protected function _readDataSource($type, $query) {
* $cacheName = md5(json_encode($query)); * $cacheName = md5(json_encode($query) . json_encode($this->hasOne) . json_encode($this->belongsTo));
* $cache = Cache::read($cacheName, 'cache-config-name'); * $cache = Cache::read($cacheName, 'cache-config-name');
* if ($cache !== false) { * if ($cache !== false) {
* return $cache; * return $cache;
* } * }
* *
* $results = parent::_readDataSource($type, $query); * $results = parent::_readDataSource($type, $query);
* Cache::write($cacheName, $results, 'cache-config-name'); * Cache::write($cacheName, $results, 'cache-config-name');
* return $results; * return $results;
* } * }
* ``` * ```
* *

View file

@ -107,10 +107,10 @@ class Permission extends AppModel {
return false; return false;
} }
$inherited = array();
$acoIDs = Hash::extract($acoPath, '{n}.' . $this->Aco->alias . '.id'); $acoIDs = Hash::extract($acoPath, '{n}.' . $this->Aco->alias . '.id');
$count = count($aroPath); $count = count($aroPath);
$inherited = array();
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$permAlias = $this->alias; $permAlias = $this->alias;
@ -129,19 +129,17 @@ class Permission extends AppModel {
$perms = Hash::extract($perms, '{n}.' . $this->alias); $perms = Hash::extract($perms, '{n}.' . $this->alias);
foreach ($perms as $perm) { foreach ($perms as $perm) {
if ($action === '*') { if ($action === '*') {
if (empty($perm)) {
foreach ($permKeys as $key) { continue;
if (!empty($perm)) {
if ($perm[$key] == -1) {
return false;
} elseif ($perm[$key] == 1) {
$inherited[$key] = 1;
}
}
} }
foreach ($permKeys as $key) {
if (count($inherited) === count($permKeys)) { if ($perm[$key] == -1 && !(isset($inherited[$key]) && $inherited[$key] == 1)) {
return true; // Deny, but only if a child node didnt't explicitly allow
return false;
} elseif ($perm[$key] == 1) {
// Allow & inherit from parent nodes
$inherited[$key] = $perm[$key];
}
} }
} else { } else {
switch ($perm['_' . $action]) { switch ($perm['_' . $action]) {
@ -154,6 +152,10 @@ class Permission extends AppModel {
} }
} }
} }
if ($action === '*' && count($inherited) === count($permKeys)) {
return true;
}
} }
return false; return false;
} }

View file

@ -165,7 +165,7 @@ class CakeRequest implements ArrayAccess {
if ($_POST) { if ($_POST) {
$this->data = $_POST; $this->data = $_POST;
} elseif (($this->is('put') || $this->is('delete')) && } elseif (($this->is('put') || $this->is('delete')) &&
strpos(env('CONTENT_TYPE'), 'application/x-www-form-urlencoded') === 0 strpos($this->contentType(), 'application/x-www-form-urlencoded') === 0
) { ) {
$data = $this->_readInput(); $data = $this->_readInput();
parse_str($data, $this->data); parse_str($data, $this->data);
@ -288,7 +288,6 @@ class CakeRequest implements ArrayAccess {
* the unnecessary part from $base to prevent issue #3318. * the unnecessary part from $base to prevent issue #3318.
* *
* @return string Base URL * @return string Base URL
* @link https://cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/3318
*/ */
protected function _base() { protected function _base() {
$dir = $webroot = null; $dir = $webroot = null;
@ -395,6 +394,19 @@ class CakeRequest implements ArrayAccess {
} }
} }
/**
* Get the content type used in this request.
*
* @return string
*/
public function contentType() {
$type = env('CONTENT_TYPE');
if ($type) {
return $type;
}
return env('HTTP_CONTENT_TYPE');
}
/** /**
* Get the IP the client is using, or says they are using. * Get the IP the client is using, or says they are using.
* *
@ -405,20 +417,10 @@ class CakeRequest implements ArrayAccess {
public function clientIp($safe = true) { public function clientIp($safe = true) {
if (!$safe && env('HTTP_X_FORWARDED_FOR')) { if (!$safe && env('HTTP_X_FORWARDED_FOR')) {
$ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR')); $ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
} elseif (!$safe && env('HTTP_CLIENT_IP')) {
$ipaddr = env('HTTP_CLIENT_IP');
} else { } else {
if (env('HTTP_CLIENT_IP')) { $ipaddr = env('REMOTE_ADDR');
$ipaddr = env('HTTP_CLIENT_IP');
} else {
$ipaddr = env('REMOTE_ADDR');
}
}
if (env('HTTP_CLIENTADDRESS')) {
$tmpipaddr = env('HTTP_CLIENTADDRESS');
if (!empty($tmpipaddr)) {
$ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
}
} }
return trim($ipaddr); return trim($ipaddr);
} }
@ -436,6 +438,9 @@ class CakeRequest implements ArrayAccess {
if (!empty($ref) && !empty($base)) { if (!empty($ref) && !empty($base)) {
if ($local && strpos($ref, $base) === 0) { if ($local && strpos($ref, $base) === 0) {
$ref = substr($ref, strlen($base)); $ref = substr($ref, strlen($base));
if (empty($ref)) {
$ref = '/';
}
if ($ref[0] !== '/') { if ($ref[0] !== '/') {
$ref = '/' . $ref; $ref = '/' . $ref;
} }

View file

@ -1184,7 +1184,7 @@ class CakeEmail {
} }
CakeLog::write( CakeLog::write(
$config['level'], $config['level'],
PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message'], PHP_EOL . $contents['headers'] . PHP_EOL . PHP_EOL . $contents['message'],
$config['scope'] $config['scope']
); );
} }

View file

@ -49,6 +49,9 @@ class MailTransport extends AbstractTransport {
$params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null; $params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null;
$this->_mail($to, $subject, $message, $headers, $params); $this->_mail($to, $subject, $message, $headers, $params);
$headers .= $eol . 'Subject: ' . $subject;
$headers .= $eol . 'To: ' . $to;
return array('headers' => $headers, 'message' => $message); return array('headers' => $headers, 'message' => $message);
} }

View file

@ -268,18 +268,28 @@ class HttpSocketResponse implements ArrayAccess {
return false; return false;
} }
preg_match_all("/(.+):(.+)(?:(?<![\t ])\r\n|\$)/Uis", $header, $matches, PREG_SET_ORDER); preg_match_all("/(.+):(.+)(?:\r\n|\$)/Uis", $header, $matches, PREG_SET_ORDER);
$lines = explode("\r\n", $header);
$header = array(); $header = array();
foreach ($matches as $match) { foreach ($lines as $line) {
list(, $field, $value) = $match; if (strlen($line) === 0) {
continue;
}
$continuation = false;
$first = substr($line, 0, 1);
// Multi-line header
if ($first === ' ' || $first === "\t") {
$value .= preg_replace("/\s+/", ' ', $line);
$continuation = true;
} elseif (strpos($line, ':') !== false) {
list($field, $value) = explode(':', $line, 2);
$field = $this->_unescapeToken($field);
}
$value = trim($value); $value = trim($value);
$value = preg_replace("/[\t ]\r\n/", "\r\n", $value); if (!isset($header[$field]) || $continuation) {
$field = $this->_unescapeToken($field);
if (!isset($header[$field])) {
$header[$field] = $value; $header[$field] = $value;
} else { } else {
$header[$field] = array_merge((array)$header[$field], (array)$value); $header[$field] = array_merge((array)$header[$field], (array)$value);

View file

@ -64,6 +64,12 @@ class MemcachedEngineTest extends CakeTestCase {
parent::setUp(); parent::setUp();
$this->skipIf(!class_exists('Memcached'), 'Memcached is not installed or configured properly.'); $this->skipIf(!class_exists('Memcached'), 'Memcached is not installed or configured properly.');
// @codingStandardsIgnoreStart
$socket = @fsockopen('127.0.0.1', 11211, $errno, $errstr, 1);
// @codingStandardsIgnoreEnd
$this->skipIf(!$socket, 'Memcached is not running.');
fclose($socket);
Cache::config('memcached', array( Cache::config('memcached', array(
'engine' => 'Memcached', 'engine' => 'Memcached',
'prefix' => 'cake_', 'prefix' => 'cake_',
@ -340,6 +346,7 @@ class MemcachedEngineTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testSaslAuthException() { public function testSaslAuthException() {
$this->skipIf(version_compare(PHP_VERSION, '7.0.0', '>='));
$Memcached = new TestMemcachedEngine(); $Memcached = new TestMemcachedEngine();
$settings = array( $settings = array(
'engine' => 'Memcached', 'engine' => 'Memcached',

View file

@ -37,6 +37,13 @@ class RedisEngineTest extends CakeTestCase {
$this->_cacheDisable = Configure::read('Cache.disable'); $this->_cacheDisable = Configure::read('Cache.disable');
Configure::write('Cache.disable', false); Configure::write('Cache.disable', false);
// @codingStandardsIgnoreStart
$socket = @fsockopen('127.0.0.1', 6379, $errno, $errstr, 1);
// @codingStandardsIgnoreEnd
$this->skipIf(!$socket, 'Redis is not running.');
fclose($socket);
Cache::config('redis', array( Cache::config('redis', array(
'engine' => 'Redis', 'engine' => 'Redis',
'prefix' => 'cake_', 'prefix' => 'cake_',
@ -137,6 +144,22 @@ class RedisEngineTest extends CakeTestCase {
Cache::drop('redisdb1'); Cache::drop('redisdb1');
} }
/**
* test write numbers method
*
* @return void
*/
public function testWriteNumbers() {
$result = Cache::write('test-counter', 1, 'redis');
$this->assertSame(1, Cache::read('test-counter', 'redis'));
$result = Cache::write('test-counter', 0, 'redis');
$this->assertSame(0, Cache::read('test-counter', 'redis'));
$result = Cache::write('test-counter', -1, 'redis');
$this->assertSame(-1, Cache::read('test-counter', 'redis'));
}
/** /**
* testReadAndWriteCache method * testReadAndWriteCache method
* *

View file

@ -253,7 +253,7 @@ class AclShellTest extends CakeTestCase {
$this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create'); $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create');
$this->Task->check(); $this->Task->check();
$this->Task->args = array('AuthUser.2', 'ROOT/Controller1', '*'); $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'delete');
$this->Task->check(); $this->Task->check();
} }

View file

@ -429,17 +429,60 @@ class DbAclTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testInherit() { public function testInherit() {
//parent doesn't have access inherit should still deny // parent doesn't have access inherit should still deny
$this->assertFalse($this->Acl->check('Milton', 'smash', 'delete')); $this->assertFalse($this->Acl->check('Milton', 'smash', 'delete'));
$this->Acl->inherit('Milton', 'smash', 'delete'); $this->Acl->inherit('Milton', 'smash', 'delete');
$this->assertFalse($this->Acl->check('Milton', 'smash', 'delete')); $this->assertFalse($this->Acl->check('Milton', 'smash', 'delete'));
//inherit parent // inherit parent
$this->assertFalse($this->Acl->check('Milton', 'smash', 'read')); $this->assertFalse($this->Acl->check('Milton', 'smash', 'read'));
$this->Acl->inherit('Milton', 'smash', 'read'); $this->Acl->inherit('Milton', 'smash', 'read');
$this->assertTrue($this->Acl->check('Milton', 'smash', 'read')); $this->assertTrue($this->Acl->check('Milton', 'smash', 'read'));
} }
/**
* test inherit from deny method
*
* @return void
*/
public function testInheritParentDeny() {
$this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'world'));
$this->Acl->Aco->save();
$this->Acl->Aco->create(array('parent_id' => $this->Acl->Aco->id, 'alias' => 'town'));
$this->Acl->Aco->save();
$this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'bizzaro_world'));
$this->Acl->Aco->save();
$this->Acl->Aco->create(array('parent_id' => $this->Acl->Aco->id, 'alias' => 'bizzaro_town'));
$this->Acl->Aco->save();
$this->Acl->Aro->create(array('parent_id' => null, 'alias' => 'Jane'));
$this->Acl->Aro->save();
// Setup deny on create for parent
$this->Acl->allow('Jane', 'world', '*');
$this->Acl->deny('Jane', 'world', 'create');
// Setup inherit and specify allow for create on child.
$this->Acl->inherit('Jane', 'town', '*');
$this->Acl->allow('Jane', 'town', 'create');
// Setup deny on create for parent
$this->Acl->deny('Jane', 'bizzaro_world', '*');
$this->Acl->allow('Jane', 'bizzaro_world', 'create');
// Setup inherit.
$this->Acl->inherit('Jane', 'bizzaro_town', '*');
$this->assertTrue($this->Acl->check('Jane', 'town', 'create'), 'Should have access due to override');
$this->assertTrue($this->Acl->check('Jane', 'town', '*'), 'Should have access due to inherit');
$this->assertTrue($this->Acl->check('Jane', 'bizzaro_town', 'create'), 'Should have access due explicit allow');
$this->assertFalse($this->Acl->check('Jane', 'bizzaro_town', '*'), 'Should not have access due to inherit');
}
/** /**
* testDbGrant method * testDbGrant method
* *

View file

@ -1621,8 +1621,6 @@ class AuthComponentTest extends CakeTestCase {
/** /**
* test that the returned URL doesn't contain the base URL. * test that the returned URL doesn't contain the base URL.
* *
* @see https://cakephp.lighthouseapp.com/projects/42648/tickets/3922-authcomponentredirecturl-prepends-appbaseurl
*
* @return void This test method doesn't return anything. * @return void This test method doesn't return anything.
*/ */
public function testRedirectUrlWithBaseSet() { public function testRedirectUrlWithBaseSet() {

View file

@ -870,7 +870,6 @@ class RequestHandlerComponentTest extends CakeTestCase {
* array URLs into their correct string ones, and adds base => false so * array URLs into their correct string ones, and adds base => false so
* the correct URLs are generated. * the correct URLs are generated.
* *
* @link https://cakephp.lighthouseapp.com/projects/42648-cakephp-1x/tickets/276
* @return void * @return void
*/ */
public function testBeforeRedirectCallbackWithArrayUrl() { public function testBeforeRedirectCallbackWithArrayUrl() {

View file

@ -1164,7 +1164,6 @@ class SecurityComponentTest extends CakeTestCase {
* the params. * the params.
* *
* @return void * @return void
* @see https://cakephp.lighthouseapp.com/projects/42648/tickets/68
*/ */
public function testSettingTokenForRequestAction() { public function testSettingTokenForRequestAction() {
$this->Controller->Security->startup($this->Controller); $this->Controller->Security->startup($this->Controller);
@ -1181,7 +1180,6 @@ class SecurityComponentTest extends CakeTestCase {
* test that blackhole doesn't delete the _Token session key so repeat data submissions * test that blackhole doesn't delete the _Token session key so repeat data submissions
* stay blackholed. * stay blackholed.
* *
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/214
* @return void * @return void
*/ */
public function testBlackHoleNotDeletingSessionInformation() { public function testBlackHoleNotDeletingSessionInformation() {

View file

@ -576,7 +576,6 @@ class AppTest extends CakeTestCase {
* test that building helper paths actually works. * test that building helper paths actually works.
* *
* @return void * @return void
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/410
*/ */
public function testImportingHelpersFromAlternatePaths() { public function testImportingHelpersFromAlternatePaths() {
$this->assertFalse(class_exists('BananaHelper', false), 'BananaHelper exists, cannot test importing it.'); $this->assertFalse(class_exists('BananaHelper', false), 'BananaHelper exists, cannot test importing it.');

View file

@ -132,7 +132,8 @@ class PostgresTestModel extends Model {
'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''), 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
'last_login' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''), 'last_login' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''), 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null) 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null),
'some_uuid' => array('type' => 'uuid', 'null' => '1', 'default' => null),
); );
} }
@ -257,7 +258,8 @@ class PostgresTest extends CakeTestCase {
'"PostgresTestModel"."comments" AS "PostgresTestModel__comments"', '"PostgresTestModel"."comments" AS "PostgresTestModel__comments"',
'"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"', '"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"',
'"PostgresTestModel"."created" AS "PostgresTestModel__created"', '"PostgresTestModel"."created" AS "PostgresTestModel__created"',
'"PostgresTestModel"."updated" AS "PostgresTestModel__updated"' '"PostgresTestModel"."updated" AS "PostgresTestModel__updated"',
'"PostgresTestModel"."some_uuid" AS "PostgresTestModel__some_uuid"'
); );
$result = $this->Dbo->fields($this->model); $result = $this->Dbo->fields($this->model);
@ -300,6 +302,7 @@ class PostgresTest extends CakeTestCase {
$this->assertEquals('decimal', $this->Dbo2->column('numeric')); $this->assertEquals('decimal', $this->Dbo2->column('numeric'));
$this->assertEquals('float', $this->Dbo2->column('float')); $this->assertEquals('float', $this->Dbo2->column('float'));
$this->assertEquals('float', $this->Dbo2->column('double precision')); $this->assertEquals('float', $this->Dbo2->column('double precision'));
$this->assertEquals('uuid', $this->Dbo2->column('uuid'));
$result = $this->Dbo2->column('bigint'); $result = $this->Dbo2->column('bigint');
$expected = 'biginteger'; $expected = 'biginteger';
@ -336,6 +339,8 @@ class PostgresTest extends CakeTestCase {
$this->assertEquals("'TRUE'", $this->Dbo->value('1', 'boolean')); $this->assertEquals("'TRUE'", $this->Dbo->value('1', 'boolean'));
$this->assertEquals("NULL", $this->Dbo->value(null, 'boolean')); $this->assertEquals("NULL", $this->Dbo->value(null, 'boolean'));
$this->assertEquals("NULL", $this->Dbo->value(array())); $this->assertEquals("NULL", $this->Dbo->value(array()));
$this->assertEquals("'550e8400-e29b-41d4-a716-446655440000'", $this->Dbo->value('550e8400-e29b-41d4-a716-446655440000', 'uuid'));
$this->assertEquals("NULL", $this->Dbo->value(null, 'uuid'));
} }
/** /**
@ -1150,7 +1155,7 @@ class PostgresTest extends CakeTestCase {
$data = $db->describe('test_uuid_describe'); $data = $db->describe('test_uuid_describe');
$expected = array( $expected = array(
'type' => 'string', 'type' => 'uuid',
'null' => false, 'null' => false,
'default' => null, 'default' => null,
'length' => 36, 'length' => 36,
@ -1204,4 +1209,13 @@ class PostgresTest extends CakeTestCase {
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
/**
* Test build column working for new uuid types
*/
public function testBuildColumnUuid() {
$column = array('name' => 'col1', 'type' => 'uuid');
$result = $this->Dbo2->buildColumn($column);
$this->assertEquals('"col1" uuid', $result);
}
} }

View file

@ -59,7 +59,7 @@ abstract class BaseModelTest extends CakeTestCase {
'core.feature_set', 'core.exterior_type_category', 'core.document', 'core.device', 'core.feature_set', 'core.exterior_type_category', 'core.document', 'core.device',
'core.document_directory', 'core.primary_model', 'core.secondary_model', 'core.something', 'core.document_directory', 'core.primary_model', 'core.secondary_model', 'core.something',
'core.something_else', 'core.join_thing', 'core.join_a', 'core.join_b', 'core.join_c', 'core.something_else', 'core.join_thing', 'core.join_a', 'core.join_b', 'core.join_c',
'core.join_a_b', 'core.join_a_c', 'core.uuid', 'core.data_test', 'core.posts_tag', 'core.join_a_b', 'core.join_a_c', 'core.uuid', 'core.uuid_native', 'core.data_test', 'core.posts_tag',
'core.the_paper_monkies', 'core.person', 'core.underscore_field', 'core.node', 'core.the_paper_monkies', 'core.person', 'core.underscore_field', 'core.node',
'core.dependency', 'core.story', 'core.stories_tag', 'core.cd', 'core.book', 'core.basket', 'core.dependency', 'core.story', 'core.stories_tag', 'core.cd', 'core.book', 'core.basket',
'core.overall_favorite', 'core.account', 'core.content', 'core.content_account', 'core.overall_favorite', 'core.account', 'core.content', 'core.content_account',
@ -71,6 +71,8 @@ abstract class BaseModelTest extends CakeTestCase {
'core.fruits_uuid_tag', 'core.uuid_tag', 'core.product_update_all', 'core.group_update_all', 'core.fruits_uuid_tag', 'core.uuid_tag', 'core.product_update_all', 'core.group_update_all',
'core.player', 'core.guild', 'core.guilds_player', 'core.armor', 'core.armors_player', 'core.player', 'core.guild', 'core.guilds_player', 'core.armor', 'core.armors_player',
'core.bidding', 'core.bidding_message', 'core.site', 'core.domain', 'core.domains_site', 'core.bidding', 'core.bidding_message', 'core.site', 'core.domain', 'core.domains_site',
'core.uuidnativeitem', 'core.uuidnativeportfolio', 'core.uuidnativeitems_uuidnativeportfolio',
'core.uuidnativeitems_uuidnativeportfolio_numericid',
); );
/** /**

View file

@ -270,6 +270,26 @@ class ModelWriteTest extends BaseModelTest {
$this->assertEquals(36, strlen($result['Uuid']['id'])); $this->assertEquals(36, strlen($result['Uuid']['id']));
} }
/**
* testAutoSaveUuidNative method
*
* @return void
*/
public function testAutoSaveUuidNative() {
$this->skipIf(!($this->db instanceof Postgres), 'This test is compatible with Postgres only.');
$this->loadFixtures('UuidNative');
$TestModel = new UuidNative();
$TestModel->save(array('title' => 'Test record'));
$result = $TestModel->findByTitle('Test record');
$this->assertEquals(
array('id', 'title', 'count', 'created', 'updated'),
array_keys($result['UuidNative'])
);
$this->assertEquals(36, strlen($result['UuidNative']['id']));
}
/** /**
* Ensure that if the id key is null but present the save doesn't fail (with an * Ensure that if the id key is null but present the save doesn't fail (with an
* x sql error: "Column id specified twice") * x sql error: "Column id specified twice")
@ -292,6 +312,27 @@ class ModelWriteTest extends BaseModelTest {
$this->assertEquals(36, strlen($result['Uuid']['id'])); $this->assertEquals(36, strlen($result['Uuid']['id']));
} }
/**
* Ensure that if the id key is null but present the save doesn't fail (with an
* x sql error: "Column id specified twice")
*
* @return void
*/
public function testSaveUuidNullNative() {
$this->skipIf(!($this->db instanceof Postgres), 'This test is compatible with Postgres only.');
$this->loadFixtures('UuidNative');
$TestModel = new UuidNative();
$TestModel->save(array('title' => 'Test record', 'id' => null));
$result = $TestModel->findByTitle('Test record');
$this->assertEquals(
array('id', 'title', 'count', 'created', 'updated'),
array_keys($result['UuidNative'])
);
$this->assertEquals(36, strlen($result['UuidNative']['id']));
}
/** /**
* testZeroDefaultFieldValue method * testZeroDefaultFieldValue method
* *
@ -2938,6 +2979,26 @@ class ModelWriteTest extends BaseModelTest {
$this->assertEquals(36, strlen($result['Uuiditem'][0]['UuiditemsUuidportfolio']['id'])); $this->assertEquals(36, strlen($result['Uuiditem'][0]['UuiditemsUuidportfolio']['id']));
} }
/**
* testHabtmUuidWithUuidId method
*
* @return void
*/
public function testHabtmUuidWithUuidIdNative() {
$this->skipIf(!($this->db instanceof Postgres), 'This test is compatible with Postgres only.');
$this->loadFixtures('Uuidnativeportfolio', 'Uuidnativeitem', 'UuidnativeitemsUuidnativeportfolio', 'UuidnativeitemsUuidnativeportfolioNumericid');
$TestModel = new Uuidnativeportfolio();
$data = array('Uuidnativeportfolio' => array('name' => 'Portfolio 3'));
$data['Uuidnativeitem']['Uuidnativeitem'] = array('483798c8-c7cc-430e-8cf9-4fcc40cf8569');
$TestModel->create($data);
$TestModel->save();
$id = $TestModel->id;
$result = $TestModel->read(null, $id);
$this->assertEquals(1, count($result['Uuidnativeitem']));
$this->assertEquals(36, strlen($result['Uuidnativeitem'][0]['UuidnativeitemsUuidnativeportfolio']['id']));
}
/** /**
* test HABTM saving when join table has no primary key and only 2 columns. * test HABTM saving when join table has no primary key and only 2 columns.
* *
@ -3007,6 +3068,25 @@ class ModelWriteTest extends BaseModelTest {
$this->assertEquals(1, count($result['Uuidportfolio'])); $this->assertEquals(1, count($result['Uuidportfolio']));
} }
/**
* testHabtmUuidWithNumericId method
*
* @return void
*/
public function testHabtmUuidWithNumericIdNative() {
$this->skipIf(!($this->db instanceof Postgres), 'This test is compatible with Postgres only.');
$this->loadFixtures('Uuidnativeportfolio', 'Uuidnativeitem', 'UuidnativeitemsUuidnativeportfolioNumericid');
$TestModel = new Uuidnativeitem();
$data = array('Uuidnativeitem' => array('name' => 'Item 7', 'published' => 0));
$data['Uuidnativeportfolio']['Uuidnativeportfolio'] = array('480af662-eb8c-47d3-886b-230540cf8569');
$TestModel->create($data);
$TestModel->save();
$id = $TestModel->id;
$result = $TestModel->read(null, $id);
$this->assertEquals(1, count($result['Uuidnativeportfolio']));
}
/** /**
* testSaveMultipleHabtm method * testSaveMultipleHabtm method
* *
@ -5313,7 +5393,6 @@ class ModelWriteTest extends BaseModelTest {
/** /**
* test that saveAll behaves like plain save() when supplied empty data * test that saveAll behaves like plain save() when supplied empty data
* *
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
* @return void * @return void
*/ */
public function testSaveAllEmptyData() { public function testSaveAllEmptyData() {
@ -6781,7 +6860,6 @@ class ModelWriteTest extends BaseModelTest {
/** /**
* test that saveMany behaves like plain save() when suplied empty data * test that saveMany behaves like plain save() when suplied empty data
* *
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
* @return void * @return void
*/ */
public function testSaveManyEmptyData() { public function testSaveManyEmptyData() {
@ -6800,7 +6878,6 @@ class ModelWriteTest extends BaseModelTest {
/** /**
* test that saveAssociated behaves like plain save() when supplied empty data * test that saveAssociated behaves like plain save() when supplied empty data
* *
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
* @return void * @return void
*/ */
public function testSaveAssociatedEmptyData() { public function testSaveAssociatedEmptyData() {

View file

@ -2120,6 +2120,21 @@ class Uuid extends CakeTestModel {
public $name = 'Uuid'; public $name = 'Uuid';
} }
/**
* UuidNative class
*
* @package Cake.Test.Case.Model
*/
class UuidNative extends CakeTestModel {
/**
* name property
*
* @var string
*/
public $name = 'UuidNative';
}
/** /**
* DataTest class * DataTest class
* *
@ -3055,6 +3070,84 @@ class UuiditemsUuidportfolioNumericid extends CakeTestModel {
public $name = 'UuiditemsUuidportfolioNumericid'; public $name = 'UuiditemsUuidportfolioNumericid';
} }
/**
* Uuidnativeportfolio class
*
* @package Cake.Test.Case.Model
*/
class Uuidnativeportfolio extends CakeTestModel {
/**
* name property
*
* @var string
*/
public $name = 'Uuidnativeportfolio';
/**
* hasAndBelongsToMany property
*
* @var array
*/
public $hasAndBelongsToMany = array('Uuidnativeitem');
}
/**
* Uuidnativeitem class
*
* @package Cake.Test.Case.Model
*/
class Uuidnativeitem extends CakeTestModel {
/**
* name property
*
* @var string
*/
public $name = 'Uuidnativeitem';
/**
* hasAndBelongsToMany property
*
* @var array
*/
public $hasAndBelongsToMany = array(
'Uuidnativeportfolio' => array(
'with' => 'UuidnativeitemsUuidnativeportfolioNumericid'
));
}
/**
* UuidnativeitemsUuidnativeportfolio class
*
* @package Cake.Test.Case.Model
*/
class UuidnativeitemsUuidnativeportfolio extends CakeTestModel {
/**
* name property
*
* @var string
*/
public $name = 'UuidnativeitemsUuidnativeportfolio';
}
/**
* UuidnativeitemsPortfolioNumericid class
*
* @package Cake.Test.Case.Model
*/
class UuidnativeitemsUuidnativeportfolioNumericid extends CakeTestModel {
/**
* name property
*
* @var string
*/
public $name = 'UuidnativeitemsUuidnativeportfolioNumericid';
}
/** /**
* TranslateTestModel class. * TranslateTestModel class.
* *

View file

@ -146,6 +146,21 @@ class CakeRequestTest extends CakeTestCase {
$this->assertFalse(isset($request->query['one'])); $this->assertFalse(isset($request->query['one']));
} }
/**
* Test the content type method.
*
* @return void
*/
public function testContentType() {
$_SERVER['HTTP_CONTENT_TYPE'] = 'application/json';
$request = new CakeRequest('/', false);
$this->assertEquals('application/json', $request->contentType());
$_SERVER['CONTENT_TYPE'] = 'application/xml';
$request = new CakeRequest('/', false);
$this->assertEquals('application/xml', $request->contentType(), 'prefer non http header.');
}
/** /**
* Test construction * Test construction
* *
@ -696,18 +711,18 @@ class CakeRequestTest extends CakeTestCase {
$_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.1.5, 10.0.1.1, proxy.com'; $_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.1.5, 10.0.1.1, proxy.com';
$_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2'; $_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2';
$_SERVER['REMOTE_ADDR'] = '192.168.1.3'; $_SERVER['REMOTE_ADDR'] = '192.168.1.3';
$request = new CakeRequest('some/path'); $request = new CakeRequest('some/path');
$this->assertEquals('192.168.1.5', $request->clientIp(false)); $this->assertEquals('192.168.1.3', $request->clientIp(), 'Use remote_addr in safe mode');
$this->assertEquals('192.168.1.2', $request->clientIp()); $this->assertEquals('192.168.1.5', $request->clientIp(false), 'Use x-forwarded');
unset($_SERVER['HTTP_X_FORWARDED_FOR']); unset($_SERVER['HTTP_X_FORWARDED_FOR']);
$this->assertEquals('192.168.1.2', $request->clientIp()); $this->assertEquals('192.168.1.3', $request->clientIp(), 'safe uses remote_addr');
$this->assertEquals('192.168.1.2', $request->clientIp(false), 'unsafe reads from client_ip');
unset($_SERVER['HTTP_CLIENT_IP']); unset($_SERVER['HTTP_CLIENT_IP']);
$this->assertEquals('192.168.1.3', $request->clientIp()); $this->assertEquals('192.168.1.3', $request->clientIp(), 'use remote_addr');
$this->assertEquals('192.168.1.3', $request->clientIp(false), 'use remote_addr');
$_SERVER['HTTP_CLIENTADDRESS'] = '10.0.1.2, 10.0.1.1';
$this->assertEquals('10.0.1.2', $request->clientIp());
} }
/** /**
@ -727,6 +742,10 @@ class CakeRequestTest extends CakeTestCase {
$result = $request->referer(); $result = $request->referer();
$this->assertSame($result, '/'); $this->assertSame($result, '/');
$_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseUrl') . '/';
$result = $request->referer(true);
$this->assertSame($result, '/');
$_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseUrl') . '/some/path'; $_SERVER['HTTP_REFERER'] = Configure::read('App.fullBaseUrl') . '/some/path';
$result = $request->referer(true); $result = $request->referer(true);
$this->assertSame($result, '/some/path'); $this->assertSame($result, '/some/path');
@ -1362,7 +1381,6 @@ class CakeRequestTest extends CakeTestCase {
* - index.php/apples/ * - index.php/apples/
* - index.php/bananas/eat/tasty_banana * - index.php/bananas/eat/tasty_banana
* *
* @link https://cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/3318
* @return void * @return void
*/ */
public function testBaseUrlWithModRewriteAndIndexPhp() { public function testBaseUrlWithModRewriteAndIndexPhp() {

View file

@ -84,7 +84,10 @@ class MailTransportTest extends CakeTestCase {
'-f' '-f'
); );
$this->MailTransport->send($email); $result = $this->MailTransport->send($email);
$this->assertContains('Subject: ', $result['headers']);
$this->assertContains('To: ', $result['headers']);
} }
} }

View file

@ -267,10 +267,19 @@ class HttpResponseTest extends CakeTestCase {
); );
$this->assertEquals($expected, $r); $this->assertEquals($expected, $r);
$header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n"; $header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nLink: \r\nX-Total-Count: 19\r\n";
$r = $this->HttpResponse->parseHeader($header); $r = $this->HttpResponse->parseHeader($header);
$expected = array( $expected = array(
'Multi-Line' => "I am a\r\nmulti line\r\nfield value.", 'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT',
'Link' => '',
'X-Total-Count' => '19',
);
$this->assertEquals($expected, $r);
$header = "Multi-Line: I am a\r\n multi line \r\n\tfield value.\r\nSingle-Line: I am not\r\n";
$r = $this->HttpResponse->parseHeader($header);
$expected = array(
'Multi-Line' => "I am a multi line field value.",
'Single-Line' => 'I am not' 'Single-Line' => 'I am not'
); );
$this->assertEquals($expected, $r); $this->assertEquals($expected, $r);

View file

@ -596,7 +596,6 @@ class ControllerTestCaseTest extends CakeTestCase {
* will always have a fresh reference to those object available * will always have a fresh reference to those object available
* *
* @return void * @return void
* @see https://cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/2705-requesthandler-weird-behavior
*/ */
public function testComponentsSameRequestAndResponse() { public function testComponentsSameRequestAndResponse() {
$this->Case->generate('TestsApps'); $this->Case->generate('TestsApps');

View file

@ -424,4 +424,16 @@ class SecurityTest extends CakeTestCase {
Security::decrypt($txt, $key); Security::decrypt($txt, $key);
} }
/**
* Test the random method.
*
* @return void
*/
public function testRandomBytes() {
$value = Security::randomBytes(16);
$this->assertSame(16, strlen($value));
$value = Security::randomBytes(64);
$this->assertSame(64, strlen($value));
}
} }

View file

@ -2505,4 +2505,20 @@ class ValidationTest extends CakeTestCase {
); );
$this->assertFalse(Validation::uploadedFile($file, $options), 'File is required.'); $this->assertFalse(Validation::uploadedFile($file, $options), 'File is required.');
} }
/**
* Test uploaded file validation.
*
* @return void
*/
public function testUploadedFileWithDifferentFileParametersOrder() {
$file = array(
'name' => 'cake.power.gif',
'error' => UPLOAD_ERR_OK,
'tmp_name' => CORE_PATH . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'webroot/img/cake.power.gif',
'type' => 'text/plain',
'size' => 201
);
$options = array();
$this->assertTrue(Validation::uploadedFile($file, $options), 'Wrong order');
}
} }

View file

@ -1460,7 +1460,6 @@ class ViewTest extends CakeTestCase {
* Test setting a block's content to null * Test setting a block's content to null
* *
* @return void * @return void
* @link https://cakephp.lighthouseapp.com/projects/42648/tickets/3938-this-redirectthis-auth-redirecturl-broken
*/ */
public function testBlockSetNull() { public function testBlockSetNull() {
$this->View->assign('testWithNull', null); $this->View->assign('testWithNull', null);

View file

@ -0,0 +1,50 @@
<?php
/**
* Short description for file.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.6700
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Class UuidNativeFixture.
*
* @package Cake.Test.Fixture
*/
class UuidNativeFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'uuid', 'key' => 'primary'),
'title' => 'string',
'count' => array('type' => 'integer', 'default' => 0),
'created' => 'datetime',
'updated' => 'datetime'
);
/**
* records property
*
* @var array
*/
public $records = array(
array('id' => '47c36f9c-bc00-4d17-9626-4e183ca6822b', 'title' => 'Unique record 1', 'count' => 2, 'created' => '2008-03-13 01:16:23', 'updated' => '2008-03-13 01:18:31'),
array('id' => '47c36f9c-f2b0-43f5-b3f7-4e183ca6822b', 'title' => 'Unique record 2', 'count' => 4, 'created' => '2008-03-13 01:18:24', 'updated' => '2008-03-13 01:20:32'),
array('id' => '47c36f9c-0ffc-4084-9b03-4e183ca6822b', 'title' => 'Unique record 3', 'count' => 5, 'created' => '2008-03-13 01:20:25', 'updated' => '2008-03-13 01:22:33'),
array('id' => '47c36f9c-2578-4c2e-aeab-4e183ca6822b', 'title' => 'Unique record 4', 'count' => 3, 'created' => '2008-03-13 01:22:26', 'updated' => '2008-03-13 01:24:34'),
);
}

View file

@ -0,0 +1,45 @@
<?php
/**
* Short description for file.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.7953
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Class UuidNativeTagFixture
*
* @package Cake.Test.Fixture
*/
class UuidNativeTagFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'uuid', 'key' => 'primary'),
'name' => array('type' => 'string', 'length' => 255),
'created' => array('type' => 'datetime')
);
/**
* records property
*
* @var array
*/
public $records = array(
array('id' => '481fc6d0-b920-43e0-e50f-6d1740cf8569', 'name' => 'MyTag', 'created' => '2009-12-09 12:30:00')
);
}

View file

@ -0,0 +1,39 @@
<?php
/**
* UUID Tree behavior fixture.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.7984
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* UuidNativeTreeFixture class
*
* @uses CakeTestFixture
* @package Cake.Test.Fixture
*/
class UuidNativeTreeFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'uuid', 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => false),
'parent_id' => array('type' => 'string', 'length' => 36, 'null' => true),
'lft' => array('type' => 'integer', 'null' => false),
'rght' => array('type' => 'integer', 'null' => false)
);
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Short description for file.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.4667
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Class UuidnativeitemFixture
*
* @package Cake.Test.Fixture
*/
class UuidnativeitemFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'uuid', 'key' => 'primary'),
'published' => array('type' => 'boolean', 'null' => false),
'name' => array('type' => 'string', 'null' => false)
);
/**
* records property
*
* @var array
*/
public $records = array(
array('id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'published' => 0, 'name' => 'Item 1'),
array('id' => '48298a29-81c0-4c26-a7fb-413140cf8569', 'published' => 0, 'name' => 'Item 2'),
array('id' => '482b7756-8da0-419a-b21f-27da40cf8569', 'published' => 0, 'name' => 'Item 3'),
array('id' => '482cfd4b-0e7c-4ea3-9582-4cec40cf8569', 'published' => 0, 'name' => 'Item 4'),
array('id' => '4831181b-4020-4983-a29b-131440cf8569', 'published' => 0, 'name' => 'Item 5'),
array('id' => '483798c8-c7cc-430e-8cf9-4fcc40cf8569', 'published' => 0, 'name' => 'Item 6')
);
}

View file

@ -0,0 +1,48 @@
<?php
/**
* Short description for file.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.4667
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Class UuiditemsUuidportfolioFixture
*
* @package Cake.Test.Fixture
*/
class UuidnativeitemsUuidnativeportfolioFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'uuid', 'key' => 'primary'),
'uuidnativeitem_id' => array('type' => 'uuid', 'null' => false),
'uuidnativeportfolio_id' => array('type' => 'uuid', 'null' => false)
);
/**
* records property
*
* @var array
*/
public $records = array(
array('id' => '4850fd8f-cc5c-449f-bf34-0c5240cf8569', 'uuidnativeitem_id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'uuidnativeportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
array('id' => '4850fee5-d24c-4ea0-9759-0c2e40cf8569', 'uuidnativeitem_id' => '48298a29-81c0-4c26-a7fb-413140cf8569', 'uuidnativeportfolio_id' => '480af662-eb8c-47d3-886b-230540cf8569'),
array('id' => '4851af6e-fa18-403d-b57e-437d40cf8569', 'uuidnativeitem_id' => '482b7756-8da0-419a-b21f-27da40cf8569', 'uuidnativeportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
array('id' => '4851b94c-9790-42dc-b760-4f9240cf8569', 'uuidnativeitem_id' => '482cfd4b-0e7c-4ea3-9582-4cec40cf8569', 'uuidnativeportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569')
);
}

View file

@ -0,0 +1,48 @@
<?php
/**
* Short description for file.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.4667
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Class UuidnativeitemsUuidnativeportfolioNumericidFixture
*
* @package Cake.Test.Fixture
*/
class UuidnativeitemsUuidnativeportfolioNumericidFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'length' => 10, 'key' => 'primary'),
'uuidnativeitem_id' => array('type' => 'uuid', 'null' => false),
'uuidnativeportfolio_id' => array('type' => 'uuid', 'null' => false)
);
/**
* records property
*
* @var array
*/
public $records = array(
array('uuidnativeitem_id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'uuidnativeportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
array('uuidnativeitem_id' => '48298a29-81c0-4c26-a7fb-413140cf8569', 'uuidnativeportfolio_id' => '480af662-eb8c-47d3-886b-230540cf8569'),
array('uuidnativeitem_id' => '482b7756-8da0-419a-b21f-27da40cf8569', 'uuidnativeportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
array('uuidnativeitem_id' => '482cfd4b-0e7c-4ea3-9582-4cec40cf8569', 'uuidnativeportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569')
);
}

View file

@ -0,0 +1,45 @@
<?php
/**
* Short description for file.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* 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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.Test.Fixture
* @since CakePHP(tm) v 1.2.0.4667
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Class UuidnativeportfolioFixture
*
* @package Cake.Test.Fixture
*/
class UuidnativeportfolioFixture extends CakeTestFixture {
/**
* fields property
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'uuid', 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => false)
);
/**
* records property
*
* @var array
*/
public $records = array(
array('id' => '4806e091-6940-4d2b-b227-303740cf8569', 'name' => 'Portfolio 1'),
array('id' => '480af662-eb8c-47d3-886b-230540cf8569', 'name' => 'Portfolio 2'),
);
}

View file

@ -824,7 +824,7 @@ class Hash {
} }
/** /**
* Sorts an array by any value, determined by a Set-compatible path * Sorts an array by any value, determined by a Hash-compatible path
* *
* ### Sort directions * ### Sort directions
* *
@ -849,7 +849,7 @@ class Hash {
* defaults to `false`. * defaults to `false`.
* *
* @param array $data An array of data to sort * @param array $data An array of data to sort
* @param string $path A Set-compatible path to the array value * @param string $path A Hash-compatible path to the array value
* @param string $dir See directions above. Defaults to 'asc'. * @param string $dir See directions above. Defaults to 'asc'.
* @param array|string $type See direction types above. Defaults to 'regular'. * @param array|string $type See direction types above. Defaults to 'regular'.
* @return array Sorted array of data * @return array Sorted array of data

View file

@ -61,6 +61,7 @@ class Security {
* Generate authorization hash. * Generate authorization hash.
* *
* @return string Hash * @return string Hash
* @deprecated 2.8.1 This method was removed in 3.0.0
*/ */
public static function generateAuthKey() { public static function generateAuthKey() {
return Security::hash(CakeText::uuid()); return Security::hash(CakeText::uuid());
@ -71,6 +72,7 @@ class Security {
* *
* @param string $authKey Authorization hash * @param string $authKey Authorization hash
* @return bool Success * @return bool Success
* @deprecated 2.8.1 This method was removed in 3.0.0
*/ */
public static function validateAuthKey($authKey) { public static function validateAuthKey($authKey) {
return true; return true;
@ -92,7 +94,7 @@ class Security {
* Creating a blowfish/bcrypt hash: * Creating a blowfish/bcrypt hash:
* *
* ``` * ```
* $hash = Security::hash($password, 'blowfish'); * $hash = Security::hash($password, 'blowfish');
* ``` * ```
* *
* @param string $string String to hash * @param string $string String to hash
@ -166,6 +168,35 @@ class Security {
static::$hashCost = $cost; static::$hashCost = $cost;
} }
/**
* Get random bytes from a secure source.
*
* This method will fall back to an insecure source an trigger a warning
* if it cannot find a secure source of random data.
*
* @param int $length The number of bytes you want.
* @return string Random bytes in binary.
*/
public static function randomBytes($length) {
if (function_exists('random_bytes')) {
return random_bytes($length);
}
if (function_exists('openssl_random_pseudo_bytes')) {
return openssl_random_pseudo_bytes($length);
}
trigger_error(
'You do not have a safe source of random data available. ' .
'Install either the openssl extension, or paragonie/random_compat. ' .
'Falling back to an insecure random source.',
E_USER_WARNING
);
$bytes = '';
while ($bytes < $length) {
$bytes .= static::hash(CakeText::uuid() . uniqid(mt_rand(), true), 'sha512', true);
}
return substr($bytes, 0, $length);
}
/** /**
* Runs $text through a XOR cipher. * Runs $text through a XOR cipher.
* *

View file

@ -1016,7 +1016,8 @@ class Validation {
if (!is_array($file)) { if (!is_array($file)) {
return false; return false;
} }
$keys = array('name', 'tmp_name', 'error', 'type', 'size'); $keys = array('error', 'name', 'size', 'tmp_name', 'type');
ksort($file);
if (array_keys($file) != $keys) { if (array_keys($file) != $keys) {
return false; return false;
} }