-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce constraint on PATCH to only patch target resource #349
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: Ted Thibodeau Jr <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this?
Because it seems to limit extensibility.
Furthermore, the spec does not define any methods that could change multiple resources, and the server cannot be expected to understand patch formats that are not covered by the spec.
So I don't think this text is necessary (or testable beyond what the specific patch formats already require, given that we cannot test any other patch formats because the server is not required to support them).
I'd like to have such things in because it is a dangerous thing to do, if people were writing new patch formats, they shouldn't do it. There is a specific case of |
Does that mean we can never have atomic updates to multiple resources at any point in the future? Or rather that we cannot have them via I could get behind that principle. However, then there is another obstacle:
What does change mean? To give a trivial example, the Or a patch to one resource could trigger something in another resource. (If I switch my main controller off, then all of my lights go off too.) So language-wise, perhaps something to the extent of: servers MUST NOT allow clients to explicitly request multi-resource changes via |
Yeah, definitely! Or, we could remove the constraint if we are sufficiently confident it would not cause harm. What I'm trying to do is to harden the servers so that a malicious actor can't exploit a client to confuse a user to modify a resource they shouldn't. If we can be confident through other means that can't happen, then OK. But until then, I think such measures are very important. It can be done throught SPARQL Update on a SPARQL Endpoint, for example, that would lie outside of the current protocol, but it should be doable.
Oh, yes, that's a real issue, because we do rely on side-effects for much of the functionality, and...
Yup.
Yeah, and there could be cascading writes, like in #227...
OK, great, I'll adopt that! |
The latest language is a big improvement. SPARQL Update on a SPARQL Endpoint is not only outside the purview of Solid per se, but also well beyond "expert mode", and ramifications of any change a user makes vis such "expert mode" should also be considered outside the purview of Solid, and the user assumes the responsibility of such ramifications. Much like tinkering inside the cover of any appliance voids the warranty... The tinkering is not impossible, just reasonably guarded and warned against. |
Well no; just not with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
@@ -708,6 +708,11 @@ <h3 property="schema:name">Writing Resources</h3> | |||
|
|||
<p><span about="" id="server-protect-containment" rel="spec:requirement" resource="#server-protect-containment"><span property="spec:statement"><span rel="spec:requirementSubject" resource="spec:Server">Servers</span> <span rel="spec:requirementLevel" resource="spec:MUST">MUST</span> NOT allow HTTP <code>POST</code>, <code>PUT</code> and <code>PATCH</code> to update a container’s containment triples; if the server receives such a request, it <span rel="spec:requirementLevel" resource="spec:MUST">MUST</span> respond with a <code>409</code> status code.</span></span> [<a href="https://github.com/solid/specification/issues/40#issuecomment-573358652" rel="cito:citesAsSourceDocument">Source</a>]</p> | |||
|
|||
<p> | |||
<span about="" id="server-patch-not-other" rel="spec:requirement" resource="#server-patch-not-other"><span property="spec:statement"><span rel="spec:requirementSubject" resource="spec:Server">Servers</span> <span rel="spec:requirementLevel" resource="spec:MUST-NOT">MUST NOT</span> allow a client to explicitly request multi-resource changes via the <code>PATCH</code> method, but the server is permitted to propagate side-effects of a change to the target resource to other resources.</span></span> [<a href="https://github.com/solid/specification/issues/125#issuecomment-873035679" rel="cito:citesAsSourceDocument">Source</a>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR title and the first comment is clear to me. But I don't quite understand the way the requirement reads.
The first sentence seems as though it is the payload that will 1) attempt to change different resources 2) besides the request's target resource. And then it says "but" it can propagate the changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but the server is permitted to propagate side-effects of a change to the target resource to other resources.
I think this bit provides more confusion than clarity. If there are explicit allowed and/or expected side-effects that aren't covered elsewhere in the specification those should be mentioned. For example, if a patch is used to create the target resource R in container P, containment information in P is affected, but that is covered elsewhere in the spec, so it wouldn't need to be mentioned. Are there some specific side-effects we want to address here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that I can think of. @RubenVerborgh , would you be OK to revert to the previous commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's correct then, but happy to abstain from voting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RubenVerborgh I think the idea is that your concerns are addressed with my generic language elsewhere in the spec. I tend to agree that the last commits are more explicit and is thus clearer. But I also see the point of @csarven and @justinwb , containment triples are dealt with elsewhere, and so, the fact that PATCH
can create a resource and thus have the side effect of adding a containment triple, doesn't need to be mentioned here. That some changes to a resource will also have a the side-effect of updating timestamps are also defined elsewhere, again, it doesn't need to be mentioned here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are mentioned in other places, but this statement creates a contradiction with those other places. Whereas the only intention here was to say "PATCH targets one resource".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear: my review comment above was about the soundness of the statements in the PR. No judgement on the solution until the statements are clarified.
#349 (comment) is the suggestion to make the request semantics more clear and what happens when applied to the target resource.
For example, if the payload of the PATCH were to result in deleting resources besides the resource that's same as the effective request URI, then those are part of the semantics of PATCH with a particular media type. That is not a "side effect". It is part of processing the request. "Side effects" may indeed be things like changes to containment when a resource is created with PATCH; server creating a memento resource of the target resource; adding/tracking creator of the resource; associating an ACL resource and a description resource with the created resource; updating authoritative information, and so on.
Kjetil, I only mentioned containment as a simple example to you in private and later in the editors meeting ( https://github.com/solid/specification/blob/main/meetings/2021-11-24.md#constraint-on-patch-to-target-resource ) . I think Justin understood and agreed with my point in the meeting and repeating it here because you asked him to leave a comment.
Ruben, I'd like to know what potential conflicts you are referring to and how to avoid them. Or are we talking passed each other?
I think we are in agreement with the intention re "PATCH targets one resource" and "the update should only change the description of the target resource", right?
PATCH /foo
INSERT DATA foo bar baz
INSERT DATA qux bar baz
DELETE DATA quux bar baz
INSERT DATA quuz bar baz
That only needs to be processed to update the description of the resource foo. It should not update the descriptions of the resources qux, quux, quuz (in their respective resource descriptions - external to foo) or create resources qux and quux if they happen to not exist or any of the example side effects mentioned above. If we want those things, they should be incorporated into the semantics of the request, case by case. Later on.
We shouldn't spend more time on dissecting the current requirement which is problematic and not really want we want. Kjetil, can you update?
The update should only change the description of the target resource. Don't mention propagations or side-effects until the request semantics can be further specialised. |
I'm fine with that, since that is what I originally did, but then @RubenVerborgh wanted some specific language to address that. I'm fine either way. Perhaps we haven't got enough on side-effects in the spec, perhaps we should have a section about that that we can refer to in such cases. Meanwhile, I think we could merge it as it is now, and do that for 1.0. |
@@ -708,6 +708,11 @@ <h3 property="schema:name">Writing Resources</h3> | |||
|
|||
<p><span about="" id="server-protect-containment" rel="spec:requirement" resource="#server-protect-containment"><span property="spec:statement"><span rel="spec:requirementSubject" resource="spec:Server">Servers</span> <span rel="spec:requirementLevel" resource="spec:MUST">MUST</span> NOT allow HTTP <code>POST</code>, <code>PUT</code> and <code>PATCH</code> to update a container’s containment triples; if the server receives such a request, it <span rel="spec:requirementLevel" resource="spec:MUST">MUST</span> respond with a <code>409</code> status code.</span></span> [<a href="https://github.com/solid/specification/issues/40#issuecomment-573358652" rel="cito:citesAsSourceDocument">Source</a>]</p> | |||
|
|||
<p> | |||
<span about="" id="server-patch-not-other" rel="spec:requirement" resource="#server-patch-not-other"><span property="spec:statement"><span rel="spec:requirementSubject" resource="spec:Server">Servers</span> <span rel="spec:requirementLevel" resource="spec:MUST-NOT">MUST NOT</span> allow a client to explicitly request multi-resource changes via the <code>PATCH</code> method, but the server is permitted to propagate side-effects of a change to the target resource to other resources.</span></span> [<a href="https://github.com/solid/specification/issues/125#issuecomment-873035679" rel="cito:citesAsSourceDocument">Source</a>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a bit of rephrasing will help matters? I've linked to a relevant DBpedia resource, but that could be changed however the Editors deem appropriate.
<span about="" id="server-patch-not-other" rel="spec:requirement" resource="#server-patch-not-other"><span property="spec:statement"><span rel="spec:requirementSubject" resource="spec:Server">Servers</span> <span rel="spec:requirementLevel" resource="spec:MUST-NOT">MUST NOT</span> allow a client to explicitly request multi-resource changes via the <code>PATCH</code> method, but the server is permitted to propagate side-effects of a change to the target resource to other resources.</span></span> [<a href="https://github.com/solid/specification/issues/125#issuecomment-873035679" rel="cito:citesAsSourceDocument">Source</a>] | |
<span about="" id="server-patch-not-other" rel="spec:requirement" resource="#server-patch-not-other"><span property="spec:statement"><span rel="spec:requirementSubject" resource="spec:Server">Servers</span> <span rel="spec:requirementLevel" resource="spec:MUST-NOT">MUST NOT</span> allow a client request to explicitly change multiple resources via the <code>PATCH</code> method. However, a <code>PATCH</code> method request that explicitly changes one resource <span rel="spec:requirementLevel" resource="spec:MAY">MAY</span> cause the server to change one or more other resources as a side-effect of the explicitly requested change (akin to a <a href="http://dbpedia.org/resource/Database_trigger">`TRIGGER` firing in a SQL DBMS</a>).</span></span> [<a href="https://github.com/solid/specification/issues/125#issuecomment-873035679" rel="cito:citesAsSourceDocument">Source</a>] |
I'll remove this from the current milestone so that we can wordsmith this into shape at some later point. We need to finish 0.9 urgently. |
The It would be faster if all the requests could be combined in a more complex PATCH which patches more than one resource. And great is atomicity were an option too. So this issue is not in the spirit of going into th multiple resource patch would be an enhancement. |
See Road map item "Atomic multi-file updates" |
I absolutely see multi-resource patches as desirable, and atomic ones important too. The question is whether that should be going through this kind of interface. My concern is that users may be duped by apps, possibly because the app has a vulnerability, to modify a resource they didn't intend to modify. I'd like to plug that possible hole at the protocol level. To support multi-resource updates in a single request, I don't think a resource-centric interface makes sense, it is not a single resource anyway. In that case, thinking in terms of endpoints (e.g. a SPARQL endpoint) makes much sense, and I suppose you could do this already using the SPARQL Protocol. |
Another concern is that if authorization always depends on the body of the message, then parsing the body and checking for other possible targets is a cost that must be paid by every Currently, we don't have a cheap method for append (though see #305 for a proposal to fix that), so even the simplest append operation will have this cost. It will also complicate caching on intermediaries as it implies that any resource might change based on any PATCH request (in contrast with just parent container and aux resources belonging to the resource), and so, implementations would need a mechanism to invalidate the cache for any resource. This suggests to me that if we are going to have multi-resource operations, it ought to be on a different interface (an endpoint-oriented one), and we should only do it once we have adverse side effects under control. |
Even if SPARQL isn't specified in 0.9, we should add some of the constraints that we agreed on in that context. The constraint that
PATCH
should only modify the target resource is a sound constraint that I think should go in. This text is mostly derived from earlier PRs, but generalized to any media type (which I guess is a good idea anyway).