Skip to content

Commit af8e9cd

Browse files
committed
fix: don't send callback request if data has been modified
1 parent 90adb9e commit af8e9cd

2 files changed

Lines changed: 17 additions & 11 deletions

File tree

api/tests/test_third_party_auth.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,15 @@ def setUp(self):
4747
self.callback_data["signature"] = hmac_hexdigest(
4848
self.api_client.hmac_key, self.callback_data["user"]
4949
)
50+
self.url = reverse("api-link:third-party-auth", query=self.query)
5051

5152
def test_auth_ok(self):
5253
self.client.force_login(self.user)
53-
res = self.client.get(reverse("api-link:third-party-auth", query=self.query))
54+
res = self.client.get(self.url)
5455
assert res.status_code == 200
5556
with mock.patch("requests.post", new_callable=mocked_post(ok=True)) as mocked:
5657
res = self.client.post(
57-
reverse("api-link:third-party-auth"),
58+
self.url,
5859
data={"cgu_accepted": True, "is_username_valid": True, **self.query},
5960
)
6061
mocked.assert_called_once_with(
@@ -70,7 +71,7 @@ def test_callback_error(self):
7071
self.client.force_login(self.user)
7172
with mock.patch("requests.post", new_callable=mocked_post(ok=False)) as mocked:
7273
res = self.client.post(
73-
reverse("api-link:third-party-auth"),
74+
self.url,
7475
data={"cgu_accepted": True, "is_username_valid": True, **self.query},
7576
)
7677
mocked.assert_called_once_with(
@@ -98,14 +99,17 @@ def test_wrong_signature(self):
9899
)
99100
]
100101

102+
res = self.client.post(self.url, data=self.query)
103+
assert res.status_code == 200
104+
101105
def test_cgu_not_accepted(self):
102106
self.client.force_login(self.user)
103-
res = self.client.get(reverse("api-link:third-party-auth", query=self.query))
107+
res = self.client.get(self.url)
104108
assert res.status_code == 200
105-
res = self.client.post(reverse("api-link:third-party-auth"), data=self.query)
109+
res = self.client.post(self.url, data=self.query)
106110
assert res.status_code == 200 # no redirect means invalid form
107111
res = self.client.post(
108-
reverse("api-link:third-party-auth"),
112+
self.url,
109113
data={"cgu_accepted": False, "is_username_valid": False, **self.query},
110114
)
111115
assert res.status_code == 200
@@ -132,3 +136,5 @@ def test_missing_parameter(self):
132136
message="Les données fournies pour l'authentification sont incorrectes.",
133137
)
134138
]
139+
res = self.client.post(self.url, data=self.query)
140+
assert res.status_code == 200

api/views.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ def parse_params(self) -> ThirdPartyAuthParamsSchema | None:
3939
# the given parameters and their signature are checked during both
4040
# POST (for obvious reasons) and GET (in order not to make
4141
# the user fill a form just to get an error he won't understand)
42-
params = self.request.GET or self.request.POST
43-
params = {key: unquote(val) for key, val in params.items()}
42+
params = self.request.GET if self.request.method == "GET" else self.request.POST
43+
params = {key: unquote(val) for key, val in params.dict().items()}
4444
try:
4545
params = ThirdPartyAuthParamsSchema(**params)
4646
except pydantic.ValidationError:
4747
messages.error(
4848
self.request, _("The data provided for authentication is incorrect")
4949
)
5050
return None
51-
client: ApiClient = get_object_or_none(ApiClient, id=params.client_id)
51+
client: ApiClient | None = get_object_or_none(ApiClient, id=params.client_id)
5252
if not client:
5353
messages.error(
5454
self.request, _("The data provided for authentication is incorrect")
@@ -71,11 +71,11 @@ def parse_params(self) -> ThirdPartyAuthParamsSchema | None:
7171
def dispatch(self, request, *args, **kwargs):
7272
if not request.user.is_authenticated:
7373
return self.handle_no_permission()
74-
self.params = self.parse_params()
75-
if not self.params:
74+
if (params := self.parse_params()) is None:
7675
# if parameters parsing failed, shortcut the operation and display
7776
# an empty page with just the error messages.
7877
return render(request, "core/base.jinja")
78+
self.params = params
7979
return super().dispatch(request, *args, **kwargs)
8080

8181
def get(self, *args, **kwargs):

0 commit comments

Comments
 (0)