add user reset password

This commit is contained in:
TUTOR03 2020-11-28 17:15:24 +05:00
parent c2ac4f979f
commit 7dceaaeed0
6 changed files with 98 additions and 3 deletions

View File

@ -147,3 +147,21 @@ EMAIL_HOST_USER = 'artemss20030906@gmail.com'
EMAIL_HOST_PASSWORD = 'hbqgvdsqhvkuijuc'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 7,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]

View File

@ -7,6 +7,9 @@ class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
points = models.DecimalField(max_digits=7, decimal_places=0, default = 0)
def __str__(self):
return(f'{self.user.username} - {self.user.email}')
@receiver(post_save, sender = User)
def create_profile(sender, instance, created, **kwargs):
if(created):

View File

@ -10,4 +10,19 @@ class UserRegisterSerializer(serializers.ModelSerializer):
'username',
'password',
'email'
]
class UserResetPasswordSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=True)
class Meta:
model = User
fields = [
'email'
]
class UserPasswordSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'password'
]

View File

@ -7,4 +7,6 @@ urlpatterns = [
path('login', obtain_auth_token, name = 'UserLogin'),
path('logout', views.UserLogoutAPIView, name = 'UserLogout'),
path('activate/<uidb64>/<token>', views.UserActivationAPIView, name = 'UserActivation'),
path('reset_password_request', views.UserResetPasswordRequestAPIView, name = 'UserResetPasswordRequest'),
path('reset_password/<uidb64>/<token>', views.UserResetPasswordAPIView, name = 'UserResetPassword'),
]

View File

@ -10,8 +10,9 @@ from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core.mail import EmailMultiAlternatives
from .serializers import UserRegisterSerializer
from .serializers import UserRegisterSerializer, UserResetPasswordSerializer, UserPasswordSerializer
from django.utils.html import strip_tags
from django.contrib.auth.password_validation import validate_password
import six
import threading
@ -20,6 +21,7 @@ class EmailTokenGenerator(PasswordResetTokenGenerator):
return(six.text_type(user.pk) + six.text_type(timestamp) + six.text_type(user.is_active))
email_token_gen = EmailTokenGenerator()
password_token_gen = PasswordResetTokenGenerator()
@api_view(['POST'])
@permission_classes([~permissions.IsAuthenticated])
@ -27,8 +29,12 @@ def UserRegisterAPIView(request):
serializer = UserRegisterSerializer(data = request.data)
if(serializer.is_valid()):
data = serializer.validated_data
if(User.objects.filter(username = data['username']).exists()):
if(User.objects.filter(username = data['username']).exists() or User.objects.filter(email = data['email']).exists()):
return Response({'ok':False, 'error':'User already exists'}, status = status.HTTP_400_BAD_REQUEST)
try:
validate_password(data['password'])
except Exception as errors:
return Response({'ok':False, 'error':errors} ,status = status.HTTP_400_BAD_REQUEST)
user = User.objects.create(username = data['username'], email = data['email'], is_active = False)
user.set_password(data['password'])
user.save()
@ -52,12 +58,57 @@ def UserActivationAPIView(request, uidb64, token):
user = User.objects.filter(id = uid)
if(user.exists()):
user = user.first()
if(email_token_gen.check_token(user, token) and not user.is_active):
if(email_token_gen.check_token(user, token)):
user.is_active = True
user.save()
return Response({'ok':True}, status = status.HTTP_200_OK)
return Response({'ok':False, 'error':'Invalid activation link'}, status = status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@permission_classes([~permissions.IsAuthenticated])
def UserResetPasswordRequestAPIView(request):
serializer = UserResetPasswordSerializer(data = request.data)
if(serializer.is_valid()):
data = serializer.validated_data
user = User.objects.filter(email = data['email'])
if(user.exists()):
user = user.first()
domain = get_current_site(request).domain
mail_subject = 'Password reset'
message = render_to_string('password_reset.html',{
'user':user,
'domain': domain,
'uidb64': urlsafe_base64_encode(force_bytes(user.pk)),
'token': password_token_gen.make_token(user),
})
message_task = threading.Thread(target = async_email_send, args=( mail_subject, message, [data['email']] ))
message_task.start()
return Response({'ok':True}, status = status.HTTP_200_OK)
return Response({'ok':False, 'error':'User does not exist'}, status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':serializer.errors}, status = status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@permission_classes([~permissions.IsAuthenticated])
def UserResetPasswordAPIView(request, uidb64, token):
serializer = UserPasswordSerializer(data = request.data)
if(serializer.is_valid()):
data = serializer.validated_data
try:
validate_password(data['password'])
except Exception as errors:
return Response({'ok':False, 'error':errors} ,status = status.HTTP_400_BAD_REQUEST)
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.filter(id = uid)
if(user.exists()):
user = user.first()
if(password_token_gen.check_token(user, token)):
user.set_password(data['password'])
user.save()
return Response({'ok':True}, status = status.HTTP_200_OK)
return Response({'ok':False, 'error':'Invalid password reset link'} ,status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':'User does not exist'} ,status = status.HTTP_400_BAD_REQUEST)
return Response({'ok':False, 'error':serializer.errors}, status = status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def UserLogoutAPIView(request):

View File

@ -0,0 +1,6 @@
{% autoescape off %}
<h1>HI {{ user.username }}</h1>
<h2>This email was used to reset your account password</h2>
<h2>To reset password follow the link below:</h2>
<a href="http://{{ domain }}/reset_pass/{{ uidb64 }}/{{ token }}"><h2>Reset Password</h2></a>
{% endautoescape %}