Reputation: 14564
In Cake 2 you could save a model and specify which fields you wanted to restrict the save to.
Is there a built-in way to do this simply in Cake 3? For example, if the request data is being put straight into a new entity which is then saved, how can I tell the method to only save the fields I allow?
Simplified Example
// User makes a request; their POST data goes directly into the entity
$customer = $this->Customers->newEntity($this->request->data);
$this->Customers->save($customer);
The obvious danger here is that I can set any properties I like on that customer entity, via the request. In reality, I only want to allowing saving of a couple of specific fields.
Upvotes: 1
Views: 2727
Reputation: 60473
That's what mass assignment protection is there for, in the form of the $_accessible
entity property
class Customer extends Entity
{
// allow only `first_name` and `last_name` to be mass assigned
protected $_accessible = [
'first_name' => true,
'last_name' => true
];
}
and the fieldList
and accessibleFields
options for Table::newEntity/newEntities/patchEntity/patchEntities()
// allow only `first_name` and `last_name` to be mass assigned,
// ignoring the entity accessible defaults
$customer = $this->Customers->newEntity($this->request->data(), [
'fieldList' => [
'first_name',
'last_name'
]
]);
The accessibleFields
option will change the accessibility of the specified fields only. Also it will actually modify the entity, ie unlike fieldList
, which the marshaller will simply use as the whitelist instead of the entity defaults, accessibleFields
will change the values of the entities $_accessible
property!
See
Upvotes: 4
Reputation: 9707
There are two ways of protecting you against this problem. The first one is by setting the default columns that can be safely set from a request using the Mass Assignment feature in the entities.
The _accessible property allows you to provide a map of properties and whether or not they can be mass-assigned. The values true and false indicate whether a field can or cannot be mass-assigned:
http://book.cakephp.org/3.0/en/orm/entities.html#entities-mass-assignment
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Article extends Entity
{
protected $_accessible = [
'title' => true,
'body' => true,
'*' => false,
];
}
The second way is by using the fieldList option when creating or merging data into an entity:
// Contains ['user_id' => 100, 'title' => 'Hacked!'];
$data = $this->request->data;
// Only allow title to be changed
$entity = $this->patchEntity($entity, $data, [
'fieldList' => ['title']
]);
$this->save($entity);
You can also control which properties can be assigned for associations:
// Only allow changing the title and tags
// and the tag name is the only column that can be set
$entity = $this->patchEntity($entity, $data, [
'fieldList' => ['title', 'tags'],
'associated' => ['Tags' => ['fieldList' => ['name']]]
]);
$this->save($entity);
Using this feature is handy when you have many different functions your users can access and you want to let your users edit different data based on their privileges.
The fieldList options is also accepted by the newEntity(), newEntities() and patchEntities() methods.
For more :http://book.cakephp.org/3.0/en/orm/saving-data.html
Upvotes: 2