Problem/Motivation
Please refer the problem/motivation section of #2737719: EntityResource: Provide comprehensive test coverage: for every entity type, every format, every method
This test coverage uncovered a security problem: it's impossible to deploy the entity:file
REST resource without allowing anybody (even anonymous users) to view File
entities in json
, xml
or hal_json
format.
Proposed resolution
Write EntityResourceTestBase subclass for the File entity, and to address the security problem in a non-invasive way (in a way that is not a BC break in practice), we the File
entity's view
operation now requires the access content
permission.
Remaining tasks
Build consensus, specifically about using theaccess content
permission to be allowed toview
File entities.#2892821: Core modules check node module's "access content" permission for displaying things that have nothing to do with nodesGreen patch.RTBC.
References
1. Follow-up of #2737719: EntityResource: Provide comprehensive test coverage: for every entity type, every format, every method
2. Subtask of #2824572: Write EntityResourceTestBase subclasses for every other entity type.
Comment | File | Size | Author |
---|---|---|---|
#121 | strong-chord-from-webchick.png | 379.04 KB | Anonymous (not verified) |
#109 | 2843139-109.patch | 24.12 KB | Wim Leers |
#96 | interdiff-94-96.txt | 1.16 KB | Anonymous (not verified) |
#96 | 2843139-96.patch | 21.09 KB | Anonymous (not verified) |
Comments
Comment #2
naveenvalechaComment #4
harings_rob CreditAttribution: harings_rob at Harings.be for Nuvole commentedComment #5
harings_rob CreditAttribution: harings_rob at Harings.be for Nuvole commentedI have prepared a raw draft of the implementation, however I am running into some issues I do not know how to resolve (yet)
I could not find any documentation or resources about file entity endpoints.
If someone could assist a bit on getting me up and running that would be great.
Comment #6
Anonymous (not verified) CreditAttribution: Anonymous commented@harings_rob, thank you for draf, it is helpful! Unfortunately, the File does not look friendly to the Rest.
We cann't use
POST
, becauseFileAccessControlHandler::checkCreateAccess()
constantly return theAccessResult::neutral()
(see also #1927648: Allow creation of file entities from binary data via REST requests).We cann't use
public://
storage, because it always return 200 status. We can use trick withprivate://
and Node Field Access via reference, but only forGET
(see patch get_and_node). But this leads to problems with accessing the file in HAL tests.We can use with switch author of file, but it's looks extremely doubtful (see patch get_patch_delete). And
PATCH
will pass only after #2853211: EntityResource::post() incorrectly assumes that every entity type has a canonical URL.PS. I added these patches only for the demonstration, and do not count on anyone's approval, of course :) If I do not mistake, we should first negotiate with the File module, and only then come back here :(
Comment #9
Anonymous (not verified) CreditAttribution: Anonymous commented'url' => '/checkout/user/3'
on Bot's site, hm.. Both my patches are green localy. Bu I did not make them neat enough, sorry. Should I correct them, if they are not on the right way?Comment #10
harings_rob CreditAttribution: harings_rob at Harings.be for Nuvole commentedWhere do you get this url from? I think it should be using $this->baseUrl as well?
Did you find this information because you know where to or was I looking in wrong places?
Comment #11
Anonymous (not verified) CreditAttribution: Anonymous commentedYou absolutely right. Attached fix for get_and_node. For second patch we need same changes + #2853211-21: EntityResource::post() incorrectly assumes that every entity type has a canonical URL. But before taking care of these patches, I suggest waiting for hints about the right direction.
Comment #12
Wim LeersThis is at minimum blocked on #2853211: EntityResource::post() incorrectly assumes that every entity type has a canonical URL, possibly also blocked on #1927648: Allow creation of file entities from binary data via REST requests.
Comment #13
Wim Leers#2853211: EntityResource::post() incorrectly assumes that every entity type has a canonical URL landed, this is now (at least partially) unblocked!
Comment #14
Anonymous (not verified) CreditAttribution: Anonymous commentedReroll variant with max test coverage (
rest
withoutPOST
, andhal
withoutPOST
&PATCH
). But the more I try to pass all the tests, the more looks like we need just to wait next issues:POST
: #1927648: Allow creation of file entities from binary data via REST requestsPATCH
inhal
test: #2539622: File uri field type has default formatter uri_link, throws exception when trying to renderWhat the problem with
PATCH
inhal
?EntityResourceTestBase
in 884 line returns 500 instead of 403:With next body:
Comment #15
Wim LeersWell the thing is that all those issues would hugely benefit if this test coverage already existed. Because then they can just update this test coverage!
However, I do think it's fine to use
$this->markTestSkipped()
for thePOST
andPATCH
testing, because as you say, those are riddled with problems/bugs right now. You can then just add an explicit@todo
to the relevant issues, to indicate that it's their responsibility to add this test coverage.:O What is this doing? I have no idea!
I have to admit, I was completely confused by this…
So I applied the patch locally, and tried to make it simpler: I tried to let the created
File
entity have the "correct" owner (the current user), which is user 0 for anon tests, and user 2 for auth tests.But then this in
FileAccessControlHandler
gets in the way:… because that means the
EntityResourceTestBase::testGet()
coverage that verifies that without the necessary authorization, you get a 403.So, that's why you create the
File
entity with user 3 as the owner.Okay.
So then the next problem that this solves is that in order for this file to be accessible, you then need to change the file owner to 0 or 2, precisely to get the cited code to allow access!
But why? Because you use a
private://
file, not apublic://
file! And hence the very first check inFileAccessControlHandler
does not apply.So why use
private://
? It's rather uncommon — the 90% use case ispublic://
. So IMHO we should test that.So, in this reroll, I'm changing it from
private://
topublic://
.But then you again have the problem that the public file is always granted access. So let's do the same here that we've done in many other tests: update
FileAccessControlHandler
to require theaccess content
permission in order for it to be allowed.So I did that this in reroll too.
AFAIK user 3 will never exist? So let's just go ahed and always create this, that will slightly simplify this code.
Let's use
setOwnerId()
,setFilename()
etc.That's … interesting. Why doesn't this at least vary by the
user.permissions
cache context?Because
If so, let's add a comment here:
@see \Drupal\file\FileAccessControlHandler::checkAccess()
.So, yes, like this. But let's add an
@todo https://www.drupal.org/node/1927648
:)Let's do something similar for
testPatch()
.Nit: needs
\n
in between.Comment #17
Anonymous (not verified) CreditAttribution: Anonymous commentedFantastic adjustment! Now I feel the ground under feet again !)
15.1: I just wanted to steal an your idea, but
array_diff
breaks down the sort andassertEquals
do not sort by default. Of course, we can just usesort()
afterarray_diff()
, but after the #15 patch, we do not need to change anything at all :)15.3: It is necessary for
DELETE
test, because this test callcreateEntity()
too, but we can use random postfix for get unique user name instead of check $author.Also after #15 patch, we haven't problem with
GuzzleHttp\Exception\ClientException
in PATCH in hal tests!But now there is a problem with the processing
_restSubmittedFields
, becauseFileEntityNormalizer
don't adding this property. I tried fix this problem + repaired a couple of foreign tests.And
'administer files'
to'update/delete'
operations.Comment #18
Wim LeersYay! :) It's one thing for me to spend some time digging into this. But if you then take that, and push it further, that makes it totally worthwhile! Thank you, @vaplas! :) Once again, great work!
WOOOT GREEN PATCH!
Heh… this means that the
access site reports
permission that was there before was not necessary.Still, let's not change this here. Let's just add the
access content
permission. We only want to update these tests in the most minimal way possible, and that means only adding the necessary permissions for file access, not fixing existing permissions/bugs.s/uid/UID/
Also, I don't think this comment is entirely accurate anymore, since my changes in #15?
Nit: let's use
->activate()
instead :)I was going to ask:
— but then I noticed why: these methods don't allow that :(So, this code is good as it is right now: fixing those setters is out of scope here.
This is by far the most complex or even "wtf" part of this patch. You already mentioned this in #17.
I still don't fully understand this though. I'd like to ask you to:
This is very close now! :)
Comment #19
Anonymous (not verified) CreditAttribution: Anonymous commented18.5: yeah, I've gone a little too far with this :) This need to
Drupal\rest\Plugin\rest\resource\EntityResource::patch()
(here) and was like c/p fromContentEntityNormalizer::denormalize()
.Comment #20
Wim LeersThis is much better, but still not clear enough.
Why is the default value for
$entity->_restSubmittedFields
not correct?And why unset
_links
and_embedded
?Oh, wait! It's simply that
\Drupal\hal\Normalizer\FileEntityNormalizer
subclasses\Drupal\hal\Normalizer\ContentEntityNormalizer
but its::denormalize()
method does not call the parent implementation! The stuff you were doing before you simply copied over from the parent implementation.So, then my question becomes: why can't we call the parent method?
Comment #21
Anonymous (not verified) CreditAttribution: Anonymous commentedCOOL!
Wait, new changes:
array wrapper, why? Because parent call
denormalizeFieldData() .. go-go-go .. if (!is_array($data))
inFieldNormalizer::denormalize()
(here).Comment #22
Wim LeersThanks! Much better! RTBC assuming this comes back green :)
Also, I want to note that the changes made to
\Drupal\hal\Normalizer\FileEntityNormalizer::denormalize()
imply thatPATCH
ingFile
entities viahal_json
simply is broken in HEAD, and likely never worked.Comment #23
Anonymous (not verified) CreditAttribution: Anonymous commentedDrupal\Tests\hal\Functional\FileDenormalizeTest::testFileDenormalize()
has case:But
ContentEntityNormalizer::denormalize()
need for'_links'
:Therefore, I returned the old behavior for the case without
_links
:(Comment #26
Wim LeersMakes sense. Because indeed, in
\Drupal\hal\Normalizer\ContentEntityNormalizer
:Comment #27
damiankloip CreditAttribution: damiankloip at Acquia commentedThis also looks good to me, as a side note #1927648: Allow creation of file entities from binary data via REST requests will hopefully just remove the FileEntityNormalizer altogether or just keep a small part for normalization only.
Comment #28
Wim Leers#27: that sounds great! :)
Comment #31
alexpottI'm not sure about this change. I guess we have an issue here in that access here means access to the entity info whereas access in the original comment was implying access to the file. I'm not sure it's really correct to change this. As per othe issues I think we need an issue to discuss the overall strategy here and whether or not 'access content' is appropriate for these type of things. Atm it feels like we're adding this to make the generic tests pass rather than for reasons of correctness.
We're missing caching the result by permissions no? Also the owner can change so we should be caching by entity change too (although this looks like it is an existing bug).
Comment #32
Anonymous (not verified) CreditAttribution: Anonymous commentedHah! Fair remark! But I can not agree with this, of course. Maybe my opinion is biased, but on the contrary, we patchinig holes in access logic through the passage of the rest-tests :)
31.2: Need to
addCacheableDependency
for all cases of FileAccessControlHandler::checkAccess(), or only indelete/update
?[PP-1] Postponed by #2870018: Should the 'access content' permission be used to control access to viewing configuration entities via REST + 31.2 point.
Comment #33
Wim LeersYep, this is blocked on #2870018: Should the 'access content' permission be used to control access to viewing configuration entities via REST reaching consensus.
#31:
'access content'
is the "baseline access" permission. The'administer files'
permission would be consistent with other entityadmin_permission
s, and typically allows doing anything to any file.Comment #34
Wim LeersConsensus was achieved! Quoting #2870018-35: Should the 'access content' permission be used to control access to viewing configuration entities via REST:
Since
File
has an access control handler that grants blanket access, we need to implement the second option. But theFile
entity does not have a "view" permission, nor an "admin" permission. So it's not clear how to continue. Furthermore, there's an important distinction between "viewing" and "downloading".Next, downloading (
$op === 'download'
)public://
files must always be free of permissions: that's how we shipped D8, we can't change that now. But we can change the requirements for viewing ($op === 'view'
) IMO, because likely nobody has been using that so far.So I propose we strike a middle ground here: we only change the behavior for:
public://
filesview
ed, notdownload
edview files
permission, we just require aaccess content
permission, because that aligns more closely with user expectations, further reducing disruption, and matching expectationsSince this is diverging (by necessity) from the simple consensus rules we arrived at, marking this NR, not RTBC.
Comment #35
xjmThis issue is fixing bugs, not just adding test coverage, so let's retitle and rescope it appropriately.
Comment #36
alexpottI thought that these access results ought to cache until entity changes - because of the scheme check - but @Wim Leers pointed out you shouldn't be able to change scheme.
These access results should be cached until the entity changes because the owner can change.
Comment #37
Wim LeersNW for #36.2.
Comment #38
Wim LeersComplying with #35, even though I don't fully agree with it.
The primary scope of this issue is a task: adding missing test coverage. This unveiled something that was forgotten before, which can be considered either a task to add it, or a bug, depending how you look at it. But that doesn't change the primary scope of the issue: that's certainly a task.
Anyway, let's get this patch updated. Any volunteers?
Comment #39
Anonymous (not verified) CreditAttribution: Anonymous commentedYes, of course!)
#37 (#36.2) + #2768651: Let TimestampItem (de)normalize to/from RFC3339 timestamps, not UNIX timestamps, for better DX + bit change in
formatExpectedTimestampItemValues
for compatibility:Comment #40
Anonymous (not verified) CreditAttribution: Anonymous commentedOr better convert immediately?
Comment #41
Wim LeersThanks, @vaplas!
I wrote this at #34:
But nobody is ever going to review this, except a committer. It's been sitting here for >2 weeks. In the end, a committer needs to sign off on this anyway. I didn't upload the patch in #40, so I'm going to RTBC again.
Comment #43
Wim Leers#40 is green again. It was re-tested on June 5 and failed. It was re-tested twice since then, and was green each time. Likely a random failure.
Comment #44
Wim LeersComment #45
catchI understand why it's necessary for access, but I'm not convinced from a usability point of view about adding a generic 'administer files' permission that unless REST is enabled, doesn't actually allow you to administer files at all - it ends up being a no-op permission.
Comment #46
Wim Leers#45: Do you have an alternative proposal?
Comment #47
catchNot really yet. On config entities we used 'administer site configuration' which was a really good compromise, that's not appropriate here.
I did think about something horrible like hiding the permission in the UI then altering it to visible, but not sure that's a good trade-off at all.
Comment #48
Wim LeersI think
administer files
would actually be a useful permission for content administrators/moderators. It could allow them to see all files at/admin/content/files
, even private files.(The patch does not currently do that, to minimize changes. But I think that'd be a good justification, and it solves an actual need.)
Comment #49
tstoecklerI like #48, but until we have that, we could also dynamically define this permission in
rest.module
if the file resource is enabled. That way we could avoid the UX problem.Comment #50
Wim Leers#49: that's a no-go, because:
Comment #51
tstoecklerThat's precisely not true. "it" in your case is solely the file resource, so nothing changes. The thing that you claim changes commences its existance at the precise time the permission does.
Comment #52
Wim LeersSorry, #51 does not make sense to me. If you have both REST and JSON API installed, then having the REST module changing access control to the
File
entity will also affect JSON API.Comment #53
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI'm confused by the conversation from #45 on. Why is it exactly that we need this patch to add an
'administer files'
permission? Specifically:Why not just base this on
'access content'
alone?Why do we want this change?
Instead of granting the tested role 'administer files' permission, can we instead have the test agent authenticate as the file owner (if we want to test success) and as someone other than the file owner (if we want to test a permission denied)?
Comment #54
Anonymous (not verified) CreditAttribution: Anonymous commentedComment #55
Wim LeersBack to RTBC, thanks @vaplas for answering #53!
Comment #57
Wim LeersComment #58
Anonymous (not verified) CreditAttribution: Anonymous commentedRerolled after SA-CORE-2017-003.
NB: now
uri
is protected, therefore, an additional conditional wrapper inFileEntityNormalizer::denormalize()
. The interdiff is made with-w
flag for more readability of this change.Comment #59
savkaviktor16@gmail.com CreditAttribution: savkaviktor16@gmail.com at Skilld commentedI could apply the patch, so no reroll is needed
Comment #60
jofitz CreditAttribution: jofitz at ComputerMinds commentedComment #61
Wim LeersThe only non-trivial change in #58 is this:
I first wondered why this is necessary. So I looked into it.
Without this change
PATCH
ing of file entities is broken 100% of the time when using thehal_json
format because\Drupal\hal\Normalizer\FileEntityNormalizer::denormalize()
unconditionally uses$data['uri']
, which is forbidden as of http://cgit.drupalcode.org/drupal/commit/?h=HEAD&id=c732355412b84a6f7079....So this is breaking a regression introduced by SA-CORE-2017-003. That regression would never have happened if this test coverage had already been part of Drupal core.
Therefore +1 for this change.
Comment #62
Wim LeersI also took another good look at the feedback @effulgentsia posted in #53, which @vaplas replied to in #54.
Perhaps it's useful for me to expand on what @vaplas already wrote.
EntityResourceTestBase
makes one key assumption wrt access control: . i.e. you should first have to grant some permission before some action is allowed. Otherwise there's no way to restrict API access for a given operation for a given entity type, which means every user is allowed to do it.Therefore as part of that, this issue is changing
FileAccessControlHandler
to at least require theaccess content
permission to be allowed toGET
aFile
. This is not contested by @effulgentsia.However, the other change that's necessary, is to have some permission to be allowed to
PATCH
orDELETE
aFile
(POST
ing doesn't work yet until #1927648: Allow creation of file entities from binary data via REST requests lands, so there's no point tackling that here). Right now, there is no such restriction. The only requirement is that the user trying to perform that action is also the owner.This is the contentious part, raised in #53.2. (#53.1 is merely a consequence of #53.2 — any user able to administer files should also be able to view them.)
So to answer #53.3: if the owner of the file is in fact the test user, that means
EntityResourceTestBase
's minimum requirement wrt access control is violated: there's no way to restrict a particular operation on a particular entity type! @vaplas came up with a clever but super confusing work-around, which I analyzed and critiqued in #15.2. I proposed switching to thisadminister files
permission.@catch already raised concerns about adding this
administer files
permission in #47. Now @effulgentsia is raising that concern again in #53.So I think we'll need to come up with some alternative. Because what we have right now, is confusing and has poor security. Adding an
administer files
permission is a solution.I'd ping the
File
module maintainer, but there's no maintainer…Comment #63
Wim LeersSo now we have two choices:
correctFileOwner()
work-aroundComment #64
Wim LeersDiscussed with @effulgentsia. We decided on choice 1.
Comment #65
Anonymous (not verified) CreditAttribution: Anonymous commentedLooks awesome! This is much better than my #14.
Comment #66
Wim LeersIt's still very close to your #14, but I tried to make it a little bit cleaner — glad you like it! :)
Comment #67
catchNeed to review again properly, but conceptually #64 looks fine to me and a good compromise.
Comment #68
Wim LeersGlad to hear that!
Comment #69
BerdirThat does mean that file introduces a hidden dependency on the node module, which it currently doesn't have?
What if someone has a site that doesn't have node enabled but uses files for e.g. custom entity types?
Comment #70
Anonymous (not verified) CreditAttribution: Anonymous commentedFair remark. But these sites are most likely rare now. And for sure they will still use the
'node'
module. Because without this module we haven't'access content'
permission, which is needed in many places drupal. Includingfile.ajax_progress
(see point @dawehner's in #2870018-17: Should the 'access content' permission be used to control access to viewing configuration entities via REST).In any case, the heroes who use drupal with super-specific configurations are probably already accustomed to a difficult fate :)
Comment #71
catchWe should probably move the access content permission to system module or at least discuss that in a follow-up?
Comment #72
Anonymous (not verified) CreditAttribution: Anonymous commentedComment #74
Anonymous (not verified) CreditAttribution: Anonymous commentedIt was random fail #2828143: Stop tests like LocaleConfigTranslationImportTest from failing if l.d.o becomes unavailable.
Comment #76
dawehnerI just opened up an issue about moving 'access content' to system module: #2907121: Move 'access content' permission to system module
Comment #77
Wim Leers❤️👏
Comment #78
Wim LeersSo, this was RTBC in #64, on June 28. That's >2 months ago.
@Berdir raised concerns in #69, about this introducing a hidden dependency on the
node
module. @vaplas replied to this in #70, elaborating on it, and @catch mentioned in #71 that we probably want to move it tosystem
module. So @dawehner just created the issue in #76 to actually do that.Once that's done, hopefully this can become an easy commit :)
Comment #79
Wim LeersApparently #2907121: Move 'access content' permission to system module is a duplicate of #2892821: Core modules check node module's "access content" permission for displaying things that have nothing to do with nodes, which we didn't notice, despite @vaplas helpfully linking it!
Marking this postponed per #78.
Comment #80
tedbowSo since this issue deals with "tighten access control handler" for files not expanding this might not be right issue but just thought I would comment here because I added patch to #1927648: Allow creation of file entities from binary data via REST requests expand file access handler and it was mentioned it might more sense here. You can see the patch on the other but the gist of it is when dealing with updating or deleting file entities
Thoughts? Belong in another issue?
Comment #81
Wim LeersBelongs in another issue. The scope of this issue really is "add
File
REST test coverage". Sadly, this requires a change to the existing access control logic — although it arguably should be descoped from this issue and get an issue of its own. But in any case, "totally revamp file access control handling", which is what #80 implies, deserves its own issue!Comment #82
tedbow#81 ok that makes sense. Maybe what I was describing in #80 should really only happen if users ask for it rather imagine how users might want to use the file resource.
Comment #83
Wim LeersSee #2824572-55: Write EntityResourceTestBase subclasses for every other entity type. and #2824572-57: Write EntityResourceTestBase subclasses for every other entity type.: this is the last remaining non-RTBC blocker for completing REST test coverage for all core entity types!
Not only does this block #2824572: Write EntityResourceTestBase subclasses for every other entity type., it also kinda/probably blocks #1927648: Allow creation of file entities from binary data via REST requests. Both are major.
Comment #84
Wim LeersThis is still blocked on #2892821: Core modules check node module's "access content" permission for displaying things that have nothing to do with nodes, but that patch is RTBC and will hopefully soon be committed. So let's already reroll this patch on top of that.
Now there's no longer a dependency on the
node
module, so the tests can be updated, which addresses Berdir's concerns.Comment #85
Wim LeersThis should probably be blocked on #2825487: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field too.
Comment #86
Wim Leers#2892821: Core modules check node module's "access content" permission for displaying things that have nothing to do with nodes landed!
Comment #88
Wim Leers#84 was a straight rebase of #64. #64 was green, #84 has 6 failures: all the
Media
entity RESTPATCH
tests. #64 didn't have any failures, because it predates theMedia
entity REST tests.The root cause? This patch requires you to have the
access content
permission to be allowed toview
File
entities. WhenPATCH
ing aMedia
entity, we point to aFile
entity, and for that, you need theaccess content
permission. So just granting theaccess content
permission solves the problem (and 99.999% of sites will have this enabled already anyway, so it's not a behavior change for them).Of course, in theory, you shouldn't need that permission if you're not actually changing which
File
entity is referenced by theMedia
entity! That is being fixed by #2824851: EntityResource::patch() makes an incorrect assumption about entity keys, hence results in incorrect behavior. So for now, I'm granting theaccess content
permission, and am including a@todo
to remove that in #2824851: EntityResource::patch() makes an incorrect assumption about entity keys, hence results in incorrect behavior.Comment #90
Wim LeersComment #91
Anonymous (not verified) CreditAttribution: Anonymous commentedEpic news!
#89: unrelated fail, now green again.
Comment #92
Wim LeersGreat, #88 is green! But this is still blocked on #2825487: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field, so postponing once more…
Comment #93
Wim LeersPer #2825487-128: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field.17, I think this should probably go in before #2825487.
Comment #94
Wim LeersApparently the patch from #88 still applies. Reuploading to see if it still passes tests.
Comment #95
Wim LeersI think the patch is actually ready — we only need an IS update here, and updated the CR.
Did that.
I rolled the last few patches, but the bulk of the work here was actually done by @vaplas! At some point, we were stuck on picking one of two approach. Core committer @effulgentsia picked one, and I applied that in #64. That was trivial — I even RTBC'd #64 in the same go. It was un-RTBC'd because it should've been blocked on #2892821: Core modules check node module's "access content" permission for displaying things that have nothing to do with nodes, which has since gone in. So I rerolled for that too, which was even more trivial.
Therefore it should still be okay for me to RTBC this.
Comment #96
Anonymous (not verified) CreditAttribution: Anonymous commented#88 super forecast! Now allowance for wonderful 'xjm-factor'!)
Comment #97
Wim Leers👏😀
Comment #98
Wim Leers#2800873: Add XML GET REST test coverage, work around XML encoder quirks just landed, which means this now needs to add XML REST test coverage for
File
too!EDIT: queued a PHP 7.1 test for #96, which should now fail, because #2800873 landed. And this patch should of course be green.
Comment #100
Anonymous (not verified) CreditAttribution: Anonymous commented#98: 💎
#99: #2926309: Random fail due to APCu not being able to allocate memory
Comment #102
Anonymous (not verified) CreditAttribution: Anonymous commentedComment #104
Anonymous (not verified) CreditAttribution: Anonymous commented#2926309: Random fail due to APCu not being able to allocate memory
Comment #106
Anonymous (not verified) CreditAttribution: Anonymous commented#105: perhaps an echo from #2829040-91: [meta] Known intermittent, random, and environment-specific test failures
Comment #107
Wim LeersUpon re-reviewing this, I noticed these changes to HAL's
FileEntityNormalizer::denormalize()
.These changes are out of scope here, and also unnecessary. Because
\Drupal\Tests\rest\Functional\EntityResource\File\FileResourceTestBase
is not yet testing the uploading of files. That's being taken care of in #1927648: Allow creation of file entities from binary data via REST requests.Simply reverting that change.
Comment #109
Wim LeersOk, so 107's reverting of the changes made to HAL's
FileEntityNormalizer::denormalize()
causes the following failures:Unsurprisingly, 3 failures: the HAL+JSON
PATCH
test in all 3 of core's authentication mechanisms.Well, that means we'll just have to skip
PATCH
File
testing of HAL+JSON. It's up to #1927648: Allow creation of file entities from binary data via REST requests to fix it. But this then goes to show that it doesn't work at all.Comment #110
Wim Leers@vaplas, do you want to re-RTBC? :)
Comment #111
Wim LeersHm, all I did was descope one change in #107, and then update the tests accordingly in #109. That's no significant change.
This patch has been ready for such a long time already, and is doing two things only:
FileAccessControlHandler
to require theaccess content
permission toview
files.This has been agreed upon for ages.
FileResourceTestBase
+ subclasses for comprehensiveFile
REST test coverage, which unblocks #2825487: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field, which in turn unblocks #1927648: Allow creation of file entities from binary data via REST requests. There's nothing to agree about here: it's merely testing the status quo, so that we don't accidentally break BC!So given all that, it's okay for me to re-RTBC.
Comment #112
BerdirI still think this is wrong simply because it can't be enforced. Reality is that anyone can access public files, you can't prevent it by removing that permission, so it is at least misleading and implies functionality that doesn't exist.
You could make a difference between download and view, which would likely make your rest tests happy, but at least in core, it's not consistently used and there is no real difference between the two (and file_entity makes an even bigger mess of it ;))
Comment #113
Wim Leers… that is exactly what the patch is doing?
You mean you can't read the contents of a File entity with just core? That's true. The REST module is the first to add that. Which is exactly why this issue is the first one to raise the need to be able to restrict access to
File
entities' data. Without this, it is public knowledge that https://www.drupal.org/project/jsonapi allows any user to see every single File entity that exists, which can lead to information disclosure.Ensuring no entity type has information disclosures by default is exactly what
\Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testGet()
is testing generically. And which is why we need to make this change here.Those are then yet more bugs elsewhere in core. We can fix those. That shouldn't prevent us from making this pragmatic, minimal step forward, right?
Comment #114
BerdirRight, sorry, I misread that about download/view access.
So we have two tests that have to be changed here:
* FileManagedAccessTest: Because it specifically checks access for both view and download. That makes sense, nothing else in core does that, so theoretically we could also update the test to more expliictly check the if/else, but fine.
* FileItemTest: Because without that permission, saving of the file entity fails. This could have *very* theoretical BC breaks if someone e.g. allowed someone to upload files on a custom entity that did not require the access content permission, but Wim correctly pointed out that several things would not work without that anyway, e.g. file upload progress. So it is extremely unlikely that anyone has this.
So.. lets do this, it's time to finally fix #1927648: Allow creation of file entities from binary data via REST requests.
Comment #115
Wim LeersYAYYYYYY!
🎉
Comment #116
webchickThanks, @Berdir.
Ok! Wim pinged me and we stepped through this patch together.
We spent a lot of time talking about the hunk @Berdir highlighted in #112. Unlike other aspects of this patch, which are specific to the REST system, this one touches the generic File entity and therefore has broader implications. However, trying to come up with a real, actual use case of a site that uses the public file system, and does not use nodes, and does not assign users "access content" permissions is pretty difficult to do. (Whereas I can definitely think of such use cases using the private file system, and have built at least one in the past. :)) And as Wim pointed out, this is the least bad of all possible options, the others being leave files completely open and insecure, or disallow REST access to files altogether.
The other hunk that stood out was:
But this is already linked off to a sub-issue, the dependency of which is also RTBC currently, so hopefully this won't be around for too long.
Otherwise, this looks like a really solid step for the API-First initiative. I'm actually really impressed with how the tests are structured, so that we can test various permutations (anon + hal, anon + json + cookie auth, etc.) with relatively few lines of code.
This is an important patch to establish a baseline for when we do ultimately fix the ability to deal with files in REST, so while the couple of
$this->markTestSkipped();
lines feel suboptimal, they also feel necessary to move forward.Committed and pushed to 8.5.x, officially bringing REST's entity test coverage to 100%. ROCK! \m/
Comment #118
webchickAlso, tagging for a release notes mention (given the change to
FileAccessControlHandler::checkAccess()
), and also a highlights mention (for the 100% entity REST test coverage :)).I think this could also benefit from a change record, so I'll work on that next.
Comment #119
webchickHere's a draft change record: https://www.drupal.org/node/2927918
Comment #120
Anonymous (not verified) CreditAttribution: Anonymous commented🎉❤️🙏👏🎸🤘🌟!!!11
@webchick, you made my day! This is really a significant event, which strikes at uncontrolled access to the file entity. And, of course, allows us to win #2824572: Write EntityResourceTestBase subclasses for every other entity type.! What is the official clarity in accessing the entities! If it's not delicious, then what's delicious?!)
Thanks to everyone, and especially @Wim Leers!
#1927648: Allow creation of file entities from binary data via REST requests incredible work! 💪💪💪
Comment #121
Anonymous (not verified) CreditAttribution: Anonymous commentedComment #122
webchickHaha, wow! That's the most epic 'thank you' I've ever gotten for a Drupal core commit. 😁 Thanks right back to you, vaplas!
Comment #123
Wim LeersYAY!
Comment #124
BerdirFor the record, this *did* break tests in token module which was uploading user pictures without having node module installed/access content .
See #2929240: Drupal\token\Tests\TokenUserTest::testUserTokens fails in dev branch.
Comment #125
effulgentsia CreditAttribution: effulgentsia at Acquia commentedGiven #124, let's publish the CR in #119? Before doing so, can someone who's worked on this issue confirm its accuracy? Thanks.
Comment #126
Anonymous (not verified) CreditAttribution: Anonymous commented#119 CR looks nice for me. Especially an example at the end of the record. As a non-native speaker, it immediately becomes clear to me what to do. 💎
Comment #127
BerdirPublished that, looks good to me.