ba-thesis/backend/schemas.py

108 lines
3.4 KiB
Python
Raw Normal View History

2023-05-12 03:59:05 +01:00
from datetime import datetime, date
from abc import ABC
from typing import Optional
from pydantic import BaseModel, validator
from .models import Gender
class AbstractUserInfoValidation(BaseModel, ABC):
@validator('email', check_fields=False)
def assert_email_is_valid(cls, email):
if email is not None:
if not len(email):
raise ValueError("Email must not be empty.")
# TODO implement more robust check
return email
@validator('first_name', check_fields=False)
def assert_first_name_is_valid(cls, first_name):
if first_name is not None:
if not len(first_name):
raise ValueError("First Name must not be empty.")
return first_name
@validator('last_name', check_fields=False)
def assert_last_name_is_valid(cls, last_name):
if last_name is not None:
if not len(last_name):
raise ValueError("Last Name must not be empty.")
return last_name
@validator('date_of_birth', check_fields=False)
def assert_dob_is_valid(cls, dob):
if dob is not None:
if dob >= date.today():
raise ValueError("Date of birth cannot be in the future.")
return dob
class AbstractUser(AbstractUserInfoValidation, ABC):
email: str
first_name: str
last_name: str
gender: Optional[Gender]
date_of_birth: Optional[date]
is_patient: Optional[bool]
is_admin: Optional[bool]
@validator('is_admin')
def assert_tegridy(cls, is_admin, values):
if values['is_patient']:
if is_admin:
raise ValueError('User cannot be both patient and admin.')
for key in ['gender', 'date_of_birth']:
if key not in values or values[key] is None:
raise ValueError(f"Must specify key '{key}' for patients.")
if not values['is_patient'] and not is_admin:
raise ValueError(f'User must either be patient or admin.')
return is_admin
class UserCreate(AbstractUser):
password: str
password_confirmation: str
@validator('password_confirmation')
def assert_passwords_match(cls, password_confirmation, values):
if not password_confirmation == values['password']:
raise ValueError("Passwords do not match.")
if len(password_confirmation) < 1:
# TODO use more robust password rules
raise ValueError("Password must not be empty.")
return password_confirmation
class UserUpdate(AbstractUserInfoValidation):
email: Optional[str]
first_name: Optional[str]
last_name: Optional[str]
gender: Optional[Gender]
date_of_birth: Optional[date]
password: Optional[str] = None
password_confirmation: Optional[str] = None
@validator('password_confirmation')
def assert_passwords_match_or_are_both_none(cls, password_confirmation, values):
password = values.get('password')
if None not in [password, password_confirmation]:
if not password == password_confirmation:
raise ValueError("Passwords do not match.")
if len(password_confirmation) < 1:
# TODO use more robust password rules
raise ValueError("Password must not be empty.")
return password_confirmation
class User(AbstractUser):
id: int
created: datetime
updated: datetime
class Config:
orm_mode = True