serializers.py 5.3 KB

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