This commit is contained in:
Sayyid Hamid Mahdavi 2025-11-18 15:15:57 +03:30
parent 193c245c0a
commit f2e8777e6d
4 changed files with 42 additions and 9 deletions

View file

@ -0,0 +1,18 @@
# Generated by Django 5.1.4 on 2025-11-18 11:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0006_alter_user_avatar'),
]
operations = [
migrations.AlterField(
model_name='user',
name='otp',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='otp'),
),
]

View file

@ -5,6 +5,7 @@ from datetime import timedelta
# import service_clients
from django.conf import settings
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.db import models
@ -34,7 +35,7 @@ class UserManager(BaseUserManager):
# TODO: validate phone number
user = self.model(phone_number=phone_number, username=username, email=email, **extra_fields)
user.set_password(password)
user.set_otp()
# user.set_otp()
user.date_joined = timezone.now()
user.save(using=self._db)
@ -113,7 +114,7 @@ class User(AbstractUser):
null=True
)
phone_number = models.CharField(_('phone number'), max_length=30, blank=True, null=True, unique=True)
otp = models.CharField(_('otp'), max_length=6, blank=True, null=True)
otp = models.CharField(_('otp'), max_length=128, blank=True, null=True)
otp_expire = models.DateTimeField(_('otp expire'), blank=True, null=True)
otp_try = models.IntegerField(_('otp try'), blank=True, null=True, default=0)
@ -151,7 +152,11 @@ class User(AbstractUser):
return state.get_province_by_id(self.province)
def set_otp(self):
self.otp = '77501'
if self.otp_expire and (self.otp_expire + timedelta(seconds=MAX_OTP_VALID_DURATION)) > timezone.now():
raise Exception('otp expire time not reached.')
self._otp = '77501'
self.otp = make_password(self._otp)
# if settings.DEBUG or self.phone_number in DEVELOPMENT_PHONE_NUMBERS:
# self.otp = '77501'
#
@ -168,10 +173,10 @@ class User(AbstractUser):
self.ott_expire = timezone.now() + timedelta(seconds=MAX_OTP_VALID_DURATION)
def otp_is_valid(self):
return bool(self.otp and timezone.now() <= self.otp_expire)
return bool(self.otp and self.otp_expire and timezone.now() <= self.otp_expire)
def ott_is_valid(self):
return bool(self.ott and timezone.now() <= self.ott_expire)
return bool(self.ott and self.ott_expire and timezone.now() <= self.ott_expire)
def check_otp(self, otp):
if self.otp_try <= MAX_OTP_TRY:
@ -221,8 +226,8 @@ class User(AbstractUser):
return result
def send_otp(self):
print(self.otp)
self.notify(body=str(self.otp), title='OTP')
print(self._otp)
self.notify(body=str(self._otp), title='OTP')
def notify(self, body, title=None, notification_type='sms'):
message = ("وینسو"

View file

@ -5,6 +5,8 @@ from apps.users.models import User
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from utils.exceptions import UnprocessableEntity
phone_number_validator = RegexValidator(regex=r'^\+98[1-9]\d{9}$', message=_(
"Phone number must be entered in the format: '+989999999999'."
),)
@ -70,8 +72,10 @@ class RequestOTPSerializer(serializers.ModelSerializer):
if not user.otp_is_valid():
user.set_otp()
user.save()
user.send_otp()
user.send_otp()
else:
raise UnprocessableEntity()
self.instance = user
return user

View file

@ -47,4 +47,10 @@ class ErrorMiddleware:
"details": str(exception) # فقط در حالت توسعه! در تولید بهتر است لاگ شود.
},
status=500
)
)
class UnprocessableEntity(APIException):
status_code = 422
default_detail = 'The request was well-formed but cannot be processed due to semantic errors.'
default_code = 'unprocessable_entity'