Browse Source

feat(account): add web user registration endpoint and serializer

- Introduced a new endpoint for web user registration at 'web/register/'.
- Created WebUserRegisterSerializer to handle user registration with email and password validation.
- Enhanced UserVerifyView to support password handling during user creation and verification.
master
mortezaei 8 months ago
parent
commit
eb7f044b3b
  1. 29
      apps/account/serializers/user_web.py
  2. 1
      apps/account/urls.py
  3. 46
      apps/account/views/user.py

29
apps/account/serializers/user_web.py

@ -0,0 +1,29 @@
from rest_framework import serializers
from django.contrib.auth.password_validation import validate_password
from apps.account.models import User
class WebUserRegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, validators=[validate_password])
fcm = serializers.CharField(required=False, allow_blank=True, allow_null=True)
email = serializers.EmailField()
class Meta:
model = User
fields = ['id', 'fullname', 'email', 'password', 'fcm']
extra_kwargs = {
'fullname': {'required': True},
'email': {'required': True},
}
def validate_email(self, value):
normalized_email = User.objects.normalize_email(value)
if User.objects.filter(email=normalized_email).exists():
raise serializers.ValidationError("This email is already registered.")
return normalized_email
def create(self, validated_data):
user = super().create(validated_data)
return user

1
apps/account/urls.py

@ -11,6 +11,7 @@ urlpatterns = [
# URL for user registration, accepts POST requests for creating new user instances. # URL for user registration, accepts POST requests for creating new user instances.
path('register/', views.UserRegisterView.as_view(), name='user-register'), path('register/', views.UserRegisterView.as_view(), name='user-register'),
path('web/register/', views.WebUserRegisterView.as_view(), name='web-user-register'),
path('verify/', views.UserVerifyView.as_view(), name='user-verify'), path('verify/', views.UserVerifyView.as_view(), name='user-verify'),
path('login/', views.UserLoginView.as_view(), name='user-login'), path('login/', views.UserLoginView.as_view(), name='user-login'),
path('guest/', views.UserGuestView.as_view(), name='user-guest'), path('guest/', views.UserGuestView.as_view(), name='user-guest'),

46
apps/account/views/user.py

@ -24,6 +24,7 @@ from rest_framework.exceptions import ValidationError
from utils.exceptions import InvaliedCodeVrify, ExpiredCodeException, ServiceUnavailableException from utils.exceptions import InvaliedCodeVrify, ExpiredCodeException, ServiceUnavailableException
from apps.account.models import User from apps.account.models import User
from apps.account.serializers import UserRegisterSerializer, UserProfileSerializer, UserVerifySerializer, UserLoginSerializer, UserRecoverPasswordSerializer, UserResetPasswordSerializer, UserGuestSerializer,UserFCMSerializer from apps.account.serializers import UserRegisterSerializer, UserProfileSerializer, UserVerifySerializer, UserLoginSerializer, UserRecoverPasswordSerializer, UserResetPasswordSerializer, UserGuestSerializer,UserFCMSerializer
from apps.account.serializers.user_web import WebUserRegisterSerializer
from utils.redis import RedisManager from utils.redis import RedisManager
from utils.exceptions import AppAPIException from utils.exceptions import AppAPIException
from utils import send_email, is_valid_email from utils import send_email, is_valid_email
@ -126,7 +127,7 @@ class UserRegisterView(CreateAPIView):
def post(self, request): def post(self, request):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
data = serializer.data
data = serializer.validated_data
code = RedisManager.generate_otp_code() code = RedisManager.generate_otp_code()
logger.info(f"phone= {data['email']}") logger.info(f"phone= {data['email']}")
@ -202,7 +203,7 @@ class UserVerifyView(CreateAPIView):
device_id = kwargs.get('device_id') device_id = kwargs.get('device_id')
user = User.objects.filter(email=email).first() user = User.objects.filter(email=email).first()
if user: if user:
if kwargs['password']:
if kwargs.get('password'):
user.is_active = True user.is_active = True
user.deletion_date = None user.deletion_date = None
if device_id: if device_id:
@ -219,11 +220,13 @@ class UserVerifyView(CreateAPIView):
if not user: if not user:
user = User.objects.create(**kwargs) user = User.objects.create(**kwargs)
user.set_password(kwargs['password'])
if kwargs.get('password'):
user.set_password(kwargs['password'])
else: else:
user.email = email user.email = email
user.fullname = kwargs['fullname'] user.fullname = kwargs['fullname']
user.set_password(kwargs['password'])
if kwargs.get('password'):
user.set_password(kwargs['password'])
if device_id: if device_id:
user.device_id = device_id user.device_id = device_id
user.last_login = timezone.now() user.last_login = timezone.now()
@ -234,6 +237,41 @@ class UserVerifyView(CreateAPIView):
return user return user
class WebUserRegisterView(CreateAPIView):
permission_classes = [AllowAny]
serializer_class = WebUserRegisterSerializer
@swagger_auto_schema(
operation_description="Web registration with password and confirmation",
request_body=WebUserRegisterSerializer,
)
def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
code = RedisManager.generate_otp_code()
logger.info(f"phone= {data['email']}")
print(f'send {code}/{data["email"]}')
# Store all registration data including password in Redis
RedisManager().add_to_redis(code, **data)
try:
send_email([data['email']], code)
except Exception as exp:
print(f'-exp-register-->{exp}')
return Response(
data={
"user": {
"id": data.get('id'),
"fullname": data.get('fullname'),
"email": data.get('email'),
},
"message": "The otp code was sent to the user's email"
},
status=status.HTTP_202_ACCEPTED,
)
class UserLoginView(CreateAPIView): class UserLoginView(CreateAPIView):
permission_classes = [AllowAny] permission_classes = [AllowAny]
serializer_class = UserLoginSerializer serializer_class = UserLoginSerializer

Loading…
Cancel
Save