-
Notifications
You must be signed in to change notification settings - Fork 26
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
✨ [#4398] Check object ownership when creating submission #4696
base: master
Are you sure you want to change the base?
✨ [#4398] Check object ownership when creating submission #4696
Conversation
8e700b5
to
7891ead
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4696 +/- ##
==========================================
+ Coverage 96.57% 96.58% +0.01%
==========================================
Files 747 748 +1
Lines 25400 25487 +87
Branches 3355 3366 +11
==========================================
+ Hits 24529 24616 +87
Misses 608 608
Partials 263 263 ☔ View full report in Codecov by Sentry. |
7891ead
to
18dc4e6
Compare
18dc4e6
to
ac6305a
Compare
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 think this is happening at the wrong place with the wrong assumptions 😬
For starters, session[FORM_AUTH_SESSION_KEY]
should not be relied on - ideally once the submission is created/started, this should be cleaned from the session data entirely since we have a hook/signal that records it on the submission itself.
Second - we should always pass a submission
instance when performing this kind of validation, exactly because different credentials could apply to a submission vs. what's in the session (the session data is a data race, since you can have different authentication details there compared to a submission that is also still in your session, for example when you are filling out two forms at the same time with different login options).
I think the prefill plugin itself should perform this access control, since:
- in
submissions.api.viewsets.SubmissionViewSet.perform_create
we dispatch the submission start signal, that ensures we have the auth details stored - after that, we call
prefill_variables
, which receives thesubmission
instance and passes it to the plugin - inside the plugin, you should be able to
raise PermissionDenied
if anything is fishy - if that exception is raised, it should bubble up to the API endpoint, will result in an HTTP 403 and the DB transaction should be rolled back so that the submission record is never persisted in the database
I'm afraid that makes this PR/ticket depend on #4620 then 🤔
55dc86e
to
84e00ce
Compare
@sergei-maertens it was mentioned in #4721 that the mechanism to pass |
uh... right. I'll have to think about that 😅 |
@sergei-maertens maybe there should be some kind of hook in |
@stevenbal I still don't see a simple/elegant way to do this, especially because data can be mutated externally and be outdated. E.g., if you verify it at I'm kind of leaning towards implementing the permission check itself once in It's again a case of two different systems doing very similar things, but that doesn't make them the same. The prefill mapping and registration mapping are technically independent from each other too, we'll just offer convenience UI options to use one as a source for the other, but in the backend, they don't know of each other's existence and that's fine. The meaning of Perhaps for registration plugins we define a new hook on the base plugin which raises |
@sergei-maertens that sound like a good idea, I'll see if I can implement this |
52daf64
to
ca09bd7
Compare
) | ||
return | ||
|
||
# TODO should this path be configurable? |
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.
yes
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.
What is the right place to configure this, should it be on both registration backend and prefill options? I don't know if there is a way around that, since I think it could be possible to use one without the other
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.
Yeah indeed, and the UI copy button is then the convenience so that users can setup prefill from their registration configuration
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've added a TODO in the PR to add the field to the prefill config form as well (since this is probably reliant on #4799)
e40cc35
to
86abe7b
Compare
86abe7b
to
fc53ad1
Compare
@@ -349,6 +357,16 @@ def validate(self, attrs: RegistrationOptions) -> RegistrationOptions: | |||
{"version": _("Unknown version: {version}").format(version=version)} | |||
) | |||
|
|||
if attrs.get("update_existing_object") and not attrs.get("auth_attribute_path"): |
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.
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.
you should be able to set up the necesary frontend state & reproduce this problem in storybook! might be that we don't have validation error display hooked up into this arrayfield (?) yet
fc53ad1
to
4fbbd10
Compare
the initial data reference is passed from the SDK to the backend as part of the login URL. In order to pass it as part of the submission create body, it must be propagated from the authentication start/return views back to the SDK
if initial_data_reference is specified, Prefill plugins will verify ownership before attempting to prefill and registration plugins will do the same during pre registration
if the object could not be fetched for whatever reason, no longer raise a PermissionDenied, because we could not explicitly verify that the user is not the owner of the object. This is needed because in case of multiple prefill/registration backends, only one of them will actually contain the object, so we do not want to break the form due to 404 errors in the others
* move initial_data_reference ownership check to separate file * change `validate_object_ownership` signature to accept an ObjectsClient and create the client in the calling code
it is no longer needed because the query parameter is now added to the nextUrl via the SDK
and raise errors if the plugin options is missing `auth_attribute_path`
…hip check previously this looped over possible backends, but at the time of executing the `verify_initial_data_ownership` check, the registration_backend that is to be used is already known
… True this field is necessary to perform the initial data reference ownership check, which is performed when updating existing objects
4fbbd10
to
15203ce
Compare
Closes #4398
TODO:
Changes
Checklist
Check off the items that are completed or not relevant.
Impact on features
Release management
I have updated the translations assets (you do NOT need to provide translations)
./bin/makemessages_js.sh
./bin/compilemessages_js.sh
Commit hygiene