api.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from django.http import Http404, HttpResponse
  2. from django.shortcuts import aget_object_or_404
  3. from ninja import Router
  4. from ninja.errors import HttpError
  5. from apps.shared.types import MeID
  6. from glitchtip.api.authentication import AuthHttpRequest
  7. from glitchtip.api.pagination import paginate
  8. from .models import User
  9. from .schema import UserIn, UserSchema
  10. router = Router()
  11. """
  12. Sentry OSS does not document any of these, but they exist
  13. GET /users/
  14. GET /users/<me_id>/
  15. DELETE /users/<me_id>/
  16. PUT /users/<me_id>/
  17. GET /organizations/burke-software/users/ (Not implemented)
  18. """
  19. def get_user_queryset(user_id: int, add_details=False):
  20. qs = User.objects.filter(id=user_id)
  21. if add_details:
  22. qs = qs.prefetch_related("socialaccount_set")
  23. return qs
  24. @router.get("/users/", response=list[UserSchema], by_alias=True)
  25. @paginate
  26. async def list_users(request: AuthHttpRequest, response: HttpResponse):
  27. """
  28. Exists in Sentry OSS, unsure what the use case is
  29. We make it only list the current user
  30. """
  31. return get_user_queryset(user_id=request.auth.user_id, add_details=True)
  32. @router.get("/users/{slug:user_id}/", response=UserSchema, by_alias=True)
  33. async def get_user(request: AuthHttpRequest, user_id: MeID):
  34. user_id = request.auth.user_id
  35. return await aget_object_or_404(get_user_queryset(user_id, add_details=True))
  36. @router.delete("/users/{slug:user_id}/", response={204: None})
  37. async def delete_user(request: AuthHttpRequest, user_id: MeID):
  38. # Can only delete self
  39. if user_id != request.auth.user_id and user_id != "me":
  40. raise Http404
  41. user_id = request.auth.user_id
  42. queryset = get_user_queryset(user_id=user_id)
  43. result, _ = await queryset.filter(
  44. organizations_ext_organizationuser__organizationowner__isnull=True
  45. ).adelete()
  46. if result:
  47. return 204, None
  48. if await queryset.aexists():
  49. raise HttpError(
  50. 400,
  51. "User is organization owner. Delete organization or transfer ownership first.",
  52. )
  53. raise Http404
  54. @router.put(
  55. "/users/{slug:user_id}/",
  56. response=UserSchema,
  57. by_alias=True,
  58. )
  59. async def update_user(request: AuthHttpRequest, user_id: MeID, payload: UserIn):
  60. if user_id != request.auth.user_id and user_id != "me":
  61. raise Http404
  62. user_id = request.auth.user_id
  63. user = await aget_object_or_404(get_user_queryset(user_id, add_details=True))
  64. for attr, value in payload.dict().items():
  65. setattr(user, attr, value)
  66. await user.asave()
  67. return user