diff --git a/ingest/views.py b/ingest/views.py index 47e675d..1e354e8 100644 --- a/ingest/views.py +++ b/ingest/views.py @@ -1,11 +1,13 @@ import json # TODO consider faster APIs +from urllib.parse import urlparse from rest_framework import permissions, status from rest_framework.response import Response from rest_framework.views import APIView +from rest_framework import exceptions # from projects.models import Project -# from sentry.utils.auth import parse_auth_header +from sentry.utils.auth import parse_auth_header from projects.models import Project from issues.models import Issue @@ -23,6 +25,29 @@ class BaseIngestAPIView(APIView): content_negotiation_class = IgnoreClientContentNegotiation http_method_names = ["post"] + @classmethod + def auth_from_request(cls, request): + # VENDORED FROM GlitchTip at a4f33da8d4e759d61ffe073a00f2bb3839ac65f5 + # Accept both sentry or glitchtip prefix. + for k in request.GET.keys(): + if k in ["sentry_key", "glitchtip_key"]: + return request.GET[k] + + if auth_header := request.META.get( + "HTTP_X_SENTRY_AUTH", request.META.get("HTTP_AUTHORIZATION") + ): + result = parse_auth_header(auth_header) + return result.get("sentry_key", result.get("glitchtip_key")) + + if isinstance(request.data, list): + if data_first := next(iter(request.data), None): + if isinstance(data_first, dict): + dsn = urlparse(data_first.get("dsn")) + if username := dsn.username: + return username + + raise exceptions.NotAuthenticated("Unable to find authentication information") + def process_event(self, event_data, request, project): event = DecompressedEvent.objects.create( project=project, diff --git a/sentry/utils/auth.py b/sentry/utils/auth.py new file mode 100644 index 0000000..0464d7f --- /dev/null +++ b/sentry/utils/auth.py @@ -0,0 +1,11 @@ +def _make_key_value(val): + return val.strip().split("=", 1) + + +def parse_auth_header(header): + if isinstance(header, bytes): + header = header.decode("latin1") + try: + return dict(map(_make_key_value, header.split(" ", 1)[1].split(","))) + except Exception: + return {}