Coverage for apps/users/serializers.py: 60%
135 statements
« prev ^ index » next coverage.py v6.4.4, created at 2024-05-15 10:51 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2024-05-15 10:51 -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_framework.validators import ValidationError
6from dj_rest_auth.serializers import UserDetailsSerializer
8from apps.organizations.models import Affiliation, OrganizationRole
9from apps.practitioners.serializers import PractitionerSerializer
10from services.google import GoogleService
12from .models import GoogleAccount, User
15class GoogleAccountSerializer(serializers.ModelSerializer):
16 class Meta:
17 model = GoogleAccount
18 read_only_fields = ["state", "auth_url"]
19 fields = read_only_fields + []
21 def create(self, validated_data):
22 google_service = GoogleService()
23 flow = google_service._create_flow()
24 auth_url, state = google_service._get_auth_url_and_state()
25 validated_data.update(
26 {
27 "state": state,
28 "auth_url": auth_url,
29 }
30 )
31 instance = super().create(validated_data)
32 return instance
35class GoogleValidateSerializer(serializers.ModelSerializer):
36 code = serializers.CharField()
38 class Meta:
39 model = GoogleAccount
40 read_only_fields = []
41 fields = read_only_fields + ["code"]
43 def update(self, instance, validated_data):
44 code = validated_data.pop("code")
45 state = instance.state
46 try:
47 google_service = GoogleService()
48 flow = google_service._get_flow_by_state(state=state)
49 fetch_token = google_service._get_flow_token(code=code)
50 credentials = google_service._get_credentials_from_flow()
51 instance.credentials_json = credentials.to_json()
52 instance.token = credentials.token
53 instance.code = code
54 instance.refresh_token = credentials.refresh_token
55 instance.expires_at = credentials.expiry
56 instance.awaiting_code = False
57 instance.save()
58 except Exception as e:
59 print(e)
60 return super().update(instance, validated_data)
63class OrganizationRoleSerializerForUser(serializers.ModelSerializer):
64 role_type = serializers.CharField(source="role_type.type_of")
66 class Meta:
67 model = OrganizationRole
68 read_only_fields = ["role_type"]
69 fields = ["name", "role_type", "random_slug"]
72class AffiliationSerializerForUser(serializers.ModelSerializer):
73 """
74 Serailizer for Affiliation
75 """
77 roles = OrganizationRoleSerializerForUser(many=True, read_only=True)
79 class Meta:
80 model = Affiliation
81 fields = ["organization", "roles", "is_owner"]
84class UserSerializer(serializers.ModelSerializer):
85 """
86 Serializer for User
87 """
89 practitioner = PractitionerSerializer(read_only=True)
90 affiliations = AffiliationSerializerForUser(many=True, read_only=True)
91 google_account = serializers.SerializerMethodField()
93 class Meta:
94 model = User
95 read_only_fields = ["id", "practitioner", "affiliations", "google_account"]
96 fields = read_only_fields + ["email", "password", "primary_color", "phone_number", "onboarding_needed"]
97 extra_kwargs = {"password": {"write_only": True, "required": False}, "email": {"required": False}}
99 def validate_password(self, value):
100 validate_password(value)
101 return value
103 def create(self, validated_data):
104 user = self.Meta.model.objects.create_user(**validated_data)
105 return user
107 def get_google_account(self, obj):
108 if getattr(obj, "googleaccount", None):
109 return True
110 else:
111 return False
114class ResetPasswordSerializer(serializers.Serializer):
115 email = serializers.EmailField()
117 def validate_email(self, value):
118 try:
119 return User.objects.get(email=value)
120 except User.DoesNotExist:
121 raise serializers.ValidationError("No existe un usuario con ese email")
123 def save(self, validated_data):
124 email = validated_data.get("email")
125 user = User.objects.get(email=email)
126 token = PasswordResetTokenGenerator().make_token(user)
128 return f"{settings.FRONTEND_DOMAIN}{settings.FRONTEND_RESET_PASSWORD_PATH}/{token}?u={user.pk}", user
131class SetPasswordSerializer(serializers.Serializer):
132 """Serializer to set password"""
134 user_id = serializers.CharField()
135 token = serializers.CharField()
136 password = serializers.CharField()
138 def validate_password(self, value):
139 validate_password(value)
140 return value
142 def validate(self, attrs):
143 token = attrs.get("token")
144 user_id = attrs.get("user_id")
145 try:
146 user = User.objects.get(pk=user_id)
147 except User.DoesNotExist:
148 raise ValidationError({"user": "The user does not exist"})
150 verified_token = PasswordResetTokenGenerator().check_token(user, token)
151 if verified_token:
152 return attrs
153 else:
154 raise ValidationError({"token": "The token is not valid"})
156 def save(self, validated_data):
157 data = validated_data
158 user_id = data.get("user_id")
159 user = User.objects.get(pk=user_id)
160 user.set_password(data.get("password"))
161 user.save()
164from django.contrib.auth import get_user_model
165UserModel = get_user_model()
167class MyUserDetailsSerializer(UserDetailsSerializer):
168 practitioner = PractitionerSerializer(read_only=True)
169 affiliations = AffiliationSerializerForUser(many=True, read_only=True)
170 google_account = serializers.SerializerMethodField()
171 class Meta:
172 extra_fields = [
173 'primary_color', 'phone_number', 'onboarding_needed', 'email',
174 'practitioner', 'affiliations', 'google_account',
176 ]
177 # see https://github.com/iMerica/dj-rest-auth/issues/181
178 # UserModel.XYZ causing attribute error while importing other
179 # classes from `serializers.py`. So, we need to check whether the auth model has
180 # the attribute or not
181 if hasattr(UserModel, 'USERNAME_FIELD'): 181 ↛ 183line 181 didn't jump to line 183, because the condition on line 181 was never false
182 extra_fields.append(UserModel.USERNAME_FIELD)
183 if hasattr(UserModel, 'EMAIL_FIELD'): 183 ↛ 184line 183 didn't jump to line 184, because the condition on line 183 was never true
184 extra_fields.append(UserModel.EMAIL_FIELD)
185 if hasattr(UserModel, 'first_name'): 185 ↛ 186line 185 didn't jump to line 186, because the condition on line 185 was never true
186 extra_fields.append('first_name')
187 if hasattr(UserModel, 'last_name'): 187 ↛ 188line 187 didn't jump to line 188, because the condition on line 187 was never true
188 extra_fields.append('last_name')
189 model = UserModel
190 fields = ('pk', *extra_fields)
191 read_only_fields = ('email',)
193 def get_google_account(self, obj):
194 if getattr(obj, 'googleaccount', None):
195 return True
196 else:
197 return False