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

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 

6 

7from apps.accounting.models import Accounting 

8from apps.organizations.models import Organization 

9from apps.organizations.serializers import BasicOrganizationSerializer, OrganizationTreeSerializer 

10from base.serializers import ToRepresentationMixin 

11 

12from .models import Employee, Fan, SuperUser, User 

13 

14 

15class UserSerializer(serializers.ModelSerializer): 

16 """ 

17 Serializer for User 

18 """ 

19 

20 class Meta: 

21 model = User 

22 read_only_fields = ["email", "first_name", "last_name"] 

23 fields = read_only_fields 

24 

25 

26class FanSerializer(ToRepresentationMixin): 

27 """ 

28 Serializer for Fan 

29 """ 

30 

31 REPRESENTATION_FIELDS = [ 

32 ("parent_organization", BasicOrganizationSerializer, False), 

33 ("registered_organizations", BasicOrganizationSerializer, True), 

34 ] 

35 

36 balance = serializers.SerializerMethodField() 

37 

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}} 

51 

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 

62 

63 def validate_password(self, value): 

64 validate_password(value) 

65 return value 

66 

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 

76 

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) 

83 

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 

93 

94 

95class EmployeeSerializer(serializers.ModelSerializer): 

96 """ 

97 Serializer for Employee 

98 """ 

99 

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}} 

112 

113 def validate_password(self, value): 

114 validate_password(value) 

115 return value 

116 

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 

126 

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 

134 

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 

148 

149 

150class SuperUserSerializer(serializers.ModelSerializer): 

151 """ 

152 Serializer for SuperUser 

153 """ 

154 

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 ] 

163 

164 

165class UserPolymorphicSerializer(PolymorphicSerializer): 

166 """ 

167 Polymorphic serializer for User 

168 """ 

169 

170 model_serializer_mapping = { 

171 User: UserSerializer, 

172 Fan: FanSerializer, 

173 Employee: EmployeeSerializer, 

174 SuperUser: SuperUserSerializer, 

175 } 

176 

177 

178class ResetPasswordSerializer(serializers.Serializer): 

179 email = serializers.EmailField() 

180 

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") 

186 

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", "") 

192 

193 return f"{origin}{settings.FRONTEND_RESET_PASSWORD_PATH}/{token}?u={user.pk}", user 

194 

195 

196class SetPasswordSerializer(serializers.Serializer): 

197 """Serializer to set password""" 

198 

199 user_id = serializers.CharField() 

200 token = serializers.CharField() 

201 password = serializers.CharField() 

202 

203 def validate_password(self, value): 

204 validate_password(value) 

205 return value 

206 

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"}) 

216 

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()