mirror of
https://github.com/workhardbekind/workout-challenge.git
synced 2026-07-04 09:23:32 -04:00
first commit
This commit is contained in:
commit
e7f627801f
152 changed files with 35352 additions and 0 deletions
118
src-backend/custom_user/serializers.py
Normal file
118
src-backend/custom_user/serializers.py
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
from rest_framework import serializers
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.tokens import default_token_generator
|
||||
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from .models import CustomUser
|
||||
from .emails.multipurpose import send_email
|
||||
|
||||
|
||||
class CustomUserSerializer(serializers.ModelSerializer):
|
||||
my = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = ['id', 'my', 'email', 'first_name', 'last_name', 'gender', 'username', 'password', 'is_verified', 'email_mid_week', 'strava_athlete_id', 'strava_allow_follow', 'strava_last_synced_at', 'my_competitions', 'my_teams', 'goal_active_days', 'goal_workout_minutes', 'goal_distance', 'scaling_kcal', 'scaling_distance']
|
||||
read_only_fields = ['is_verified', 'strava_athlete_id', 'strava_last_synced_at']
|
||||
extra_kwargs = {
|
||||
'password': {'write_only': True},
|
||||
}
|
||||
|
||||
def get_my(self, obj):
|
||||
user = self.context['request'].user
|
||||
return obj.pk == user.pk
|
||||
|
||||
def create(self, validated_data):
|
||||
user = CustomUser.objects.create_user(
|
||||
email=validated_data.get('email'),
|
||||
first_name=validated_data.get('first_name'),
|
||||
last_name=validated_data.get('last_name', None),
|
||||
password=validated_data.get('password'),
|
||||
gender=validated_data.get('gender', None),
|
||||
)
|
||||
return user
|
||||
|
||||
def to_representation(self, instance):
|
||||
rep = super().to_representation(instance)
|
||||
user = self.context['request'].user
|
||||
|
||||
# Omit 'secret' fields of other users that this user is not allowed to see
|
||||
if instance.pk != user.pk:
|
||||
rep.pop('email', None)
|
||||
rep.pop('first_name', None)
|
||||
rep.pop('last_name', None)
|
||||
rep.pop('gender', None)
|
||||
rep.pop('password', None)
|
||||
rep.pop('strava_last_synced_at', None)
|
||||
|
||||
if not rep['strava_allow_follow']:
|
||||
rep.pop('strava_athlete_id', None)
|
||||
|
||||
return rep
|
||||
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# If instance exists, it's an update (PUT/PATCH), make fields optional
|
||||
if self.instance:
|
||||
self.fields['email'].required = False
|
||||
self.fields['password'].required = False
|
||||
self.fields['first_name'].required = False
|
||||
self.fields['last_name'].required = False
|
||||
|
||||
|
||||
class PasswordResetSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField()
|
||||
|
||||
def validate_email(self, value):
|
||||
if not CustomUser.objects.filter(email=value).exists():
|
||||
# To avoid leaking info
|
||||
return value
|
||||
return value
|
||||
|
||||
def save(self, request):
|
||||
email = self.validated_data['email']
|
||||
users = CustomUser.objects.filter(email=email)
|
||||
for user in users:
|
||||
uid = urlsafe_base64_encode(force_bytes(user.pk))
|
||||
token = default_token_generator.make_token(user)
|
||||
reset_url = f"{settings.MAIN_HOST}/password/reset/{uid}/{token}/"
|
||||
|
||||
email_subject = "Workout Challenge - Reset Your Password"
|
||||
email_body = render_to_string(
|
||||
"email_password_reset.html",
|
||||
{
|
||||
'first_name': user.first_name,
|
||||
'MAIN_HOST': settings.MAIN_HOST,
|
||||
'RESET_URL': reset_url,
|
||||
'EMAIL_REPLY_TO': settings.EMAIL_REPLY_TO,
|
||||
}
|
||||
)
|
||||
|
||||
send_email(subject=email_subject, body=email_body, to_email=user.email)
|
||||
|
||||
|
||||
|
||||
class PasswordResetConfirmSerializer(serializers.Serializer):
|
||||
uid = serializers.CharField()
|
||||
token = serializers.CharField()
|
||||
new_password = serializers.CharField(write_only=True)
|
||||
|
||||
def validate(self, attrs):
|
||||
try:
|
||||
uid = urlsafe_base64_decode(attrs['uid']).decode()
|
||||
self.user = CustomUser.objects.get(pk=uid)
|
||||
except (CustomUser.DoesNotExist, ValueError):
|
||||
raise serializers.ValidationError("Invalid user.")
|
||||
|
||||
if not default_token_generator.check_token(self.user, attrs['token']):
|
||||
raise serializers.ValidationError("Invalid or expired token.")
|
||||
|
||||
return attrs
|
||||
|
||||
def save(self):
|
||||
self.user.set_password(self.validated_data['new_password'])
|
||||
self.user.save()
|
||||
Loading…
Add table
Add a link
Reference in a new issue