139 lines
4.6 KiB
Python
Executable File
139 lines
4.6 KiB
Python
Executable File
import re
|
|
from typing import Optional
|
|
|
|
from pydantic import EmailStr, Field, field_validator
|
|
|
|
from app.core.data_types import UUID7Field
|
|
from app.core.exceptions import UnprocessableEntity
|
|
|
|
from .base import BaseSchema
|
|
from .organization_schema import OrganizationWithMapsetSchema
|
|
from .role_schema import RoleSchema
|
|
|
|
|
|
class UserSchema(BaseSchema):
|
|
id: UUID7Field
|
|
name: str
|
|
email: EmailStr
|
|
profile_picture: Optional[str] = None
|
|
username: str
|
|
position: Optional[str] = None
|
|
role: RoleSchema | None
|
|
employee_id: Optional[str] = None
|
|
organization: OrganizationWithMapsetSchema
|
|
is_active: bool = True
|
|
|
|
|
|
class UserCreateSchema(BaseSchema):
|
|
name: str = Field(..., min_length=4, max_length=100)
|
|
email: EmailStr
|
|
profile_picture: Optional[str] = Field(None)
|
|
username: str = Field(None, min_length=3, max_length=30, pattern=r"^[a-zA-Z0-9_]+$")
|
|
password: str = Field(..., min_length=8, max_length=128)
|
|
position: Optional[str] = Field(None)
|
|
role_id: UUID7Field
|
|
employee_id: Optional[str] = None
|
|
organization_id: UUID7Field
|
|
is_active: bool = True
|
|
|
|
@field_validator("password")
|
|
@classmethod
|
|
def validate_password(cls, value):
|
|
if value is None:
|
|
return value
|
|
|
|
has_letter = any(c.isalpha() for c in value)
|
|
has_digit = any(c.isdigit() for c in value)
|
|
has_special = any(c in "@$!%*#?&" for c in value)
|
|
|
|
if not (has_letter and has_digit and has_special):
|
|
raise UnprocessableEntity(
|
|
"Password must be at least 8 characters long and contain at least one letter, one number, and one special character"
|
|
)
|
|
|
|
return value
|
|
|
|
@field_validator("username")
|
|
@classmethod
|
|
def validate_username(cls, value):
|
|
if value is None:
|
|
return value
|
|
|
|
if not re.match(r"^[a-zA-Z0-9_]+$", value):
|
|
raise UnprocessableEntity("Username can only contain letters, numbers, and underscores")
|
|
|
|
return value
|
|
|
|
@field_validator("email")
|
|
@classmethod
|
|
def validate_email_domain(cls, value):
|
|
if value is None:
|
|
return value
|
|
|
|
# Validasi tambahan untuk domain email jika diperlukan
|
|
value.split("@")[1]
|
|
valid_domains = ["gmail.com", "yahoo.com", "hotmail.com", "company.com"] # Sesuaikan dengan kebutuhan
|
|
|
|
# Hapus validasi ini jika tidak diperlukan atau sesuaikan dengan kebutuhan
|
|
# if domain not in valid_domains:
|
|
# raise UnprocessableEntity(f'Domain email tidak valid. Domain yang diizinkan: {", ".join(valid_domains)}')
|
|
|
|
return value
|
|
|
|
|
|
class UserUpdateSchema(BaseSchema):
|
|
name: Optional[str] = Field(None, min_length=2, max_length=100)
|
|
email: Optional[EmailStr] = None
|
|
profile_picture: Optional[str] = Field(None, max_length=255)
|
|
username: Optional[str] = Field(None, min_length=3, max_length=30, pattern=r"^[a-zA-Z0-9_]+$")
|
|
password: Optional[str] = Field(None, min_length=8, max_length=128)
|
|
position: Optional[str] = Field(None)
|
|
role_id: Optional[UUID7Field] = Field(None)
|
|
employee_id: Optional[str] = Field(None, max_length=50)
|
|
organization_id: Optional[UUID7Field] = Field(None)
|
|
is_active: Optional[bool] = None
|
|
|
|
@field_validator("password")
|
|
@classmethod
|
|
def validate_password(cls, value):
|
|
if value is None:
|
|
return value
|
|
|
|
has_letter = any(c.isalpha() for c in value)
|
|
has_digit = any(c.isdigit() for c in value)
|
|
has_special = any(c in "@$!%*#?&" for c in value)
|
|
|
|
if not (has_letter and has_digit and has_special):
|
|
raise UnprocessableEntity(
|
|
"Password must be at least 8 characters long and contain at least one letter, one number, and one special character"
|
|
)
|
|
|
|
return value
|
|
|
|
@field_validator("username")
|
|
@classmethod
|
|
def validate_username(cls, value):
|
|
if value is None:
|
|
return value
|
|
|
|
if not re.match(r"^[a-zA-Z0-9_]+$", value):
|
|
raise UnprocessableEntity("Username can only contain letters, numbers, and underscores")
|
|
|
|
return value
|
|
|
|
@field_validator("email")
|
|
@classmethod
|
|
def validate_email_domain(cls, value):
|
|
if value is None:
|
|
return value
|
|
|
|
# Validasi tambahan untuk domain email jika diperlukan
|
|
value.split("@")[1]
|
|
valid_domains = ["gmail.com", "yahoo.com", "hotmail.com", "company.com"] # Sesuaikan dengan kebutuhan
|
|
|
|
# Hapus validasi ini jika tidak diperlukan atau sesuaikan dengan kebutuhan
|
|
# if domain not in valid_domains:
|
|
# raise UnprocessableEntity(f'Domain email tidak valid. Domain yang diizinkan: {", ".join(valid_domains)}')
|
|
|
|
return value
|