diff --git a/app/main.py b/app/main.py index 2e2a539..5b7dfbd 100644 --- a/app/main.py +++ b/app/main.py @@ -1,11 +1,13 @@ -from fastapi import FastAPI +from fastapi import FastAPI, Request +from fastapi.exceptions import RequestValidationError +from fastapi.responses import JSONResponse from starlette.middleware.authentication import AuthenticationMiddleware import uvicorn from app.database import engine, Base from app.models import * -from app.routers import chargepoint_v1, user_v1, ocpp_v1 +from app.routers import chargepoint_v1, id_token_v1, ocpp_v1, user_v1 from app.util.websocket_auth_backend import BasicAuthBackend Base.metadata.create_all(bind=engine) @@ -25,6 +27,7 @@ def create_app(): ) app.include_router(chargepoint_v1.router, prefix="/v1") + app.include_router(id_token_v1.router, prefix="/v1") app.include_router(user_v1.router, prefix="/v1") app.mount(path="/v1/ocpp", app=create_ocpp_app()) diff --git a/app/models/id_token.py b/app/models/id_token.py index 61651b2..12430bd 100644 --- a/app/models/id_token.py +++ b/app/models/id_token.py @@ -8,7 +8,7 @@ class IdToken(Base): __tablename__ = "id_tokens" id = Column(Uuid, primary_key=True, default=uuid.uuid4) - title = Column(String) + friendly_name = Column(String) is_active = Column(Boolean, default=True) token = Column(String, index=True) diff --git a/app/routers/chargepoint_v1.py b/app/routers/chargepoint_v1.py index 01d2b72..35d78f1 100644 --- a/app/routers/chargepoint_v1.py +++ b/app/routers/chargepoint_v1.py @@ -12,8 +12,8 @@ from app.models.chargepoint import ChargePoint as DbChargePoint from app.security import get_api_key router = APIRouter( - prefix="/chargepoint", - tags=["chargepoint (v1)"], + prefix="/chargepoints", + tags=["Chargepoint (v1)"], ) @router.get(path="", response_model=list[ChargePoint]) diff --git a/app/routers/id_token_v1.py b/app/routers/id_token_v1.py new file mode 100644 index 0000000..017aaaa --- /dev/null +++ b/app/routers/id_token_v1.py @@ -0,0 +1,96 @@ +from uuid import UUID +from fastapi import APIRouter, HTTPException, Security +from fastapi.exceptions import RequestValidationError +from fastapi.params import Depends +from sqlalchemy.orm import Session + +from app.database import get_db +from app.schemas.id_token import IdToken, IdTokenCreate, IdTokenUpdate +from app.models.id_token import IdToken as DbIdToken +from app.models.user import User as DbUser +from app.security import get_api_key + +router = APIRouter( + prefix="/id-tokens", + tags=["IdToken (v1)"] +) + +@router.get(path="", response_model=list[IdToken]) +async def get_it_tokens( + skip: int = 0, + limit: int = 20, + api_key: str = Security(get_api_key), + db: Session = Depends(get_db) +): + return db.query(DbIdToken).offset(skip).limit(limit).all() + +@router.get(path="/{id_token_id}", response_model=IdToken) +async def get_id_token( + id_token_id: UUID, + api_key: str = Security(get_api_key), + db: Session = Depends(get_db) +): + id_token = db.get(DbIdToken, id_token_id) + if id_token == None: + raise HTTPException(status_code=404, detail="IdToken not found") + return id_token + +@router.post(path="", status_code=201, response_model=IdToken) +async def create_id_token( + create_id_token: IdTokenCreate, + api_key: str = Security(get_api_key), + db: Session = Depends(get_db) +): + owner = db.get(DbUser, create_id_token.owner_id) + if owner == None: + raise HTTPException(status_code=422, detail=[{ + "loc": ["body", "owner_id"], + "msg": "Owner not found", + "type": "invalid_relation" + }]) + id_token = DbIdToken( + friendly_name=create_id_token.friendly_name, + is_active=create_id_token.is_active, + token=create_id_token.token, + owner_id=create_id_token.owner_id + ) + db.add(id_token) + db.commit() + db.refresh(id_token) + return id_token + +@router.patch(path="/{id_token_id}", response_model=IdToken) +async def update_id_token( + id_token_id: UUID, + id_token_update: IdTokenUpdate, + api_key: str = Security(get_api_key), + db: Session = Depends(get_db) +): + id_token = db.get(DbIdToken, id_token_id) + if id_token is None: + raise HTTPException(status_code=404, detail="IdToken not found") + for key, value in id_token_update.model_dump(exclude_unset=True).items(): + if key == "owner_id": + owner = db.get(DbUser, value) + if owner == None: + raise HTTPException(status_code=422, detail=[{ + "loc": ["body", "owner_id"], + "msg": "Owner not found", + "type": "invalid_relation" + }]) + setattr(id_token, key, value) + db.commit() + return id_token + +@router.delete(path="/{id_token_id}", response_model=None) +async def delete_id_token( + id_token_id: UUID, + api_key: str = Security(get_api_key), + db: Session = Depends(get_db) +): + id_token = db.get(DbIdToken, id_token_id) + if id_token == None: + raise HTTPException(status_code=404, detail="IdToken not found") + db.delete(id_token) + db.commit() + return [] diff --git a/app/routers/user_v1.py b/app/routers/user_v1.py index 064bc78..5655dad 100644 --- a/app/routers/user_v1.py +++ b/app/routers/user_v1.py @@ -9,8 +9,8 @@ from app.models.user import User as DbUser from app.security import get_api_key router = APIRouter( - prefix="/user", - tags=["user (v1)"], + prefix="/users", + tags=["User (v1)"], ) @router.get(path="", response_model=list[User]) diff --git a/app/schemas/id_token.py b/app/schemas/id_token.py index d279913..b8c5e06 100644 --- a/app/schemas/id_token.py +++ b/app/schemas/id_token.py @@ -1,18 +1,25 @@ +from typing import Optional from uuid import UUID from pydantic import BaseModel from app.schemas.user import User class IdTokenBase(BaseModel): - title: str + friendly_name: str is_active: bool + owner_id: UUID + token: str class IdTokenCreate(IdTokenBase): pass +class IdTokenUpdate(BaseModel): + friendly_name: Optional[str] = None + is_active: Optional[bool] = None + owner_id: Optional[UUID] = None + class IdToken(IdTokenBase): id: UUID - owner: User class Config: from_attributes = True \ No newline at end of file