serializers.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. from rest_framework import serializers
  2. from rest_framework.exceptions import PermissionDenied
  3. from glitchtip.exceptions import ConflictException
  4. from projects.serializers.serializers import OrganizationProjectSerializer
  5. from teams.models import Team
  6. from teams.serializers import TeamSerializer
  7. from users.models import User
  8. from users.serializers import UserSerializer
  9. from users.utils import is_user_registration_open
  10. from ..models import ROLES, OrganizationUser, OrganizationUserRole
  11. from .base_serializers import OrganizationReferenceSerializer
  12. class OrganizationSerializer(OrganizationReferenceSerializer):
  13. pass
  14. class OrganizationDetailSerializer(OrganizationSerializer):
  15. projects = OrganizationProjectSerializer(many=True)
  16. teams = TeamSerializer(many=True)
  17. openMembership = serializers.BooleanField(source="open_membership")
  18. scrubIPAddresses = serializers.BooleanField(source="scrub_ip_addresses")
  19. class Meta(OrganizationSerializer.Meta):
  20. fields = OrganizationSerializer.Meta.fields + (
  21. "projects",
  22. "openMembership",
  23. "scrubIPAddresses",
  24. "teams",
  25. )
  26. class OrganizationUserSerializer(serializers.ModelSerializer):
  27. user = UserSerializer(required=False, read_only=True)
  28. role = serializers.CharField(source="get_role")
  29. roleName = serializers.CharField(source="get_role_display", read_only=True)
  30. dateCreated = serializers.DateTimeField(source="created", read_only=True)
  31. teams = serializers.SlugRelatedField(
  32. many=True, write_only=True, slug_field="slug", queryset=Team.objects.none()
  33. )
  34. isOwner = serializers.SerializerMethodField()
  35. class Meta:
  36. model = OrganizationUser
  37. fields = (
  38. "role",
  39. "id",
  40. "user",
  41. "roleName",
  42. "dateCreated",
  43. "email",
  44. "teams",
  45. "pending",
  46. "isOwner",
  47. )
  48. def __init__(self, *args, request_user=None, **kwargs):
  49. super().__init__(*args, **kwargs)
  50. if "request" in self.context:
  51. organization_slug = self.context["view"].kwargs.get("organization_slug")
  52. self.fields["teams"].child_relation.queryset = Team.objects.filter(
  53. organization__slug=organization_slug
  54. )
  55. def get_extra_kwargs(self):
  56. """email should be read only when updating"""
  57. extra_kwargs = super().get_extra_kwargs()
  58. if self.instance is not None:
  59. extra_kwargs["email"] = {"read_only": True}
  60. extra_kwargs["user"] = {"read_only": True}
  61. return extra_kwargs
  62. def get_isOwner(self, obj):
  63. if owner := obj.organization.owner:
  64. return owner.organization_user_id == obj.id
  65. return False
  66. def create(self, validated_data):
  67. role = OrganizationUserRole.from_string(validated_data.get("get_role"))
  68. email = validated_data.get("email")
  69. organization = validated_data.get("organization")
  70. teams = validated_data.get("teams")
  71. if (
  72. not is_user_registration_open()
  73. and not User.objects.filter(email=email).exists()
  74. ):
  75. raise PermissionDenied("Only existing users may be invited")
  76. if organization.organization_users.filter(email=email).exists():
  77. raise ConflictException(f"The user {email} is already invited", "email")
  78. if organization.organization_users.filter(user__email=email).exists():
  79. raise ConflictException(f"The user {email} is already a member", "email")
  80. org_user = super().create(
  81. {"role": role, "email": email, "organization": organization}
  82. )
  83. org_user.team_set.add(*teams)
  84. return org_user
  85. def update(self, instance, validated_data):
  86. get_role = validated_data.pop("get_role", None)
  87. if get_role:
  88. role = OrganizationUserRole.from_string(get_role)
  89. validated_data["role"] = role
  90. return super().update(instance, validated_data)
  91. def to_representation(self, obj):
  92. """Override email for representation to potentially show user's email"""
  93. self.fields["email"] = serializers.SerializerMethodField()
  94. return super().to_representation(obj)
  95. def get_email(self, obj):
  96. """Prefer user primary email over org user email (which is only for invites)"""
  97. if obj.user:
  98. return obj.user.email
  99. return obj.email
  100. class OrganizationUserDetailSerializer(OrganizationUserSerializer):
  101. teams = serializers.SlugRelatedField(
  102. source="team_set", slug_field="slug", read_only=True, many=True
  103. )
  104. roles = serializers.SerializerMethodField()
  105. class Meta(OrganizationUserSerializer.Meta):
  106. fields = OrganizationUserSerializer.Meta.fields + ("roles",)
  107. def get_roles(self, obj):
  108. return ROLES
  109. class OrganizationUserProjectsSerializer(OrganizationUserSerializer):
  110. projects = serializers.SerializerMethodField()
  111. class Meta(OrganizationUserSerializer.Meta):
  112. fields = OrganizationUserSerializer.Meta.fields + ("projects",)
  113. def get_projects(self, obj):
  114. return obj.organization.projects.filter(team__members=obj).values_list(
  115. "slug", flat=True
  116. )
  117. class ReinviteSerializer(serializers.Serializer):
  118. reinvite = serializers.IntegerField()
  119. def update(self, instance, validated_data):
  120. if validated_data.get("reinvite"):
  121. pass
  122. # Send email
  123. return instance
  124. class OrganizationUserOrganizationSerializer(OrganizationUserSerializer):
  125. """Organization User Serializer with Organization info"""
  126. organization = OrganizationSerializer()
  127. class Meta(OrganizationUserSerializer.Meta):
  128. fields = OrganizationUserSerializer.Meta.fields + ("organization",)
  129. class AcceptInviteSerializer(serializers.Serializer):
  130. accept_invite = serializers.BooleanField()
  131. org_user = OrganizationUserOrganizationSerializer(read_only=True)