Skip to content

Commit

Permalink
✨ [#4320] Implement shortcut flow for cosign verification
Browse files Browse the repository at this point in the history
If the code querystring parameter is provided, perform the form validation
in the GET request rather than requiring the user to fill out the form,
and automatically redirect back to the frontend to do the cosigning.

There is a minor risk for CSRF here, *if* the attacker is able to
guess the submission reference + form combination and the victim
has an active, authenticated session. Note that the session idle
time is capped at 15 minutes, so the risk is considered not
problematic.
  • Loading branch information
sergei-maertens committed Nov 12, 2024
1 parent e3ab079 commit 499e0d8
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
45 changes: 45 additions & 0 deletions src/openforms/submissions/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,51 @@ def test_successfully_submit_form(self):
fetch_redirect_response=False,
)

def test_successfully_resolve_code_from_GET_params(self):
submission = SubmissionFactory.from_components(
form__authentication_backends=["digid"],
components_list=[
{
"key": "cosign",
"type": "cosign",
"label": "Cosign component",
"validate": {"required": True},
},
],
submitted_data={"cosign": "test@test.nl"},
completed=True,
cosign_complete=False,
form__slug="form-to-cosign",
form_url="http://url-to-form.nl/startpagina",
public_registration_reference="OF-IMAREFERENCE",
)
session = self.app.session
session[FORM_AUTH_SESSION_KEY] = {
"plugin": "digid",
"attribute": "bsn",
"value": "123456782",
"loa": DIGID_DEFAULT_LOA,
}
session.save()

response = self.app.get(
reverse(
"submissions:find-submission-for-cosign",
kwargs={"form_slug": "form-to-cosign"},
),
{"code": submission.public_registration_reference},
)

self.assertRedirectsToFrontend(
response,
frontend_base_url="http://url-to-form.nl/",
action="cosign",
action_params={
"submission_uuid": str(submission.uuid),
},
fetch_redirect_response=False,
)

def test_user_no_auth_details_in_session(self):
SubmissionFactory.from_components(
components_list=[
Expand Down
17 changes: 15 additions & 2 deletions src/openforms/submissions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class SearchSubmissionForCosignFormView(UserPassesTestMixin, FormView):
raise_exception = True

form = None
submission = None
submission: Submission | None = None

def test_func(self):
"""
Expand All @@ -311,17 +311,30 @@ def test_func(self):
self.request, self.form.authentication_backend_options
)

def get(self, request: HttpRequest, *args, **kwargs):
# If we have a code param in the query string, apply the shortcuts and skip
# the actual lookup screen - the code is already provided in the URL
if request.GET.get("code"):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
return super().get(request, *args, **kwargs)

def get_form_kwargs(self):
super_kwargs = super().get_form_kwargs()
super_kwargs["instance"] = self.form
if code := self.request.GET.get("code"):
super_kwargs["data"] = {"code": code}
return super_kwargs

def form_valid(self, form):
def form_valid(self, form: SearchSubmissionForCosignForm):
self.submission = form.cleaned_data["submission"]
assert self.submission
add_submmission_to_session(self.submission, self.request.session)
return super().form_valid(form)

def get_success_url(self):
assert self.submission
return get_frontend_redirect_url(
self.submission,
action="cosign",
Expand Down

0 comments on commit 499e0d8

Please sign in to comment.