mirror of
https://github.com/i701/sarlink-portal-api.git
synced 2025-06-28 05:26:07 +00:00
registration and verify abuse WIP
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 1m27s
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 1m27s
This commit is contained in:
@ -2,10 +2,12 @@
|
||||
This is the models module for api.
|
||||
"""
|
||||
|
||||
from datetime import timedelta
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from .managers import CustomUserManager
|
||||
from django.utils import timezone
|
||||
import pyotp
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
@ -34,6 +36,22 @@ class User(AbstractUser):
|
||||
objects = CustomUserManager()
|
||||
|
||||
|
||||
class TemporaryUser(User):
|
||||
otp_secret = models.CharField(max_length=50, default=pyotp.random_base32)
|
||||
otp_verified = models.BooleanField(default=False)
|
||||
|
||||
def generate_otp(self):
|
||||
totp = pyotp.TOTP(self.otp_secret, interval=300)
|
||||
return totp.now()
|
||||
|
||||
def verify_otp(self, otp):
|
||||
totp = pyotp.TOTP(self.otp_secret, interval=300)
|
||||
return totp.verify(otp)
|
||||
|
||||
def is_expired(self):
|
||||
return self.created_at < timezone.now() - timedelta(minutes=5)
|
||||
|
||||
|
||||
class Atoll(models.Model):
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
|
@ -139,3 +139,8 @@ class AtollSerializer(serializers.ModelSerializer):
|
||||
model = Atoll
|
||||
fields = "__all__"
|
||||
depth = 2
|
||||
|
||||
|
||||
class OTPVerificationSerializer(serializers.Serializer):
|
||||
mobile = serializers.CharField()
|
||||
otp = serializers.CharField()
|
||||
|
@ -6,6 +6,8 @@ from django_rest_passwordreset.signals import reset_password_token_created
|
||||
from django.db.models.signals import post_save
|
||||
from api.models import User
|
||||
from django.contrib.auth.models import Permission
|
||||
from api.tasks import verify_user_with_person_api_task
|
||||
from asgiref.sync import sync_to_async
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
@ -26,6 +28,13 @@ def assign_device_permissions(sender, instance, created, **kwargs):
|
||||
instance.user_permissions.add(permission)
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
@sync_to_async
|
||||
def verify_user_with_person_api(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
verify_user_with_person_api_task(instance.id)
|
||||
|
||||
|
||||
@receiver(reset_password_token_created)
|
||||
def password_reset_token_created(
|
||||
sender, instance, reset_password_token, *args, **kwargs
|
||||
|
41
api/tasks.py
Normal file
41
api/tasks.py
Normal file
@ -0,0 +1,41 @@
|
||||
from django.shortcuts import get_object_or_404
|
||||
from api.models import User
|
||||
import requests
|
||||
from apibase.env import env, BASE_DIR
|
||||
import os
|
||||
|
||||
PERSON_API_URL = env.str("PERSON_VERIFY_BASE_URL", "")
|
||||
|
||||
env.read_env(os.path.join(BASE_DIR, ".env"))
|
||||
|
||||
|
||||
def verify_user_with_person_api_task(user_id: int):
|
||||
"""
|
||||
Verify the user with the Person API.
|
||||
:param user_id: The ID of the user to verify.
|
||||
"""
|
||||
|
||||
user = get_object_or_404(User, id=user_id)
|
||||
# Call the Person API to verify the user
|
||||
response = requests.get(f"{PERSON_API_URL}/api/person/{user.id_card}")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"Data from Person API: {data}")
|
||||
print("Data from of user: ", user.__dict__)
|
||||
if (
|
||||
data.get("nic") == user.id_card
|
||||
and data.get("name_en") == f"{user.first_name} {user.last_name}"
|
||||
and data.get("house_name_en") == user.address
|
||||
and data.get("dob") == user.dob.isoformat()
|
||||
):
|
||||
user.verified = True
|
||||
user.save()
|
||||
return True
|
||||
else:
|
||||
user.verified = False
|
||||
user.save()
|
||||
return False
|
||||
else:
|
||||
# Handle the error case
|
||||
print(f"Error verifying user: {response.status_code} - {response.text}")
|
||||
return False
|
13
api/views.py
13
api/views.py
@ -43,6 +43,7 @@ ACCOUNT_NUMBER_PATTERN = r"^(7\d{12}|9\d{16})$"
|
||||
|
||||
class ErrorMessages:
|
||||
USERNAME_EXISTS = "Username already exists."
|
||||
MOBILE_EXISTS = "Mobile number already exists."
|
||||
INVALID_ID_CARD = "Please enter a valid ID card number."
|
||||
INVALID_MOBILE = "Please enter a valid mobile number."
|
||||
INVALID_ACCOUNT = "Please enter a valid account number."
|
||||
@ -99,12 +100,9 @@ class CreateUserView(generics.CreateAPIView):
|
||||
firstname = request.data.get("firstname")
|
||||
lastname = request.data.get("lastname")
|
||||
|
||||
# Validate required fields first
|
||||
validation_error = self.validate_required_fields(request.data)
|
||||
if validation_error:
|
||||
return validation_error
|
||||
if User.objects.filter(mobile=mobile).exists():
|
||||
return Response({"message": ErrorMessages.MOBILE_EXISTS}, status=400)
|
||||
|
||||
# Check username uniqueness after validation
|
||||
if User.objects.filter(username=username).exists():
|
||||
return Response({"message": ErrorMessages.USERNAME_EXISTS}, status=400)
|
||||
|
||||
@ -120,6 +118,11 @@ class CreateUserView(generics.CreateAPIView):
|
||||
if acc_no is None or not re.match(ACCOUNT_NUMBER_PATTERN, acc_no):
|
||||
return Response({"message": ErrorMessages.INVALID_ACCOUNT}, status=400)
|
||||
|
||||
# Validate required fields first
|
||||
validation_error = self.validate_required_fields(request.data)
|
||||
if validation_error:
|
||||
return validation_error
|
||||
|
||||
# Fetch Atoll and Island instances
|
||||
try:
|
||||
atoll = Atoll.objects.get(id=atoll_id)
|
||||
|
Reference in New Issue
Block a user