Skip to content

Commit 6b62a57

Browse files
committed
apply review comments
1 parent 876b6d3 commit 6b62a57

1 file changed

Lines changed: 37 additions & 10 deletions

File tree

api/views.py

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
import pydantic
55
import requests
6+
import sentry_sdk
67
from django.conf import settings
78
from django.contrib import messages
89
from django.contrib.auth.mixins import LoginRequiredMixin
9-
from django.core.exceptions import PermissionDenied
10+
from django.shortcuts import render
1011
from django.urls import reverse, reverse_lazy
1112
from django.utils.translation import gettext as _
1213
from django.views.generic import FormView, TemplateView
@@ -25,11 +26,14 @@ class ThirdPartyAuthView(LoginRequiredMixin, FormView):
2526
template_name = "api/third_party/auth.jinja"
2627
success_url = reverse_lazy("core:index")
2728

28-
def parse_params(self) -> ThirdPartyAuthParamsSchema:
29+
def parse_params(self) -> ThirdPartyAuthParamsSchema | None:
2930
"""Parse and check the authentication parameters.
3031
31-
Raises:
32-
PermissionDenied: if the verification failed.
32+
If parsing fails, messages will be created using the django message
33+
infrastructure.
34+
35+
Returns:
36+
The parses parameters, or None if the parsing failed.
3337
"""
3438
# This is here rather than in ThirdPartyAuthForm because
3539
# the given parameters and their signature are checked during both
@@ -39,20 +43,39 @@ def parse_params(self) -> ThirdPartyAuthParamsSchema:
3943
params = {key: unquote(val) for key, val in params.items()}
4044
try:
4145
params = ThirdPartyAuthParamsSchema(**params)
42-
except pydantic.ValidationError as e:
43-
raise PermissionDenied("Wrong data format") from e
46+
except pydantic.ValidationError:
47+
messages.error(
48+
self.request, _("The data provided for authentication is incorrect")
49+
)
50+
return None
4451
client: ApiClient = get_object_or_none(ApiClient, id=params.client_id)
4552
if not client:
46-
raise PermissionDenied
53+
messages.error(
54+
self.request, _("The data provided for authentication is incorrect")
55+
)
56+
return None
4757
if not hmac.compare_digest(
4858
hmac_hexdigest(client.hmac_key, params.model_dump(exclude={"signature"})),
4959
params.signature,
5060
):
51-
raise PermissionDenied("Bad signature")
61+
messages.error(
62+
self.request,
63+
_(
64+
"The signature is incorrect. "
65+
"We cannot ensure the provenance of the request."
66+
),
67+
)
68+
return None
5269
return params
5370

5471
def dispatch(self, request, *args, **kwargs):
5572
self.params = self.parse_params()
73+
if not self.params:
74+
# if parameters parsing failed, shortcut the operation and display
75+
# an empty page with just the error messages.
76+
if not request.user.is_authenticated:
77+
return self.handle_no_permission()
78+
return render(request, "core/base.jinja")
5679
return super().dispatch(request, *args, **kwargs)
5780

5881
def get(self, *args, **kwargs):
@@ -73,10 +96,14 @@ def form_valid(self, form):
7396
client = ApiClient.objects.get(id=form.cleaned_data["client_id"])
7497
user = UserProfileSchema.from_orm(self.request.user).model_dump()
7598
data = {"user": user, "signature": hmac_hexdigest(client.hmac_key, user)}
76-
response = requests.post(form.cleaned_data["callback_url"], json=data)
99+
try:
100+
ok = requests.post(form.cleaned_data["callback_url"], json=data).ok
101+
except requests.RequestException as e:
102+
sentry_sdk.capture_exception(e)
103+
ok = False
77104
self.success_url = reverse(
78105
"api-link:third-party-auth-result",
79-
kwargs={"result": "success" if response.ok else "failure"},
106+
kwargs={"result": "success" if ok else "failure"},
80107
)
81108
return super().form_valid(form)
82109

0 commit comments

Comments
 (0)