fix: don't send callback request if data has been modified

This commit is contained in:
imperosol
2026-07-15 16:28:05 +02:00
parent 7c66fffbfb
commit 1640742ce2
2 changed files with 17 additions and 11 deletions
+12 -6
View File
@@ -47,14 +47,15 @@ class TestThirdPartyAuth(TestCase):
self.callback_data["signature"] = hmac_hexdigest( self.callback_data["signature"] = hmac_hexdigest(
self.api_client.hmac_key, self.callback_data["user"] self.api_client.hmac_key, self.callback_data["user"]
) )
self.url = reverse("api-link:third-party-auth", query=self.query)
def test_auth_ok(self): def test_auth_ok(self):
self.client.force_login(self.user) self.client.force_login(self.user)
res = self.client.get(reverse("api-link:third-party-auth", query=self.query)) res = self.client.get(self.url)
assert res.status_code == 200 assert res.status_code == 200
with mock.patch("requests.post", new_callable=mocked_post(ok=True)) as mocked: with mock.patch("requests.post", new_callable=mocked_post(ok=True)) as mocked:
res = self.client.post( res = self.client.post(
reverse("api-link:third-party-auth"), self.url,
data={"cgu_accepted": True, "is_username_valid": True, **self.query}, data={"cgu_accepted": True, "is_username_valid": True, **self.query},
) )
mocked.assert_called_once_with( mocked.assert_called_once_with(
@@ -70,7 +71,7 @@ class TestThirdPartyAuth(TestCase):
self.client.force_login(self.user) self.client.force_login(self.user)
with mock.patch("requests.post", new_callable=mocked_post(ok=False)) as mocked: with mock.patch("requests.post", new_callable=mocked_post(ok=False)) as mocked:
res = self.client.post( res = self.client.post(
reverse("api-link:third-party-auth"), self.url,
data={"cgu_accepted": True, "is_username_valid": True, **self.query}, data={"cgu_accepted": True, "is_username_valid": True, **self.query},
) )
mocked.assert_called_once_with( mocked.assert_called_once_with(
@@ -98,14 +99,17 @@ class TestThirdPartyAuth(TestCase):
) )
] ]
res = self.client.post(self.url, data=self.query)
assert res.status_code == 200
def test_cgu_not_accepted(self): def test_cgu_not_accepted(self):
self.client.force_login(self.user) self.client.force_login(self.user)
res = self.client.get(reverse("api-link:third-party-auth", query=self.query)) res = self.client.get(self.url)
assert res.status_code == 200 assert res.status_code == 200
res = self.client.post(reverse("api-link:third-party-auth"), data=self.query) res = self.client.post(self.url, data=self.query)
assert res.status_code == 200 # no redirect means invalid form assert res.status_code == 200 # no redirect means invalid form
res = self.client.post( res = self.client.post(
reverse("api-link:third-party-auth"), self.url,
data={"cgu_accepted": False, "is_username_valid": False, **self.query}, data={"cgu_accepted": False, "is_username_valid": False, **self.query},
) )
assert res.status_code == 200 assert res.status_code == 200
@@ -132,3 +136,5 @@ class TestThirdPartyAuth(TestCase):
message="Les données fournies pour l'authentification sont incorrectes.", message="Les données fournies pour l'authentification sont incorrectes.",
) )
] ]
res = self.client.post(self.url, data=self.query)
assert res.status_code == 200
+5 -5
View File
@@ -39,8 +39,8 @@ class ThirdPartyAuthView(AccessMixin, FormView):
# the given parameters and their signature are checked during both # the given parameters and their signature are checked during both
# POST (for obvious reasons) and GET (in order not to make # POST (for obvious reasons) and GET (in order not to make
# the user fill a form just to get an error he won't understand) # the user fill a form just to get an error he won't understand)
params = self.request.GET or self.request.POST params = self.request.GET if self.request.method == "GET" else self.request.POST
params = {key: unquote(val) for key, val in params.items()} params = {key: unquote(val) for key, val in params.dict().items()}
try: try:
params = ThirdPartyAuthParamsSchema(**params) params = ThirdPartyAuthParamsSchema(**params)
except pydantic.ValidationError: except pydantic.ValidationError:
@@ -48,7 +48,7 @@ class ThirdPartyAuthView(AccessMixin, FormView):
self.request, _("The data provided for authentication is incorrect") self.request, _("The data provided for authentication is incorrect")
) )
return None return None
client: ApiClient = get_object_or_none(ApiClient, id=params.client_id) client: ApiClient | None = get_object_or_none(ApiClient, id=params.client_id)
if not client: if not client:
messages.error( messages.error(
self.request, _("The data provided for authentication is incorrect") self.request, _("The data provided for authentication is incorrect")
@@ -71,11 +71,11 @@ class ThirdPartyAuthView(AccessMixin, FormView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated: if not request.user.is_authenticated:
return self.handle_no_permission() return self.handle_no_permission()
self.params = self.parse_params() if (params := self.parse_params()) is None:
if not self.params:
# if parameters parsing failed, shortcut the operation and display # if parameters parsing failed, shortcut the operation and display
# an empty page with just the error messages. # an empty page with just the error messages.
return render(request, "core/base.jinja") return render(request, "core/base.jinja")
self.params = params
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def get(self, *args, **kwargs): def get(self, *args, **kwargs):