David Burke 1 year ago
parent
commit
8f867e9397

+ 1 - 0
glitchtip/api/__init__.py

@@ -0,0 +1 @@
+from .api import api

+ 110 - 0
glitchtip/api/api.py

@@ -0,0 +1,110 @@
+from typing import Optional
+
+from allauth.socialaccount.models import SocialApp
+from allauth.socialaccount.providers.openid_connect.views import OpenIDConnectAdapter
+from django.http import HttpRequest
+from django.conf import settings
+from ninja import NinjaAPI, ModelSchema, Schema
+from glitchtip.constants import SOCIAL_ADAPTER_MAP
+from users.utils import ais_user_registration_open
+
+from .exceptions import ThrottleException
+from .parsers import EnvelopeParser
+from .renderers import ORJSONRenderer
+from .schema import CamelSchema
+
+try:
+    from djstripe.settings import djstripe_settings
+except ImportError:
+    pass
+
+
+api = NinjaAPI(parser=EnvelopeParser(), renderer=ORJSONRenderer())
+api.add_router("", "glitchtip.event_ingest.api.router")
+
+
+@api.exception_handler(ThrottleException)
+def throttled(request: HttpRequest, exc: ThrottleException):
+    response = api.create_response(
+        request,
+        {"message": "Please retry later"},
+        status=429,
+    )
+    if retry_after := exc.retry_after:
+        if isinstance(retry_after, int):
+            response["Retry-After"] = retry_after
+        else:
+            response["Retry-After"] = retry_after.strftime("%a, %d %b %Y %H:%M:%S GMT")
+
+    return response
+
+
+class SocialAppSchema(ModelSchema):
+    scopes: list[str]
+    authorize_url: Optional[str]
+
+    class Config:
+        model = SocialApp
+        model_fields = ["name", "client_id", "provider"]
+
+
+class SettingsOut(CamelSchema):
+    social_apps: list[SocialAppSchema]
+    billing_enabled: bool
+    i_paid_for_glitchtip: bool
+    enable_user_registration: bool
+    enable_organization_creation: bool
+    stripe_public_key: Optional[str]
+    plausible_url: Optional[str]
+    plausible_domain: Optional[str]
+
+    # "chatwootWebsiteToken": settings.CHATWOOT_WEBSITE_TOKEN,
+    # "sentryDSN": settings.SENTRY_FRONTEND_DSN,
+    # "sentryTracesSampleRate": settings.SENTRY_TRACES_SAMPLE_RATE,
+    # "environment": settings.ENVIRONMENT,
+    # "version": settings.GLITCHTIP_VERSION,
+    # "serverTimeZone": settings.TIME_ZONE,
+
+
+@api.get("settings/", response=SettingsOut, by_alias=True)
+async def settings_view(request: HttpRequest):
+    social_apps: list[SocialApp] = []
+    async for social_app in SocialApp.objects.order_by("name"):
+        provider = social_app.get_provider(request)
+        social_app.scopes = provider.get_scope(request)
+
+        adapter_cls = SOCIAL_ADAPTER_MAP.get(social_app.provider)
+        if adapter_cls == OpenIDConnectAdapter:
+            adapter = adapter_cls(request, social_app.provider_id)
+        elif adapter_cls:
+            adapter = adapter_cls(request)
+        else:
+            adapter = None
+        if adapter:
+            social_app.authorize_url = adapter.authorize_url
+
+        social_app.provider = social_app.provider_id or social_app.provider
+        social_apps.append(social_app)
+
+    billing_enabled = settings.BILLING_ENABLED
+
+    return SettingsOut(
+        social_apps=social_apps,
+        billing_enabled=billing_enabled,
+        i_paid_for_glitchtip=settings.I_PAID_FOR_GLITCHTIP,
+        enable_user_registration=await ais_user_registration_open(),
+        enable_organization_creation=settings.ENABLE_ORGANIZATION_CREATION,
+        stripe_public_key=djstripe_settings.STRIPE_PUBLIC_KEY
+        if billing_enabled
+        else None,
+        plausible_url=settings.PLAUSIBLE_URL,
+        plausible_domain=settings.PLAUSIBLE_DOMAIN,
+    )
+
+
+# billing_enabled = settings.BILLING_ENABLED
+# enable_user_registration = is_user_registration_open()
+# enable_organization_creation = settings.ENABLE_ORGANIZATION_CREATION
+# stripe_public_key = None
+# if billing_enabled:
+#     stripe_public_key = djstripe_settings.STRIPE_PUBLIC_KEY

+ 0 - 0
glitchtip/event_ingest/exceptions.py → glitchtip/api/exceptions.py


+ 0 - 0
glitchtip/event_ingest/parsers.py → glitchtip/api/parsers.py


+ 0 - 0
glitchtip/event_ingest/renderers.py → glitchtip/api/renderers.py


+ 14 - 0
glitchtip/api/schema.py

@@ -0,0 +1,14 @@
+from ninja import Schema
+
+
+def to_camel(string: str) -> str:
+    return "".join(
+        word if i == 0 else word.capitalize()
+        for i, word in enumerate(string.split("_"))
+    )
+
+
+class CamelSchema(Schema):
+    class Config(Schema.Config):
+        alias_generator = to_camel
+        populate_by_name = True

+ 10 - 25
glitchtip/event_ingest/api.py

@@ -4,35 +4,16 @@ from urllib.parse import urlparse
 
 
 from django.conf import settings
 from django.conf import settings
 from django.http import HttpRequest
 from django.http import HttpRequest
-from ninja import NinjaAPI, Schema
+from ninja import Router, Schema
 from ninja.errors import AuthenticationError, HttpError, ValidationError
 from ninja.errors import AuthenticationError, HttpError, ValidationError
 
 
 from projects.models import Project
 from projects.models import Project
 
 
 from .authentication import event_auth, get_project
 from .authentication import event_auth, get_project
 from .data_models import EnvelopeSchema, EventIngestSchema
 from .data_models import EnvelopeSchema, EventIngestSchema
-from .exceptions import ThrottleException
-from .parsers import EnvelopeParser
-from .renderers import ORJSONRenderer
 from .tasks import ingest_event
 from .tasks import ingest_event
 
 
-api = NinjaAPI(parser=EnvelopeParser(), renderer=ORJSONRenderer())
-
-
-@api.exception_handler(ThrottleException)
-def throttled(request: HttpRequest, exc: ThrottleException):
-    response = api.create_response(
-        request,
-        {"message": "Please retry later"},
-        status=429,
-    )
-    if retry_after := exc.retry_after:
-        if isinstance(retry_after, int):
-            response["Retry-After"] = retry_after
-        else:
-            response["Retry-After"] = retry_after.strftime("%a, %d %b %Y %H:%M:%S GMT")
-
-    return response
+router = Router()
 
 
 
 
 class EventIngestOut(Schema):
 class EventIngestOut(Schema):
@@ -44,7 +25,7 @@ def check_status():
         print(json.dumps(self.request.data))
         print(json.dumps(self.request.data))
 
 
 
 
-@api.post("/{project_id}/store/", response=EventIngestOut)
+@router.post("/{project_id}/store/", response=EventIngestOut)
 async def event_store(
 async def event_store(
     request: HttpRequest,
     request: HttpRequest,
     payload: EventIngestSchema,
     payload: EventIngestSchema,
@@ -52,26 +33,30 @@ async def event_store(
 ):
 ):
     check_status()
     check_status()
     project = await get_project(request)
     project = await get_project(request)
-    res = ingest_event.delay(project.id, payload.dict())
+    ingest_event.delay(project.id, payload.dict())
     return {"event_id": payload.event_id.hex}
     return {"event_id": payload.event_id.hex}
 
 
 
 
-@api.post("/{project_id}/envelope/", response=EventIngestOut, auth=event_auth)
+@router.post("/{project_id}/envelope/", response=EventIngestOut, auth=event_auth)
 async def event_envelope(
 async def event_envelope(
     request: HttpRequest,
     request: HttpRequest,
     payload: EnvelopeSchema,
     payload: EnvelopeSchema,
     project_id: int,
     project_id: int,
 ):
 ):
+    if not len(payload) >= 3:
+        raise ValidationError([])
     header = payload[0]
     header = payload[0]
+    event = payload[2]
     if not hasattr(header, "event_id"):
     if not hasattr(header, "event_id"):
         raise ValidationError([])
         raise ValidationError([])
 
 
     event_id = header.event_id
     event_id = header.event_id
+    ingest_event.delay(project_id, event.dict())
 
 
     return {"event_id": event_id.hex}
     return {"event_id": event_id.hex}
 
 
 
 
-@api.post("/{project_id}/security/", response=EventIngestOut)
+@router.post("/{project_id}/security/", response=EventIngestOut)
 async def event_security(
 async def event_security(
     request: HttpRequest,
     request: HttpRequest,
     payload: EventIngestSchema,
     payload: EventIngestSchema,

+ 1 - 2
glitchtip/event_ingest/authentication.py

@@ -9,7 +9,7 @@ from projects.models import Project
 from sentry.utils.auth import parse_auth_header
 from sentry.utils.auth import parse_auth_header
 
 
 from .constants import EVENT_BLOCK_CACHE_KEY
 from .constants import EVENT_BLOCK_CACHE_KEY
-from .exceptions import ThrottleException
+from glitchtip.api.exceptions import ThrottleException
 
 
 
 
 def auth_from_request(request: HttpRequest):
 def auth_from_request(request: HttpRequest):
@@ -74,7 +74,6 @@ async def get_project(request: HttpRequest):
 
 
 
 
 async def event_auth(request: HttpRequest):
 async def event_auth(request: HttpRequest):
-    print("auth!")
     if settings.MAINTENANCE_EVENT_FREEZE:
     if settings.MAINTENANCE_EVENT_FREEZE:
         raise HttpError(
         raise HttpError(
             503, "Events are not currently being accepted due to maintenance."
             503, "Events are not currently being accepted due to maintenance."

+ 5 - 2
glitchtip/event_ingest/tasks.py

@@ -1,11 +1,14 @@
 import uuid
 import uuid
 
 
 from celery import shared_task
 from celery import shared_task
+from celery_batches import Batches
 
 
 from .data_models import EventIngestSchema
 from .data_models import EventIngestSchema
 
 
 
 
-@shared_task
-def ingest_event(project_id: int, data: dict):
+@shared_task(base=Batches, flush_every=100, flush_interval=2)
+def ingest_event(requests):
+    print(requests)
+    print(requests[0].args)
     event = EventIngestSchema(**data)
     event = EventIngestSchema(**data)
     print(event)
     print(event)

+ 0 - 7
glitchtip/event_ingest/urls.py

@@ -1,7 +0,0 @@
-from django.urls import path
-
-from .api import api
-
-urlpatterns = [
-    path("", api.urls),
-]

Some files were not shown because too many files changed in this diff