123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- from django.db.models import Q
- from django.http import Http404, HttpResponse
- from django.shortcuts import aget_object_or_404
- from ninja import Router
- from ninja.pagination import paginate
- from apps.organizations_ext.models import OrganizationUserRole
- from apps.projects.models import Project
- from glitchtip.api.authentication import AuthHttpRequest
- from glitchtip.api.permissions import has_permission
- from .models import AlertRecipient, ProjectAlert
- from .schema import ProjectAlertIn, ProjectAlertSchema
- router = Router()
- def get_project_alert_queryset(user_id: int, organization_slug: str, project_slug: str):
- return ProjectAlert.objects.filter(
- project__organization__users=user_id,
- project__organization__slug=organization_slug,
- project__slug=project_slug,
- ).prefetch_related("alertrecipient_set")
- @router.get(
- "projects/{slug:organization_slug}/{slug:project_slug}/alerts/",
- response=list[ProjectAlertSchema],
- by_alias=True,
- )
- @has_permission(["project:read"])
- @paginate
- async def list_project_alerts(
- request: AuthHttpRequest,
- response: HttpResponse,
- organization_slug: str,
- project_slug: str,
- ):
- return get_project_alert_queryset(
- request.auth.user_id, organization_slug, project_slug
- )
- @router.post(
- "projects/{slug:organization_slug}/{slug:project_slug}/alerts/",
- response={201: ProjectAlertSchema},
- by_alias=True,
- )
- @has_permission(["project:write", "project:admin"])
- async def create_project_alert(
- request: AuthHttpRequest,
- organization_slug: str,
- project_slug: str,
- payload: ProjectAlertIn,
- ):
- user_id = request.auth.user_id
- project = await aget_object_or_404(
- Project.objects.filter(
- Q(
- organization__users=user_id,
- organization__organization_users__role__gte=OrganizationUserRole.ADMIN,
- )
- | Q(teams__members__user=user_id)
- ).distinct(),
- organization__slug=organization_slug,
- slug=project_slug,
- )
- data = payload.dict()
- recipients = data.pop("alert_recipients")
- project_alert = await project.projectalert_set.acreate(**data)
- await AlertRecipient.objects.abulk_create(
- [AlertRecipient(alert=project_alert, **recipient) for recipient in recipients]
- )
- return await get_project_alert_queryset(
- user_id, organization_slug, project_slug
- ).aget(id=project_alert.id)
- @router.put(
- "projects/{slug:organization_slug}/{slug:project_slug}/alerts/{alert_id}/",
- response=ProjectAlertSchema,
- by_alias=True,
- )
- @has_permission(["project:write", "project:admin"])
- async def update_project_alert(
- request: AuthHttpRequest,
- organization_slug: str,
- project_slug: str,
- alert_id: int,
- payload: ProjectAlertIn,
- ):
- user_id = request.auth.user_id
- alert = await aget_object_or_404(
- get_project_alert_queryset(user_id, organization_slug, project_slug),
- id=alert_id,
- )
- data = payload.dict()
- alert_recipients = data.pop("alert_recipients")
- for attr, value in data.items():
- setattr(alert, attr, value)
- await alert.asave()
- # Create/Delete recipients as needed
- delete_recipient_ids = set(
- {id async for id in alert.alertrecipient_set.values_list("id", flat=True)}
- )
- for recipient in alert_recipients:
- new_recipient, created = await AlertRecipient.objects.aget_or_create(
- alert=alert, **recipient
- )
- if not created:
- delete_recipient_ids.discard(new_recipient.pk)
- if delete_recipient_ids:
- await alert.alertrecipient_set.filter(pk__in=delete_recipient_ids).adelete()
- return await get_project_alert_queryset(
- user_id, organization_slug, project_slug
- ).aget(id=alert.id)
- @router.delete(
- "projects/{slug:organization_slug}/{slug:project_slug}/alerts/{alert_id}/",
- response={204: None},
- )
- @has_permission(["project:admin"])
- async def delete_project_alert(
- request: AuthHttpRequest, organization_slug: str, project_slug: str, alert_id: int
- ):
- user_id = request.auth.user_id
- result, _ = (
- await get_project_alert_queryset(user_id, organization_slug, project_slug)
- .filter(id=alert_id)
- .filter(
- project__organization__users=user_id,
- project__organization__organization_users__role__gte=OrganizationUserRole.ADMIN,
- )
- .adelete()
- )
- if result:
- return 204, None
- raise Http404
|