diff --git a/web_admin/serializers/auth_serializer.py b/web_admin/serializers/auth_serializer.py index 386571b..06cdf3a 100644 --- a/web_admin/serializers/auth_serializer.py +++ b/web_admin/serializers/auth_serializer.py @@ -1,6 +1,7 @@ """ web_admin auth serializers file """ +# python imports from datetime import datetime # django imports @@ -13,7 +14,6 @@ from templated_email import send_templated_mail # local imports from account.models import UserEmailOtp -from account.utils import custom_error_response from base.messages import ERROR_CODE from guardian.tasks import generate_otp @@ -21,9 +21,15 @@ USER = get_user_model() class AdminForgotPasswordSerializer(serializers.ModelSerializer): - email = serializers.EmailField(required=True) + """ + admin forgot password serializer + """ + email = serializers.EmailField() class Meta: + """ + meta class + """ model = USER fields = ('email',) @@ -38,11 +44,12 @@ class AdminForgotPasswordSerializer(serializers.ModelSerializer): return attrs def create(self, validated_data): + """ + to send otp + :return: user_data + """ email = validated_data['email'] - try: - USER.objects.get(email=email) - except USER.DoesNotExist: - return custom_error_response(ERROR_CODE['2004'], response_status=status.HTTP_404_NOT_FOUND) + verification_code = generate_otp() # Send the verification code to the user's email @@ -68,21 +75,88 @@ class AdminForgotPasswordSerializer(serializers.ModelSerializer): class AdminVerifyOTPSerializer(serializers.Serializer): + """ + admin verify otp serializer + """ + email = serializers.EmailField() otp = serializers.CharField(max_length=6, min_length=6) class Meta: """ meta class """ - fields = ('otp',) + fields = ('email', 'otp',) def validate(self, attrs): - otp = attrs.pop('otp') + """ + to validate data + :return: validated data + """ + email = attrs.get('email') + otp = attrs.get('otp') + + user = USER.objects.filter(email=attrs['email']).first() + if not user: + raise serializers.ValidationError(ERROR_CODE['2004']) + elif not user.is_superuser: + raise serializers.ValidationError(ERROR_CODE['2036']) # fetch email otp object of the user - user_opt_details = UserEmailOtp.objects.filter(otp=otp).last() - if not user_opt_details: + user_otp_details = UserEmailOtp.objects.filter(email=email, otp=otp).last() + if not user_otp_details: raise serializers.ValidationError(ERROR_CODE['2008']) - if user_opt_details.expired_at.replace(tzinfo=None) < datetime.utcnow(): + if user_otp_details.expired_at.replace(tzinfo=None) < datetime.utcnow(): raise serializers.ValidationError(ERROR_CODE['2029']) - user_details = USER.objects.filter(email=user_opt_details.email).last() - user_opt_details.delete() - if user_details: + user_otp_details.is_verified = True + user_otp_details.save() + return attrs + + +class AdminCreatePasswordSerializer(serializers.ModelSerializer): + """ + admin create new password serializer + """ + email = serializers.EmailField() + new_password = serializers.CharField() + confirm_password = serializers.CharField() + + class Meta: + """ + meta class + """ + model = USER + fields = ('email', 'new_password', 'confirm_password') + + def validate(self, attrs): + """ + to validate data + :return: validated data + """ + email = attrs.get('email') + new_password = attrs.get('new_password') + confirm_password = attrs.get('confirm_password') + + # matching password + if new_password != confirm_password: + raise serializers.ValidationError('password do not match') + + user = USER.objects.filter(email=attrs['email']).first() + if not user: + raise serializers.ValidationError(ERROR_CODE['2004']) + elif not user.is_superuser: + raise serializers.ValidationError(ERROR_CODE['2036']) + + user_otp_details = UserEmailOtp.objects.filter(email=email).last() + + if user_otp_details and user_otp_details.is_verified: + user_otp_details.delete() + attrs.update({'user': user}) return attrs + raise serializers.ValidationError(ERROR_CODE['2036']) + + def create(self, validated_data): + """ + to create password + :return: user + """ + user = validated_data.get('user') + user.set_password(validated_data.get('password')) + user.save() + return user diff --git a/web_admin/urls.py b/web_admin/urls.py index 95228ad..5fbe21e 100644 --- a/web_admin/urls.py +++ b/web_admin/urls.py @@ -7,7 +7,7 @@ from rest_framework import routers # local imports from web_admin.views.article import ArticleViewSet, DefaultArticleCardImagesViewSet, UserManagementViewSet -from web_admin.views.auth import ForgetAndResetPasswordViewSet +from web_admin.views.auth import ForgotAndResetPasswordViewSet # initiate router router = routers.SimpleRouter() @@ -17,7 +17,7 @@ router.register('default-card-images', DefaultArticleCardImagesViewSet, basename router.register('user', UserManagementViewSet, basename='user') # forgot and reset password api for admin -router.register('admin', ForgetAndResetPasswordViewSet, basename='admin') +router.register('admin', ForgotAndResetPasswordViewSet, basename='admin') urlpatterns = [ path('api/v1/', include(router.urls)), diff --git a/web_admin/views/auth.py b/web_admin/views/auth.py index 84835cb..2129600 100644 --- a/web_admin/views/auth.py +++ b/web_admin/views/auth.py @@ -2,26 +2,32 @@ web_admin auth views file """ # django imports -from rest_framework.viewsets import GenericViewSet, mixins +from rest_framework.viewsets import GenericViewSet from rest_framework.decorators import action from django.contrib.auth import get_user_model # local imports from account.utils import custom_response -from base.constants import USER_TYPE -from base.messages import SUCCESS_CODE, ERROR_CODE -from web_admin.permission import AdminPermission -from web_admin.serializers.auth_serializer import AdminForgotPasswordSerializer, AdminVerifyOTPSerializer +from base.messages import SUCCESS_CODE +from web_admin.serializers.auth_serializer import (AdminForgotPasswordSerializer, AdminVerifyOTPSerializer, + AdminCreatePasswordSerializer) USER = get_user_model() -class ForgetAndResetPasswordViewSet(GenericViewSet): +class ForgotAndResetPasswordViewSet(GenericViewSet): + """ + to reset admin password + """ queryset = None @action(methods=['post'], url_name='forgot-password', url_path='forgot-password', detail=False, serializer_class=AdminForgotPasswordSerializer) def admin_forgot_password(self, request): + """ + api method to send otp + :return: success message + """ serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() @@ -30,6 +36,10 @@ class ForgetAndResetPasswordViewSet(GenericViewSet): @action(methods=['post'], url_name='verify-otp', url_path='verify-otp', detail=False, serializer_class=AdminVerifyOTPSerializer) def admin_verify_otp(self, request): + """ + api method to verify otp + :return: success message + """ serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) return custom_response(SUCCESS_CODE['3011']) @@ -37,7 +47,23 @@ class ForgetAndResetPasswordViewSet(GenericViewSet): @action(methods=['post'], url_name='resend-otp', url_path='resend-otp', detail=False, serializer_class=AdminForgotPasswordSerializer) def admin_resend_otp(self, request): + """ + api method to resend otp + :return: success message + """ serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return custom_response(SUCCESS_CODE['3015']) + + @action(methods=['post'], url_name='create-password', url_path='create-password', + detail=False, serializer_class=AdminCreatePasswordSerializer) + def admin_create_password(self, request): + """ + api method to create new password + :return: success message + """ + serializer = self.serializer_class(data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save() + return custom_response(SUCCESS_CODE['3007'])