Coverage for apps/users/serializers.py: 47%
133 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-09-29 13:12 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-09-29 13:12 -0600
1from django.conf import settings
2from django.contrib.auth.password_validation import validate_password
3from django.contrib.auth.tokens import PasswordResetTokenGenerator
4from rest_framework import serializers
5from rest_polymorphic.serializers import PolymorphicSerializer
7from apps.accounting.models import Accounting
8from apps.organizations.models import Organization
9from apps.organizations.serializers import BasicOrganizationSerializer, OrganizationTreeSerializer
10from base.serializers import ToRepresentationMixin
12from .models import Employee, Fan, SuperUser, User
15class UserSerializer(serializers.ModelSerializer):
16 """
17 Serializer for User
18 """
20 class Meta:
21 model = User
22 read_only_fields = ["email", "first_name", "last_name"]
23 fields = read_only_fields
26class FanSerializer(ToRepresentationMixin):
27 """
28 Serializer for Fan
29 """
31 REPRESENTATION_FIELDS = [
32 ("parent_organization", BasicOrganizationSerializer, False),
33 ("registered_organizations", BasicOrganizationSerializer, True),
34 ]
36 balance = serializers.SerializerMethodField()
38 class Meta:
39 model = Fan
40 read_only_fields = ["id", "created_at"]
41 fields = read_only_fields + [
42 "email",
43 "first_name",
44 "last_name",
45 "password",
46 "parent_organization",
47 "registered_organizations",
48 "balance",
49 ]
50 extra_kwargs = {"password": {"write_only": True}}
52 def get_balance(self, instance):
53 origin = self.context.get("request").headers.get("Origin", "")
54 try:
55 organization = Organization.objects.filter(is_active=True).get(domain=origin)
56 except Organization.DoesNotExist:
57 return 0
58 try:
59 return instance.accounting.get(organization=organization).balance
60 except Accounting.DoesNotExist:
61 return 0
63 def validate_password(self, value):
64 validate_password(value)
65 return value
67 def validate(self, attrs):
68 email = attrs.get("email")
69 parent_organization = attrs.get("parent_organization")
70 fan = Fan.objects.filter(email=email, parent_organization=parent_organization)
71 if fan.exists():
72 raise serializers.ValidationError(
73 {"email": "There is already a user with the same email registered on this organization"}
74 )
75 return attrs
77 def update(self, instance, validated_data):
78 password = validated_data.pop("password", None)
79 if password:
80 instance.set_password(password)
81 instance.save()
82 return super().update(instance, validated_data)
84 def create(self, validated_data):
85 email = validated_data.pop("email")
86 password = validated_data.pop("password")
87 registered_organizations = validated_data.pop("registered_organizations", [])
88 fan = Fan.objects.create_user(email, password, **validated_data)
89 for organization in registered_organizations:
90 fan.registered_organizations.add(organization)
91 fan.save()
92 return fan
95class EmployeeSerializer(serializers.ModelSerializer):
96 """
97 Serializer for Employee
98 """
100 class Meta:
101 model = Employee
102 read_only_fields = ["created_at"]
103 fields = read_only_fields + [
104 "email",
105 "first_name",
106 "last_name",
107 "password",
108 "parent_organization",
109 "registered_organizations",
110 ]
111 extra_kwargs = {"password": {"write_only": True, "required": False}}
113 def validate_password(self, value):
114 validate_password(value)
115 return value
117 def validate(self, attrs):
118 email = attrs.get("email")
119 parent_organization = attrs.get("parent_organization")
120 employee = Employee.objects.filter(email=email, parent_organization=parent_organization)
121 if employee.exists():
122 raise serializers.ValidationError(
123 {"email": "There is already a user with the same email registered on this organization"}
124 )
125 return attrs
127 def create(self, validated_data):
128 registered_organizations = validated_data.pop("registered_organizations", [])
129 employee = Employee.objects.create_user(**validated_data)
130 for organization in registered_organizations:
131 employee.registered_organizations.add(organization)
132 employee.save()
133 return employee
135 def to_representation(self, instance):
136 representation = super(EmployeeSerializer, self).to_representation(instance)
137 # Parent organization representation
138 parent_organization_slug = representation.get("parent_organization")
139 parent_organization = Organization.objects.get(random_slug=parent_organization_slug)
140 serializer = OrganizationTreeSerializer(instance=parent_organization)
141 representation["parent_organization"] = serializer.data
142 # Registered organizations representation
143 registered_organization_slugs = representation.get("registered_organizations")
144 registered_organizations = Organization.objects.filter(random_slug__in=registered_organization_slugs)
145 serializer = BasicOrganizationSerializer(instance=registered_organizations, many=True)
146 representation["registered_organizations"] = serializer.data
147 return representation
150class SuperUserSerializer(serializers.ModelSerializer):
151 """
152 Serializer for SuperUser
153 """
155 class Meta:
156 model = SuperUser
157 read_only_fields = ["created_at"]
158 fields = read_only_fields + [
159 "email",
160 "first_name",
161 "last_name",
162 ]
165class UserPolymorphicSerializer(PolymorphicSerializer):
166 """
167 Polymorphic serializer for User
168 """
170 model_serializer_mapping = {
171 User: UserSerializer,
172 Fan: FanSerializer,
173 Employee: EmployeeSerializer,
174 SuperUser: SuperUserSerializer,
175 }
178class ResetPasswordSerializer(serializers.Serializer):
179 email = serializers.EmailField()
181 def validate_email(self, value):
182 try:
183 return User.objects.get(email=value)
184 except User.DoesNotExist:
185 raise serializers.ValidationError("No existe un usuario con ese email")
187 def save(self, validated_data):
188 email = validated_data.get("email")
189 user = Fan.objects.get(email=email)
190 token = PasswordResetTokenGenerator().make_token(user)
191 origin = self.context.get("request").headers.get("Origin", "")
193 return f"{origin}{settings.FRONTEND_RESET_PASSWORD_PATH}/{token}?u={user.pk}", user
196class SetPasswordSerializer(serializers.Serializer):
197 """Serializer to set password"""
199 user_id = serializers.CharField()
200 token = serializers.CharField()
201 password = serializers.CharField()
203 def validate_password(self, value):
204 validate_password(value)
205 return value
207 def validate(self, attrs):
208 token = attrs.get("token")
209 user_id = attrs.get("user_id")
210 user = Fan.objects.get(pk=user_id)
211 verified_token = PasswordResetTokenGenerator().check_token(user, token)
212 if verified_token:
213 return attrs
214 else:
215 raise serializers.ValidationError({"token": "The token is not valid"})
217 def save(self, validated_data):
218 data = validated_data
219 user_id = data.get("user_id")
220 user = Fan.objects.get(pk=user_id)
221 user.set_password(data.get("password"))
222 user.save()