new api service and logic implemented

This commit is contained in:
2025-01-23 22:27:25 +03:00
parent d91ecda9df
commit 32022ca521
245 changed files with 28004 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
"""Base models for MongoDB documents."""
from typing import Any, Dict, Optional, Union
from bson import ObjectId
from pydantic import BaseModel, ConfigDict, Field, model_validator
from pydantic.json_schema import JsonSchemaValue
from pydantic_core import CoreSchema, core_schema
from ApiLibrary import system_arrow
class PyObjectId(ObjectId):
"""Custom type for handling MongoDB ObjectId in Pydantic models."""
@classmethod
def __get_pydantic_core_schema__(
cls,
_source_type: Any,
_handler: Any,
) -> CoreSchema:
"""Define the core schema for PyObjectId."""
return core_schema.json_or_python_schema(
json_schema=core_schema.str_schema(),
python_schema=core_schema.union_schema(
[
core_schema.is_instance_schema(ObjectId),
core_schema.chain_schema(
[
core_schema.str_schema(),
core_schema.no_info_plain_validator_function(cls.validate),
]
),
]
),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda x: str(x),
return_schema=core_schema.str_schema(),
when_used="json",
),
)
@classmethod
def validate(cls, value: Any) -> ObjectId:
"""Validate and convert the value to ObjectId."""
if not ObjectId.is_valid(value):
raise ValueError("Invalid ObjectId")
return ObjectId(value)
@classmethod
def __get_pydantic_json_schema__(
cls,
_core_schema: CoreSchema,
_handler: Any,
) -> JsonSchemaValue:
"""Define the JSON schema for PyObjectId."""
return {"type": "string"}
class MongoBaseModel(BaseModel):
"""Base model for all MongoDB documents."""
model_config = ConfigDict(
arbitrary_types_allowed=True,
json_encoders={ObjectId: str},
populate_by_name=True,
from_attributes=True,
validate_assignment=True,
extra="allow",
)
# Optional _id field that will be ignored in create operations
id: Optional[PyObjectId] = Field(None, alias="_id")
def get_extra(self, field_name: str, default: Any = None) -> Any:
"""Safely get extra field value.
Args:
field_name: Name of the extra field to retrieve
default: Default value to return if field doesn't exist
Returns:
Value of the extra field if it exists, otherwise the default value
"""
return getattr(self, field_name, default)
def as_dict(self) -> Dict[str, Any]:
"""Convert model to dictionary including all fields and extra fields.
Returns:
Dict containing all model fields and extra fields with proper type conversion
"""
return self.model_dump(by_alias=True)
class MongoDocument(MongoBaseModel):
"""Base document model with timestamps."""
created_at: float = Field(default_factory=lambda: system_arrow.now().timestamp())
updated_at: float = Field(default_factory=lambda: system_arrow.now().timestamp())
@model_validator(mode="before")
@classmethod
def prevent_protected_fields(cls, data: Any) -> Any:
"""Prevent user from setting protected fields like _id and timestamps."""
if isinstance(data, dict):
# Remove protected fields from input
data.pop("_id", None)
data.pop("created_at", None)
data.pop("updated_at", None)
# Set timestamps
data["created_at"] = system_arrow.now().timestamp()
data["updated_at"] = system_arrow.now().timestamp()
return data

View File

@@ -0,0 +1,76 @@
"""
MongoDB Domain Models.
This module provides Pydantic models for domain management,
including domain history and access details.
"""
from datetime import datetime
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field, ConfigDict, model_validator
from ApiLibrary import system_arrow
from Services.MongoDb.Models.action_models.base import MongoBaseModel, MongoDocument
class DomainData(MongoBaseModel):
"""Model for domain data.
Attributes:
user_uu_id: Unique identifier of the user
main_domain: Primary domain
other_domains_list: List of additional domains
extra_data: Additional domain-related data
"""
user_uu_id: str = Field(..., description="User's unique identifier")
main_domain: str = Field(..., description="Primary domain")
other_domains_list: List[str] = Field(
default_factory=list, description="List of additional domains"
)
extra_data: Optional[Dict[str, Any]] = Field(
default_factory=dict,
alias="extraData",
description="Additional domain-related data",
)
model_config = ConfigDict(
from_attributes=True, populate_by_name=True, validate_assignment=True
)
class DomainDocument(MongoDocument):
"""Model for domain-related documents."""
data: DomainData = Field(..., description="Domain data")
def update_main_domain(self, new_domain: str) -> None:
"""Update the main domain and move current to history.
Args:
new_domain: New main domain to set
"""
if self.data.main_domain and self.data.main_domain != new_domain:
if self.data.main_domain not in self.data.other_domains_list:
self.data.other_domains_list.append(self.data.main_domain)
self.data.main_domain = new_domain
class DomainDocumentCreate(MongoDocument):
"""Model for creating new domain documents."""
data: DomainData = Field(..., description="Initial domain data")
model_config = ConfigDict(
from_attributes=True, populate_by_name=True, validate_assignment=True
)
class DomainDocumentUpdate(MongoDocument):
"""Model for updating existing domain documents."""
data: DomainData = Field(..., description="Updated domain data")
model_config = ConfigDict(
from_attributes=True, populate_by_name=True, validate_assignment=True
)

View File

@@ -0,0 +1,49 @@
"""
MongoDB Password Models.
This module provides Pydantic models for password management,
including password history and access details.
"""
from datetime import datetime
from typing import Any, Dict, List, Optional
from pydantic import Field
from ApiLibrary import system_arrow
from Services.MongoDb.Models.action_models.base import MongoBaseModel, MongoDocument
class PasswordHistoryDetail(MongoBaseModel):
"""Model for password history details."""
timestamp: datetime
ip_address: Optional[str] = Field(None, alias="ipAddress")
user_agent: Optional[str] = Field(None, alias="userAgent")
location: Optional[Dict[str, Any]] = None
class PasswordHistoryData(MongoBaseModel):
"""Model for password history data."""
password_history: List[str] = Field([], alias="passwordHistory")
access_history_detail: Dict[str, PasswordHistoryDetail] = Field(
default_factory=dict, alias="accessHistoryDetail"
)
class PasswordDocument(MongoDocument):
"""Model for password-related documents."""
data: PasswordHistoryData
class PasswordDocumentCreate(MongoBaseModel):
"""Model for creating new password documents."""
data: PasswordHistoryData = Field(..., description="Initial password data")
class PasswordDocumentUpdate(MongoBaseModel):
"""Model for updating existing password documents."""
data: PasswordHistoryData