serializers.py 6.0 KB

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