first commit
This commit is contained in:
commit
d416fe4cce
69 changed files with 8269 additions and 0 deletions
0
backend/app/api/__init__.py
Normal file
0
backend/app/api/__init__.py
Normal file
43
backend/app/api/auth.py
Normal file
43
backend/app/api/auth.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||
|
||||
from app.core.security import create_access_token
|
||||
from app.db.mongo import get_database
|
||||
from app.schemas.auth import (
|
||||
AuthBootstrapResponse,
|
||||
AuthLoginBootstrapRequest,
|
||||
AuthLoginRequest,
|
||||
AuthSignupRequest,
|
||||
AuthTokenResponse,
|
||||
)
|
||||
from app.services.auth import create_account, get_account_by_identifier, verify_account_login
|
||||
|
||||
router = APIRouter(prefix="/auth", tags=["auth"])
|
||||
|
||||
|
||||
@router.post("/signup", response_model=AuthTokenResponse)
|
||||
async def signup(payload: AuthSignupRequest, database: AsyncIOMotorDatabase = Depends(get_database)) -> AuthTokenResponse:
|
||||
owner_id = await create_account(database, payload)
|
||||
access_token = create_access_token(owner_id)
|
||||
return AuthTokenResponse(accessToken=access_token, ownerId=owner_id)
|
||||
|
||||
|
||||
@router.post("/bootstrap", response_model=AuthBootstrapResponse)
|
||||
async def bootstrap(
|
||||
payload: AuthLoginBootstrapRequest,
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> AuthBootstrapResponse:
|
||||
account = await get_account_by_identifier(database, payload.identifierType.value, payload.identifier)
|
||||
return AuthBootstrapResponse(
|
||||
identifierType=payload.identifierType,
|
||||
identifier=account["identifier"],
|
||||
saltAuth=account["saltAuth"],
|
||||
saltEnc=account["saltEnc"],
|
||||
)
|
||||
|
||||
|
||||
@router.post("/login", response_model=AuthTokenResponse)
|
||||
async def login(payload: AuthLoginRequest, database: AsyncIOMotorDatabase = Depends(get_database)) -> AuthTokenResponse:
|
||||
owner_id = await verify_account_login(database, payload)
|
||||
access_token = create_access_token(owner_id)
|
||||
return AuthTokenResponse(accessToken=access_token, ownerId=owner_id)
|
||||
61
backend/app/api/children.py
Normal file
61
backend/app/api/children.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||
|
||||
from app.dependencies.auth import get_current_owner_id
|
||||
from app.db.mongo import get_database
|
||||
from app.schemas.records import ChildCreateRequest, ChildRecordResponse, ChildUpdateRequest
|
||||
from app.services.records import create_child, delete_child, get_child, list_children, update_child
|
||||
|
||||
router = APIRouter(prefix="/parents/{parent_id}/children", tags=["children"])
|
||||
|
||||
|
||||
@router.post("", response_model=ChildRecordResponse)
|
||||
async def create_child_record(
|
||||
parent_id: str,
|
||||
payload: ChildCreateRequest,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> ChildRecordResponse:
|
||||
if payload.parentId != parent_id:
|
||||
payload = ChildCreateRequest(parentId=parent_id, iv=payload.iv, ciphertext=payload.ciphertext)
|
||||
return await create_child(database, owner_id, payload)
|
||||
|
||||
|
||||
@router.get("", response_model=list[ChildRecordResponse])
|
||||
async def list_child_records(
|
||||
parent_id: str,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> list[ChildRecordResponse]:
|
||||
return await list_children(database, owner_id, parent_id)
|
||||
|
||||
|
||||
@router.get("/{child_id}", response_model=ChildRecordResponse)
|
||||
async def get_child_record(
|
||||
parent_id: str,
|
||||
child_id: str,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> ChildRecordResponse:
|
||||
return await get_child(database, owner_id, parent_id, child_id)
|
||||
|
||||
|
||||
@router.put("/{child_id}", response_model=ChildRecordResponse)
|
||||
async def update_child_record(
|
||||
parent_id: str,
|
||||
child_id: str,
|
||||
payload: ChildUpdateRequest,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> ChildRecordResponse:
|
||||
return await update_child(database, owner_id, parent_id, child_id, payload)
|
||||
|
||||
|
||||
@router.delete("/{child_id}", status_code=204)
|
||||
async def delete_child_record(
|
||||
parent_id: str,
|
||||
child_id: str,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> None:
|
||||
await delete_child(database, owner_id, parent_id, child_id)
|
||||
8
backend/app/api/health.py
Normal file
8
backend/app/api/health.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter(prefix="/health", tags=["health"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def health_check() -> dict[str, str]:
|
||||
return {"status": "ok"}
|
||||
54
backend/app/api/parents.py
Normal file
54
backend/app/api/parents.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||
|
||||
from app.dependencies.auth import get_current_owner_id
|
||||
from app.db.mongo import get_database
|
||||
from app.schemas.records import ParentCreateRequest, ParentRecordResponse, ParentUpdateRequest
|
||||
from app.services.records import create_parent, delete_parent, get_parent, list_parents, update_parent
|
||||
|
||||
router = APIRouter(prefix="/parents", tags=["parents"])
|
||||
|
||||
|
||||
@router.post("", response_model=ParentRecordResponse)
|
||||
async def create_parent_record(
|
||||
payload: ParentCreateRequest,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> ParentRecordResponse:
|
||||
return await create_parent(database, owner_id, payload)
|
||||
|
||||
|
||||
@router.get("", response_model=list[ParentRecordResponse])
|
||||
async def list_parent_records(
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> list[ParentRecordResponse]:
|
||||
return await list_parents(database, owner_id)
|
||||
|
||||
|
||||
@router.get("/{parent_id}", response_model=ParentRecordResponse)
|
||||
async def get_parent_record(
|
||||
parent_id: str,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> ParentRecordResponse:
|
||||
return await get_parent(database, owner_id, parent_id)
|
||||
|
||||
|
||||
@router.put("/{parent_id}", response_model=ParentRecordResponse)
|
||||
async def update_parent_record(
|
||||
parent_id: str,
|
||||
payload: ParentUpdateRequest,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> ParentRecordResponse:
|
||||
return await update_parent(database, owner_id, parent_id, payload)
|
||||
|
||||
|
||||
@router.delete("/{parent_id}", status_code=204)
|
||||
async def delete_parent_record(
|
||||
parent_id: str,
|
||||
owner_id: str = Depends(get_current_owner_id),
|
||||
database: AsyncIOMotorDatabase = Depends(get_database),
|
||||
) -> None:
|
||||
await delete_parent(database, owner_id, parent_id)
|
||||
Loading…
Add table
Add a link
Reference in a new issue