mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-18 18:46:17 +00:00
"References #4394, additional fixes to multi record forms.
Added additional test cases" git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6629 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
5d59938121
commit
d14b50fc92
4 changed files with 177 additions and 28 deletions
|
@ -519,6 +519,7 @@ class SecurityComponent extends Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ksort($check);
|
||||||
foreach ($check as $key => $value) {
|
foreach ($check as $key => $value) {
|
||||||
$merge = array();
|
$merge = array();
|
||||||
if ($key === '__Token') {
|
if ($key === '__Token') {
|
||||||
|
@ -545,7 +546,11 @@ class SecurityComponent extends Object {
|
||||||
|
|
||||||
if (is_numeric($k[0])) {
|
if (is_numeric($k[0])) {
|
||||||
for ($i = 0; $count > $i; $i++) {
|
for ($i = 0; $count > $i; $i++) {
|
||||||
$field[$newKey][$i] = array_merge($field[$newKey][$i], array_keys($values[$i]));
|
foreach ($values[$i] as $key2 => $value1) {
|
||||||
|
if ($value1 === '0') {
|
||||||
|
$field[$newKey][$i] = array_merge($field[$newKey][$i], array($key2));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$controller->data[$newKey] = Set::pushDiff($controller->data[$key], $controller->data[$newKey]);
|
$controller->data[$newKey] = Set::pushDiff($controller->data[$key], $controller->data[$newKey]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,47 +295,65 @@ class FormHelper extends AppHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Generates a field list
|
* Determine which fields of a form should be used for hash
|
||||||
*
|
*
|
||||||
* @param string $model Model name
|
* @param string $model Model name
|
||||||
* @param array $options Options
|
* @param mixed $options Options
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function __secure($model = null, $options = null) {
|
function __secure($model = null, $options = null) {
|
||||||
if (!$model) {
|
if (!$model) {
|
||||||
$model = $this->model();
|
$model = $this->model();
|
||||||
}
|
}
|
||||||
|
$view =& ClassRegistry::getObject('view');
|
||||||
|
$field = $view->field;
|
||||||
|
$fieldSuffix = $view->fieldSuffix;
|
||||||
|
|
||||||
if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
|
if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
|
||||||
if (!empty($this->params['_Token']['disabledFields'])) {
|
if (!empty($this->params['_Token']['disabledFields'])) {
|
||||||
foreach ($this->params['_Token']['disabledFields'] as $value) {
|
foreach ($this->params['_Token']['disabledFields'] as $value) {
|
||||||
$parts = preg_split('/\/|\./', $value);
|
$parts = preg_split('/\/|\./', $value);
|
||||||
if (count($parts) == 1) {
|
if (count($parts) == 1) {
|
||||||
if ($parts[0] === $this->field()) {
|
if ($parts[0] === $field || $parts[0] === $fieldSuffix) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} elseif (count($parts) == 2) {
|
} elseif (count($parts) == 2) {
|
||||||
if ($parts[0] === $this->model() && $parts[1] === $this->field()) {
|
if ($parts[0] === $model && ($parts[1] === $field || $parts[1] === $fieldSuffix)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_null($options)) {
|
|
||||||
$this->fields[$model][$this->field()] = $options;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$this->fields[$model][] = $this->field();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!is_null($options)) {
|
$this->__fields($model, $field, $fieldSuffix, $options);
|
||||||
$this->fields[$model][$this->field()] = $options;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
if ((isset($this->fields[$model]) && !in_array($this->field(), $this->fields[$model], true)) || !isset($this->fields[$model])) {
|
/**
|
||||||
$this->fields[$model][] = $this->field();
|
* Generates a field list used to secure forms
|
||||||
|
*
|
||||||
|
* @param string $model
|
||||||
|
* @param string $field
|
||||||
|
* @param string $fieldSuffix
|
||||||
|
* @param mixed $options
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function __fields($model, $field, $fieldSuffix, $options) {
|
||||||
|
if (!is_null($options)) {
|
||||||
|
if (is_numeric($field)) {
|
||||||
|
$this->fields[$model][$field][$fieldSuffix] = $options;
|
||||||
|
} else {
|
||||||
|
$this->fields[$model][$field] = $options;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ((isset($this->fields[$model]) && !in_array($field, $this->fields[$model], true)) || !isset($this->fields[$model])) {
|
||||||
|
if (is_numeric($field)) {
|
||||||
|
$this->fields[$model][$field][] = $fieldSuffix;
|
||||||
|
} else {
|
||||||
|
$this->fields[$model][] = $field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns true if there is an error for the given field, otherwise false
|
* Returns true if there is an error for the given field, otherwise false
|
||||||
|
|
|
@ -180,24 +180,27 @@ class SecurityComponentTest extends CakeTestCase {
|
||||||
$this->Controller->Security->startup($this->Controller);
|
$this->Controller->Security->startup($this->Controller);
|
||||||
$key = $this->Controller->params['_Token']['key'];
|
$key = $this->Controller->params['_Token']['key'];
|
||||||
|
|
||||||
$data['Model'][0]['username'] = '';
|
$data['Model'][0]['username'] = 'username';
|
||||||
$data['Model'][0]['password'] = '';
|
$data['Model'][0]['password'] = 'password';
|
||||||
$data['Model'][1]['username'] = '';
|
$data['Model'][1]['username'] = 'username';
|
||||||
$data['Model'][1]['password'] = '';
|
$data['Model'][1]['password'] = 'password';
|
||||||
$data['_Model'][0]['hidden'] = 'value';
|
$data['_Model'][0]['hidden'] = 'value';
|
||||||
$data['_Model'][1]['hidden'] = 'value';
|
$data['_Model'][1]['hidden'] = 'value';
|
||||||
|
$data['_Model'][0]['valid'] = '0';
|
||||||
|
$data['_Model'][1]['valid'] = '0';
|
||||||
$data['__Token']['key'] = $key;
|
$data['__Token']['key'] = $key;
|
||||||
|
|
||||||
$fields = array(
|
$fields = array(
|
||||||
'Model' => array(
|
'Model' => array(
|
||||||
0 => array('username', 'password', 'hidden'),
|
0 => array('username', 'password', 'valid'),
|
||||||
1 => array('username', 'password', 'hidden')),
|
1 => array('username', 'password', 'valid')),
|
||||||
'_Model' => array(
|
'_Model' => array(
|
||||||
0 => array('hidden' => 'value'),
|
0 => array('hidden' => 'value', 'valid' => '0'),
|
||||||
1 => array('hidden' => 'value')),
|
1 => array('hidden' => 'value', 'valid' => '0')),
|
||||||
'__Token' => array('key' => $key));
|
'__Token' => array('key' => $key));
|
||||||
|
|
||||||
$fields = $this->__sortFields($fields);
|
$fields = $this->__sortFields($fields);
|
||||||
|
|
||||||
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||||
$data['__Token']['fields'] = $fields;
|
$data['__Token']['fields'] = $fields;
|
||||||
|
|
||||||
|
@ -208,6 +211,9 @@ class SecurityComponentTest extends CakeTestCase {
|
||||||
unset($data['_Model']);
|
unset($data['_Model']);
|
||||||
$data['Model'][0]['hidden'] = 'value';
|
$data['Model'][0]['hidden'] = 'value';
|
||||||
$data['Model'][1]['hidden'] = 'value';
|
$data['Model'][1]['hidden'] = 'value';
|
||||||
|
$data['Model'][0]['valid'] = '0';
|
||||||
|
$data['Model'][1]['valid'] = '0';
|
||||||
|
|
||||||
$this->assertTrue($this->Controller->data == $data);
|
$this->assertTrue($this->Controller->data == $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,126 @@ class FormHelperTest extends CakeTestCase {
|
||||||
);
|
);
|
||||||
$this->Form->params['_Token']['key'] = $key;
|
$this->Form->params['_Token']['key'] = $key;
|
||||||
$result = $this->Form->secure($fields);
|
$result = $this->Form->secure($fields);
|
||||||
|
|
||||||
|
$fields = $this->__sortFields($fields);
|
||||||
|
$expected = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||||
|
$this->assertPattern('/'.$expected.'/', $result);
|
||||||
|
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFormSecurityMultipleFields() {
|
||||||
|
$key = 'testKey';
|
||||||
|
$fields = array(
|
||||||
|
'Model' => array(
|
||||||
|
0 => array('username', 'password', 'valid'),
|
||||||
|
1 => array('username', 'password', 'valid')),
|
||||||
|
'_Model' => array(
|
||||||
|
0 => array('hidden' => 'value', 'valid' => '0'),
|
||||||
|
1 => array('hidden' => 'value', 'valid' => '0')),
|
||||||
|
'__Token' => array('key' => $key));
|
||||||
|
$this->Form->params['_Token']['key'] = $key;
|
||||||
|
$result = $this->Form->secure($fields);
|
||||||
|
|
||||||
|
$fields = $this->__sortFields($fields);
|
||||||
|
$expected = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||||
|
$this->assertPattern('/'.$expected.'/', $result);
|
||||||
|
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFormSecurityMultipleInputFields() {
|
||||||
|
$key = 'testKey';
|
||||||
|
$this->Form->params['_Token']['key'] = $key;
|
||||||
|
$this->Form->create();
|
||||||
|
|
||||||
|
$this->Form->hidden('Addresses.0.id', array('value' => '123456'));
|
||||||
|
$this->Form->input('Addresses.0.title');
|
||||||
|
$this->Form->input('Addresses.0.first_name');
|
||||||
|
$this->Form->input('Addresses.0.last_name');
|
||||||
|
$this->Form->input('Addresses.0.address');
|
||||||
|
$this->Form->input('Addresses.0.city');
|
||||||
|
$this->Form->input('Addresses.0.phone');
|
||||||
|
$this->Form->hidden('Addresses.1.id', array('value' => '654321'));
|
||||||
|
$this->Form->input('Addresses.1.title');
|
||||||
|
$this->Form->input('Addresses.1.first_name');
|
||||||
|
$this->Form->input('Addresses.1.last_name');
|
||||||
|
$this->Form->input('Addresses.1.address');
|
||||||
|
$this->Form->input('Addresses.1.city');
|
||||||
|
$this->Form->input('Addresses.1.phone');
|
||||||
|
|
||||||
|
$fields = array(
|
||||||
|
'Addresses' => array(
|
||||||
|
0 => array('title', 'first_name', 'last_name', 'address', 'city', 'phone'),
|
||||||
|
1 => array('title', 'first_name', 'last_name', 'address', 'city', 'phone')),
|
||||||
|
'_Addresses' => array(
|
||||||
|
0 => array('id' => '123456'),
|
||||||
|
1 => array('id' => '654321')),
|
||||||
|
'__Token' => array('key' => $key));
|
||||||
|
|
||||||
|
$fields = $this->__sortFields($fields);
|
||||||
|
$result = $this->Form->secure($this->Form->fields);
|
||||||
|
$expected = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||||
|
$this->assertPattern('/'.$expected.'/', $result);
|
||||||
|
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFormSecurityMultipleInputDisabledFields() {
|
||||||
|
$key = 'testKey';
|
||||||
|
$this->Form->params['_Token']['key'] = $key;
|
||||||
|
$this->Form->params['_Token']['disabledFields'] = array('first_name', 'address');
|
||||||
|
$this->Form->create();
|
||||||
|
|
||||||
|
$this->Form->hidden('Addresses.0.id', array('value' => '123456'));
|
||||||
|
$this->Form->input('Addresses.0.title');
|
||||||
|
$this->Form->input('Addresses.0.first_name');
|
||||||
|
$this->Form->input('Addresses.0.last_name');
|
||||||
|
$this->Form->input('Addresses.0.address');
|
||||||
|
$this->Form->input('Addresses.0.city');
|
||||||
|
$this->Form->input('Addresses.0.phone');
|
||||||
|
$this->Form->hidden('Addresses.1.id', array('value' => '654321'));
|
||||||
|
$this->Form->input('Addresses.1.title');
|
||||||
|
$this->Form->input('Addresses.1.first_name');
|
||||||
|
$this->Form->input('Addresses.1.last_name');
|
||||||
|
$this->Form->input('Addresses.1.address');
|
||||||
|
$this->Form->input('Addresses.1.city');
|
||||||
|
$this->Form->input('Addresses.1.phone');
|
||||||
|
|
||||||
|
$fields = array(
|
||||||
|
'Addresses' => array(
|
||||||
|
0 => array('title', 'last_name', 'city', 'phone'),
|
||||||
|
1 => array('title', 'last_name', 'city', 'phone')),
|
||||||
|
'_Addresses' => array(
|
||||||
|
0 => array('id' => '123456'),
|
||||||
|
1 => array('id' => '654321')),
|
||||||
|
'__Token' => array('key' => $key));
|
||||||
|
|
||||||
|
$fields = $this->__sortFields($fields);
|
||||||
|
$result = $this->Form->secure($this->Form->fields);
|
||||||
|
$expected = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||||
|
$this->assertPattern('/'.$expected.'/', $result);
|
||||||
|
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFormSecurityInputDisabledFields() {
|
||||||
|
$key = 'testKey';
|
||||||
|
$this->Form->params['_Token']['key'] = $key;
|
||||||
|
$this->Form->params['_Token']['disabledFields'] = array('first_name', 'address');
|
||||||
|
$this->Form->create();
|
||||||
|
|
||||||
|
$this->Form->hidden('Addresses.id', array('value' => '123456'));
|
||||||
|
$this->Form->input('Addresses.title');
|
||||||
|
$this->Form->input('Addresses.first_name');
|
||||||
|
$this->Form->input('Addresses.last_name');
|
||||||
|
$this->Form->input('Addresses.address');
|
||||||
|
$this->Form->input('Addresses.city');
|
||||||
|
$this->Form->input('Addresses.phone');
|
||||||
|
|
||||||
|
$fields = array(
|
||||||
|
'Addresses' => array('title', 'last_name', 'city', 'phone'),
|
||||||
|
'_Addresses' => array('id' => '123456'),
|
||||||
|
'__Token' => array('key' => $key));
|
||||||
|
|
||||||
|
$fields = $this->__sortFields($fields);
|
||||||
|
$result = $this->Form->secure($this->Form->fields);
|
||||||
$expected = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
$expected = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
|
||||||
$this->assertPattern('/'.$expected.'/', $result);
|
$this->assertPattern('/'.$expected.'/', $result);
|
||||||
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);
|
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);
|
||||||
|
@ -707,15 +827,15 @@ class FormHelperTest extends CakeTestCase {
|
||||||
$this->assertPattern('/id="ModelField1"/', $result);
|
$this->assertPattern('/id="ModelField1"/', $result);
|
||||||
$this->assertPattern('/id="ModelField0".*checked="checked"/', $result);
|
$this->assertPattern('/id="ModelField0".*checked="checked"/', $result);
|
||||||
$this->assertPattern('/(<input[^<>]+name="data\[Model\]\[field\]"[^<>]+>.+){2}/', $result);
|
$this->assertPattern('/(<input[^<>]+name="data\[Model\]\[field\]"[^<>]+>.+){2}/', $result);
|
||||||
|
|
||||||
$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => null));
|
$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => null));
|
||||||
$this->assertPattern('/id="ModelField1"/', $result);
|
$this->assertPattern('/id="ModelField1"/', $result);
|
||||||
$this->assertPattern('/id="ModelField0"\svalue="0"\s(?!checked="checked")/', $result);
|
$this->assertPattern('/id="ModelField0"\svalue="0"\s(?!checked="checked")/', $result);
|
||||||
|
|
||||||
$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'));
|
$result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'));
|
||||||
$this->assertPattern('/id="ModelField1"/', $result);
|
$this->assertPattern('/id="ModelField1"/', $result);
|
||||||
$this->assertPattern('/id="ModelField0"\svalue="0"\s(?!checked="checked")/', $result);
|
$this->assertPattern('/id="ModelField0"\svalue="0"\s(?!checked="checked")/', $result);
|
||||||
|
|
||||||
$result = $this->Form->input('Newsletter.subscribe', array('legend' => 'Legend title', 'type' => 'radio', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
|
$result = $this->Form->input('Newsletter.subscribe', array('legend' => 'Legend title', 'type' => 'radio', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
|
||||||
$expected = '<div class="input"><fieldset><legend>Legend title</legend><input type="hidden" name="data[Newsletter][subscribe]" value="" id="NewsletterSubscribe_" /><input type="radio" name="data[Newsletter][subscribe]" id="NewsletterSubscribe0" value="0" /><label for="NewsletterSubscribe0">Unsubscribe</label><input type="radio" name="data[Newsletter][subscribe]" id="NewsletterSubscribe1" value="1" /><label for="NewsletterSubscribe1">Subscribe</label></fieldset></div>';
|
$expected = '<div class="input"><fieldset><legend>Legend title</legend><input type="hidden" name="data[Newsletter][subscribe]" value="" id="NewsletterSubscribe_" /><input type="radio" name="data[Newsletter][subscribe]" id="NewsletterSubscribe0" value="0" /><label for="NewsletterSubscribe0">Unsubscribe</label><input type="radio" name="data[Newsletter][subscribe]" id="NewsletterSubscribe1" value="1" /><label for="NewsletterSubscribe1">Subscribe</label></fieldset></div>';
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
Loading…
Add table
Reference in a new issue