Skip to content

Commit

Permalink
job_seekers_views: ensure we perform the action the session was creat…
Browse files Browse the repository at this point in the history
…ed for

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.
  • Loading branch information
EwenKorr committed Jan 8, 2025
1 parent 55849a0 commit 5c9b3d4
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
14 changes: 13 additions & 1 deletion itou/www/job_seekers_views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ def get_queryset(self):


class JobSeekerBaseView(TemplateView):
EXPECTED_SESSION_KIND = None

def __init__(self):
super().__init__()
self.company = None
Expand All @@ -198,6 +200,11 @@ def setup(self, request, *args, session_uuid, hire_process=False, **kwargs):
self.job_seeker_session = SessionNamespace(request.session, session_uuid)
if not self.job_seeker_session.exists():
raise Http404
# Ensure we are performing the action (update, create…) the session was created for.
if (
session_kind := self.job_seeker_session.get("config").get("session_kind")
) and session_kind != self.EXPECTED_SESSION_KIND:
raise Http404
self.is_gps = "gps" in request.GET and request.GET["gps"] == "true"
if company_pk := self.job_seeker_session.get("apply", {}).get("company_pk"):
self.company = (
Expand Down Expand Up @@ -269,6 +276,7 @@ def dispatch(self, request, *args, **kwargs):

class CheckNIRForJobSeekerView(JobSeekerBaseView):
template_name = "job_seekers_views/step_check_job_seeker_nir.html"
EXPECTED_SESSION_KIND = "job-seeker-get-or-create-job-seeker"

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -328,6 +336,7 @@ def get_context_data(self, **kwargs):

class CheckNIRForSenderView(JobSeekerForSenderBaseView):
template_name = "job_seekers_views/step_check_job_seeker_nir.html"
EXPECTED_SESSION_KIND = "job-seeker-get-or-create-sender"

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -779,7 +788,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, "session_kind": "job-seeker-update"},
"job_seeker_pk": job_seeker.pk,
"apply": {"company_pk": company.pk},
},
Expand All @@ -794,6 +803,8 @@ def get(self, request, *args, **kwargs):


class UpdateJobSeekerBaseView(JobSeekerBaseView):
EXPECTED_SESSION_KIND = "job-seeker-update"

def __init__(self):
super().__init__()
self.job_seeker_session = None
Expand All @@ -803,6 +814,7 @@ def get_job_seeker_queryset(self):

def setup(self, request, *args, **kwargs):
super().setup(request, *args, **kwargs)

self.job_seeker = get_object_or_404(
self.get_job_seeker_queryset(), pk=self.job_seeker_session.get("job_seeker_pk")
)
Expand Down
2 changes: 1 addition & 1 deletion tests/www/apply/test_submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -3480,7 +3480,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, "session_kind": "job-seeker-update"},
"job_seeker_pk": self.job_seeker.pk,
}
self.step_1_url = reverse(
Expand Down
26 changes: 26 additions & 0 deletions tests/www/job_seekers_views/test_create_or_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"), "session_kind": "job-seeker-get-or-create-sender"},
"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()
Expand Down

0 comments on commit 5c9b3d4

Please sign in to comment.