Problem/Motivation
It is not possible to create a comment via a REST POST because the field access is too strict.
Well, this is the way to add a comment using hal+json
{
"_links": {
"type": {
"href": "http://d8/rest/type/comment/comment_type"
},
"http://d8/rest/relation/comment/comment/entity_id": [
{
"href": "http://d8/node/1"
}
]
},
"entity_type": [{
"value": "node"
}],
"entity_id":
[{"target_id":"1"
}],
"field_name": [{
"value":"field_test_comment"
}],
"uid": [{
"target_id":"1"
}],
"comment_body":[{
"value":"HEYYYYYYYYYYY"
}]
}Here another example #2300827-19: How to POST a comment and other entities using entity references
So, if you avoid the validation, the comment is created as expected. It is not correct because we need to avoid to add the uid for example and of course we need the validation.
But, if you try to add the comment using the validation you will see this error:
{"error":"Access denied on creating field entity_id"}
or the same for entity_type...
If you remove the field from the json then you will see:
{"error":"Unprocessable Entity: validation failed.\nentity_id: This value should not be null.\n"}
And the problem is here (CommentAccessControlHandler::checkFieldAccess)
// No user can change read-only fields.
$read_only_fields = array(
'hostname',
'uuid',
'cid',
'thread',
'comment_type',
'pid',
'entity_id',
'entity_type',
'field_name',
);
if (in_array($field_definition->getName(), $read_only_fields, TRUE)) {
return AccessResult::forbidden();
}Proposed resolution
Some of the read-only fields are in fact editable when the comment is new. Update access controller to reflect this.
Remaining tasks
Reviews
Original report by @marthinal
| Comment | File | Size | Author |
|---|---|---|---|
| #13 | comment-rest-access-2430669.pass_.patch | 8.41 KB | larowlan |
| #13 | comment-rest-access-2430669.fail_.patch | 6.97 KB | larowlan |
| #4 | 2430669-4.patch | 1.83 KB | marthinal |
| #2 | 2430669-2.patch | 1021 bytes | marthinal |
Comments
Comment #1
marthinal commentedComment #2
marthinal commentedWorking a little bit more on this I have detected that we set to 0 the uid by default. No uid is added when creating a comment programatically. This patch fixes the problem but maybe we should add this method(getCurrentUserId()) to the ContentEntityBase class...
Comment #3
larowlanSo that fixes entity type too, or are you fixing something else with that patch?
Comment #4
marthinal commented@larowlan I was adding the uid by default when creating a comment programatically. The current patch fixes the entity type problem.
By default only cid and uuid are read only fields...
Comment #5
larowlanYeah but this is going to impact #2227503: Apply formatters and widgets to Comment base fields - we have to make sure those fields don't show up in the edit form after we change the access controls.
Also, expect CommentFieldAccessTest will fail with current patch.
Comment #7
clemens.tolboomIn trying patch from #2 or #4 I cannot post a comment.
It fails on \Drupal\comment\Plugin\Validation\Constraint\CommentNameConstraintValidator maybe due to anonymous user?
I thought this issue was connected with #1964034: Pass entity_type into Serializer via context but are not sure anymore. To post a comment we now need lot of tricky data: entity_type, entity_id, field_name of which the first 2 are duplicates as their values are derivable from _links.
I've created #2469581: Add tests for comments CRUD for REST as we are chasing head for POST comments :-/
Comment #8
larowlantagging
Comment #9
larowlanLooking
Comment #10
larowlanComment #11
larowlanClosed #2469581: Add tests for comments CRUD for REST in favour of this. Bringing in the tests to here.
Comment #12
alexpottCreating @clemens.tolboom as requested by @larowlan
Comment #13
larowlanBrings in and finishes tests from #2469581: Add tests for comments CRUD for REST and changes implementation to make sure that the fields are only editable on create, when the entity is new.
Comment #15
larowlanIssue summary changes
Comment #16
larowlanComment #17
jibranHow is this create only field?
Comment #18
larowlanYou can't edit uuid after an entity is created right?
Comment #19
larowlan@jibran and I discussed this on IRC - whether uuid should be read only, or allowed on creation. Based on our existing tests we concluded that it is allowed on creation.
logs below
Comment #20
jibranPatch has a dedicated test for access check which is good and it also has a comment creation test using rest api which fixes the original bug so it's awesome. Code changes look good so RTBC.
Comment #21
alexpottThis issue addresses a major bug and is allowed per https://www.drupal.org/core/beta-changes. Committed db390cd and pushed to 8.0.x. Thanks!