i701 3957ca0ea4
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 4m58s
Add user verification endpoint and logic; implement check against Person API
2025-06-10 16:42:13 +05:00

140 lines
5.1 KiB
Python

import logging
from typing import List, TypedDict
import requests
from decouple import config
from api.models import User
logger = logging.getLogger(__name__)
def reverse_dhivehi_string(input_str):
"""
Reverses a Dhivehi string while preserving character composition.
Args:
input_str (str): The Dhivehi string to be reversed
Returns:
str: The reversed Dhivehi string
"""
# Reverse the string and then normalize the character order
reversed_str = input_str[::-1]
# List to store the corrected characters
corrected_chars = []
# Iterate through the reversed string
i = 0
while i < len(reversed_str):
# Check if current character is a combining character
if i + 1 < len(reversed_str) and "\u0300" <= reversed_str[i + 1] <= "\u036f":
# If next character is a combining mark, add it before the base character
corrected_chars.append(reversed_str[i + 1] + reversed_str[i])
i += 2
else:
corrected_chars.append(reversed_str[i])
i += 1
return "".join(corrected_chars)
class MismatchResult(TypedDict):
ok: bool
mismatch_fields: List[str]
def check_person_api_verification(
user_data: User,
id_card: str | None,
) -> MismatchResult:
"""
Compares user data with data from the Person API and returns a verification result.
:param user_data: A dictionary containing user information. Expected keys:
'id_card', 'first_name', 'last_name', 'address', 'dob',
'atoll_name', 'island_name'.
:param api_data: A dictionary containing data from the Person API. Expected keys:
'nic', 'name_en', 'house_name_en', 'dob', 'atoll_en',
'island_name_en'.
:return: A dictionary with 'ok' (boolean) and 'mismatch_fields' (list of strings).
"""
PERSON_VERIFY_BASE_URL = config("PERSON_VERIFY_BASE_URL", default="") # type: ignore
if not PERSON_VERIFY_BASE_URL:
raise ValueError(
"PERSON_VERIFY_BASE_URL is not set in the environment variables."
)
print(id_card)
response = requests.get(f"{PERSON_VERIFY_BASE_URL}/api/person/{id_card}")
if response.status_code != 200:
logger.error(
f"Failed to fetch data from Person API for ID Card '{id_card}'. "
f"Status Code: {response.status_code}, Response: {response.text}"
)
return {"ok": False, "mismatch_fields": ["api_error"]}
api_data = response.json()
if not api_data:
logger.error(
f"No data found in Person API for ID Card '{id_card}'. Response: {response.text}"
)
return {"ok": False, "mismatch_fields": ["no_data"]}
# Initialize a list to hold fields that do not match
mismatch_fields = []
# Prepare user data for comparison
user_full_name = f"{user_data.first_name} {user_data.last_name}".strip()
user_dob_iso = user_data.dob.isoformat() if user_data.dob else None
# Prepare API data for comparison
api_nic = api_data.get("nic")
api_name = api_data.get("name_en")
api_house_name = api_data.get("house_name_en")
api_dob = api_data.get("dob")
api_atoll = api_data.get("atoll_en")
api_island_name = api_data.get("island_name_en")
# Perform comparisons and identify mismatches
if user_data.id_card != api_nic:
mismatch_fields.append("id_card")
logger.debug(f"ID Card mismatch: User '{user_data.id_card}' vs API '{api_nic}'")
if user_full_name != api_name:
mismatch_fields.append("name")
logger.debug(f"Name mismatch: User '{user_full_name}' vs API '{api_name}'")
if user_data.address != api_house_name:
mismatch_fields.append("address")
logger.debug(
f"Address mismatch: User '{user_data.address}' vs API '{api_house_name}'"
)
# API DOB might include time component, so split it
api_dob_date_only = api_dob.split("T")[0] if api_dob else None
if user_dob_iso != api_dob_date_only:
mismatch_fields.append("dob")
logger.debug(
f"DOB mismatch: User '{user_dob_iso}' vs API '{api_dob_date_only}'"
)
# Use .strip() for atoll and island names due to potential whitespace
user_atoll_name = user_data.atoll.name if user_data.atoll is not None else None
api_atoll_stripped = api_atoll.strip() if api_atoll else None
if user_atoll_name != api_atoll_stripped:
mismatch_fields.append("atoll")
logger.debug(
f"Atoll mismatch: User '{user_atoll_name}' vs API '{api_atoll_stripped}'"
)
user_island_name = user_data.island.name if user_data.island is not None else None
api_island_name_stripped = api_island_name.strip() if api_island_name else None
if user_island_name != api_island_name_stripped:
mismatch_fields.append("island_name")
logger.debug(
f"Island Name mismatch: User '{user_island_name}' vs API '{api_island_name_stripped}'"
)
if mismatch_fields:
return {"ok": False, "mismatch_fields": mismatch_fields}
else:
return {"ok": True, "mismatch_fields": []}