mirror of
https://github.com/i701/sarlink-portal-api.git
synced 2025-04-19 17:36:53 +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:
parent
9f3f586181
commit
e0a80d4a00
@ -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)
|
||||
|
@ -2,24 +2,31 @@ aiohappyeyeballs==2.4.3
|
||||
aiohttp==3.11.2
|
||||
aiohttp-retry==2.8.3
|
||||
aiosignal==1.3.1
|
||||
amqp==5.3.1
|
||||
anyio==4.9.0
|
||||
arabic-reshaper==3.0.0
|
||||
asgiref==3.8.1
|
||||
asn1crypto==1.5.1
|
||||
async-timeout==4.0.3
|
||||
attrs==24.2.0
|
||||
billiard==4.2.1
|
||||
black==23.12.1
|
||||
boto3==1.35.49
|
||||
botocore==1.35.49
|
||||
celery==5.5.1
|
||||
certifi==2024.2.2
|
||||
cffi==1.16.0
|
||||
chardet==5.2.0
|
||||
charset-normalizer==3.3.2
|
||||
click==8.1.7
|
||||
click-didyoumean==0.3.1
|
||||
click-plugins==1.1.1
|
||||
click-repl==0.3.0
|
||||
colorama==0.4.6
|
||||
cryptography==41.0.7
|
||||
cssselect2==0.7.0
|
||||
dj-database-url==2.1.0
|
||||
django==5.1.2
|
||||
django==5.2
|
||||
django-cors-headers==4.3.1
|
||||
django-debug-toolbar==4.2.0
|
||||
django-easy-audit==1.3.7
|
||||
@ -38,15 +45,20 @@ djangorestframework-simplejwt==5.3.1
|
||||
djangorestframework-stubs==3.15.1
|
||||
dnspython==2.4.2
|
||||
drf-spectacular==0.27.2
|
||||
exceptiongroup==1.2.2
|
||||
faker==30.8.0
|
||||
frozenlist==1.5.0
|
||||
gunicorn==23.0.0
|
||||
h11==0.14.0
|
||||
html5lib==1.1
|
||||
httpcore==1.0.7
|
||||
httpx==0.28.1
|
||||
idna==3.6
|
||||
inflection==0.5.1
|
||||
jmespath==1.0.1
|
||||
jsonschema==4.23.0
|
||||
jsonschema-specifications==2024.10.1
|
||||
kombu==5.5.2
|
||||
lxml==5.1.0
|
||||
multidict==6.1.0
|
||||
mypy-extensions==1.0.0
|
||||
@ -55,6 +67,7 @@ packaging==23.2
|
||||
pathspec==0.12.1
|
||||
pillow==10.2.0
|
||||
platformdirs==4.1.0
|
||||
prompt-toolkit==3.0.50
|
||||
propcache==0.2.0
|
||||
psycopg==3.2.3
|
||||
psycopg-binary==3.2.3
|
||||
@ -70,6 +83,7 @@ pypng==0.20220715.0
|
||||
python-bidi==0.4.2
|
||||
python-dateutil==2.9.0.post0
|
||||
python-decouple==3.8
|
||||
python-telegram-bot==22.0
|
||||
pytz==2023.3.post1
|
||||
pyyaml==6.0.1
|
||||
qrcode==7.4.2
|
||||
@ -81,11 +95,13 @@ rpds-py==0.21.0
|
||||
ruff==0.7.0
|
||||
s3transfer==0.10.3
|
||||
six==1.16.0
|
||||
sniffio==1.3.1
|
||||
sqlparse==0.5.1
|
||||
svglib==1.5.1
|
||||
tinycss2==1.2.1
|
||||
tomli==2.0.2
|
||||
toposort==1.10
|
||||
twilio==9.3.7
|
||||
types-pyyaml==6.0.12.20240917
|
||||
types-requests==2.32.0.20241016
|
||||
typing-extensions==4.12.2
|
||||
@ -94,6 +110,8 @@ tzlocal==5.2
|
||||
uritemplate==4.1.1
|
||||
uritools==4.0.2
|
||||
urllib3==2.2.1
|
||||
vine==5.1.0
|
||||
wcwidth==0.2.13
|
||||
webencodings==0.5.1
|
||||
whitenoise==6.7.0
|
||||
yarl==1.17.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user