"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:
phpnut 2008-04-03 06:48:56 +00:00
parent 5d59938121
commit d14b50fc92
4 changed files with 177 additions and 28 deletions

View file

@ -519,6 +519,7 @@ class SecurityComponent extends Object {
}
}
}
ksort($check);
foreach ($check as $key => $value) {
$merge = array();
if ($key === '__Token') {
@ -545,7 +546,11 @@ class SecurityComponent extends Object {
if (is_numeric($k[0])) {
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]);
}

View file

@ -295,47 +295,65 @@ class FormHelper extends AppHelper {
return null;
}
/**
* Generates a field list
* Determine which fields of a form should be used for hash
*
* @param string $model Model name
* @param array $options Options
* @param mixed $options Options
* @access private
*/
function __secure($model = null, $options = null) {
if (!$model) {
$model = $this->model();
}
$view =& ClassRegistry::getObject('view');
$field = $view->field;
$fieldSuffix = $view->fieldSuffix;
if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
if (!empty($this->params['_Token']['disabledFields'])) {
foreach ($this->params['_Token']['disabledFields'] as $value) {
$parts = preg_split('/\/|\./', $value);
if (count($parts) == 1) {
if ($parts[0] === $this->field()) {
if ($parts[0] === $field || $parts[0] === $fieldSuffix) {
return;
}
} elseif (count($parts) == 2) {
if ($parts[0] === $this->model() && $parts[1] === $this->field()) {
if ($parts[0] === $model && ($parts[1] === $field || $parts[1] === $fieldSuffix)) {
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][$this->field()] = $options;
return;
}
if ((isset($this->fields[$model]) && !in_array($this->field(), $this->fields[$model], true)) || !isset($this->fields[$model])) {
$this->fields[$model][] = $this->field();
$this->__fields($model, $field, $fieldSuffix, $options);
return;
}
}
/**
* 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;
}
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

View file

@ -180,24 +180,27 @@ class SecurityComponentTest extends CakeTestCase {
$this->Controller->Security->startup($this->Controller);
$key = $this->Controller->params['_Token']['key'];
$data['Model'][0]['username'] = '';
$data['Model'][0]['password'] = '';
$data['Model'][1]['username'] = '';
$data['Model'][1]['password'] = '';
$data['Model'][0]['username'] = 'username';
$data['Model'][0]['password'] = 'password';
$data['Model'][1]['username'] = 'username';
$data['Model'][1]['password'] = 'password';
$data['_Model'][0]['hidden'] = 'value';
$data['_Model'][1]['hidden'] = 'value';
$data['_Model'][0]['valid'] = '0';
$data['_Model'][1]['valid'] = '0';
$data['__Token']['key'] = $key;
$fields = array(
'Model' => array(
0 => array('username', 'password', 'hidden'),
1 => array('username', 'password', 'hidden')),
0 => array('username', 'password', 'valid'),
1 => array('username', 'password', 'valid')),
'_Model' => array(
0 => array('hidden' => 'value'),
1 => array('hidden' => 'value')),
0 => array('hidden' => 'value', 'valid' => '0'),
1 => array('hidden' => 'value', 'valid' => '0')),
'__Token' => array('key' => $key));
$fields = $this->__sortFields($fields);
$fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
$data['__Token']['fields'] = $fields;
@ -208,6 +211,9 @@ class SecurityComponentTest extends CakeTestCase {
unset($data['_Model']);
$data['Model'][0]['hidden'] = 'value';
$data['Model'][1]['hidden'] = 'value';
$data['Model'][0]['valid'] = '0';
$data['Model'][1]['valid'] = '0';
$this->assertTrue($this->Controller->data == $data);
}

View file

@ -258,6 +258,126 @@ class FormHelperTest extends CakeTestCase {
);
$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 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')));
$this->assertPattern('/'.$expected.'/', $result);
$this->assertPattern('/input type="hidden" name="data\[__Token\]\[fields\]" value="'.$expected.'"/', $result);