From 46810fe403b943b6be10e096286a0f882141ea77 Mon Sep 17 00:00:00 2001 From: Ewen Corre Date: Mon, 6 Jan 2025 15:52:12 +0100 Subject: [PATCH] job_seekers_views: add a `tunnel` key to the session When initializing the job_seeker_session, we set a `tunnel` key to determine which action will be performed in the job_seekers_views block with that session (here, `job-seeker-update`). This is to prevent a (malicious) user from playing with session, and using a session that was not intended for updating a job seeker to do so. --- itou/www/job_seekers_views/views.py | 7 ++++- tests/www/apply/test_submit.py | 2 +- .../test_create_or_update.py | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/itou/www/job_seekers_views/views.py b/itou/www/job_seekers_views/views.py index e953223e4f..8c4b064f6f 100644 --- a/itou/www/job_seekers_views/views.py +++ b/itou/www/job_seekers_views/views.py @@ -785,7 +785,7 @@ def setup(self, request, *args, **kwargs): self.job_seeker_session = SessionNamespace.create_uuid_namespace( request.session, data={ - "config": {"from_url": from_url}, + "config": {"from_url": from_url, "tunnel": "job-seeker-update"}, "job_seeker_pk": job_seeker.pk, "apply": {"company_pk": company.pk}, }, @@ -809,6 +809,11 @@ def get_job_seeker_queryset(self): def setup(self, request, *args, **kwargs): super().setup(request, *args, **kwargs) + + # Check that the session was initialized to update a job seeker. + if self.job_seeker_session.get("config").get("tunnel") != "job-seeker-update": + raise Http404 + self.job_seeker = get_object_or_404( self.get_job_seeker_queryset(), pk=self.job_seeker_session.get("job_seeker_pk") ) diff --git a/tests/www/apply/test_submit.py b/tests/www/apply/test_submit.py index 5c8b433f1f..edc7f889bb 100644 --- a/tests/www/apply/test_submit.py +++ b/tests/www/apply/test_submit.py @@ -3481,7 +3481,7 @@ def setup_method(self, settings, mocker): ) self.config = { "apply": {"company_pk": self.company.pk}, - "config": {"from_url": from_url}, + "config": {"from_url": from_url, "tunnel": "job-seeker-update"}, "job_seeker_pk": self.job_seeker.pk, } self.step_1_url = reverse( diff --git a/tests/www/job_seekers_views/test_create_or_update.py b/tests/www/job_seekers_views/test_create_or_update.py index 35f390ebfe..c54ae92700 100644 --- a/tests/www/job_seekers_views/test_create_or_update.py +++ b/tests/www/job_seekers_views/test_create_or_update.py @@ -7,8 +7,10 @@ from itou.asp.models import Commune, Country from itou.users.enums import Title +from itou.utils.session import SessionNamespace from itou.utils.urls import add_url_params from tests.companies.factories import CompanyFactory +from tests.prescribers.factories import PrescriberOrganizationWithMembershipFactory from tests.users.factories import JobSeekerFactory from tests.utils.test import KNOWN_SESSION_KEYS @@ -190,6 +192,30 @@ def test_birth_country_france_and_no_birthplace(self, client): ) +class TestUpdateJobSeeker: + def test_update_with_wrong_tunnel_in_session(self, client): + job_seeker = JobSeekerFactory() + company = CompanyFactory(with_membership=True) + prescriber = PrescriberOrganizationWithMembershipFactory(authorized=True).members.first() + client.force_login(prescriber) + + # Create a session with a wrong tunnel key + job_seeker_session = SessionNamespace.create_uuid_namespace( + client.session, + data={ + "config": {"from_url": reverse("dashboard:index"), "tunnel": "job-seeker-create"}, + "job_seeker_pk": job_seeker.pk, + "apply": {"company_pk": company.pk}, + }, + ) + job_seeker_session.save() + + url = reverse("job_seekers_views:update_job_seeker_step_1", kwargs={"session_uuid": job_seeker_session.name}) + response = client.get(url) + + assert response.status_code == 404 + + class TestUpdateJobSeekerStart: def test_update_start_with_valid_parameters(self, client): job_seeker = JobSeekerFactory()