Refactoring Hub Firms routes
This commit is contained in:
@@ -5,25 +5,29 @@ from pymongo import IndexModel
|
|||||||
from hub.core import CrudDocument
|
from hub.core import CrudDocument
|
||||||
|
|
||||||
class Firm(CrudDocument):
|
class Firm(CrudDocument):
|
||||||
name: str = Field()
|
|
||||||
instance: str = Field()
|
instance: str = Field()
|
||||||
|
firm: str = Field()
|
||||||
owner: PydanticObjectId = Field()
|
owner: PydanticObjectId = Field()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by_name(cls, instance, firm):
|
||||||
|
return cls.find_one({"instance": instance, "firm": firm})
|
||||||
|
|
||||||
def compute_label(self) -> str:
|
def compute_label(self) -> str:
|
||||||
return self.name
|
return f"{self.instance} / {self.firm}"
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
indexes = [
|
indexes = [
|
||||||
IndexModel(["name", "instance"], unique=True),
|
IndexModel(["instance", "firm"], unique=True),
|
||||||
]
|
]
|
||||||
|
|
||||||
class FirmRead(BaseModel):
|
class FirmRead(BaseModel):
|
||||||
instance: str = Field()
|
instance: str = Field()
|
||||||
name: str = Field()
|
firm: str = Field()
|
||||||
|
|
||||||
class FirmCreate(FirmRead):
|
class FirmCreate(FirmRead):
|
||||||
instance: str = Field(max_length=32, min_length=3, pattern="^[0-9a-z-]+$")
|
instance: str = Field(max_length=32, min_length=3, pattern="^[0-9a-z-]+$")
|
||||||
name: str = Field(max_length=32, min_length=3, pattern="^[0-9a-z-]+$")
|
firm: str = Field(max_length=32, min_length=3, pattern="^[0-9a-z-]+$")
|
||||||
|
|
||||||
class FirmUpdate(BaseModel):
|
class FirmUpdate(BaseModel):
|
||||||
owner: PydanticObjectId = Field()
|
owner: PydanticObjectId = Field()
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
from beanie import PydanticObjectId
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
|
||||||
from hub.auth import get_current_user
|
from hub.auth import get_current_user
|
||||||
@@ -7,42 +6,41 @@ from hub.firm import Firm, FirmRead, FirmCreate, FirmUpdate
|
|||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.get("/", response_model=list[FirmRead], response_description="{} records retrieved".format(Firm.__name__))
|
@router.get("/", response_model=list[FirmRead], response_description="List of firms owned by the current user")
|
||||||
async def read_list(user=Depends(get_current_user)) -> list[FirmRead]:
|
async def read_list(user=Depends(get_current_user)) -> list[FirmRead]:
|
||||||
return await Firm.find({ "owner": user.id}).to_list()
|
return await Firm.find({ "owner": user.id}).to_list()
|
||||||
|
|
||||||
@router.post("/", response_description="{} added to the database".format(Firm.__name__))
|
@router.post("/", response_description="Firm added to the database")
|
||||||
async def create(item: FirmCreate, user=Depends(get_current_user)) -> FirmRead:
|
async def create(item: FirmCreate, user=Depends(get_current_user)) -> FirmRead:
|
||||||
firm_dict = {"name": item.name, "instance": item.instance}
|
exists = await Firm.get_by_name(item.instance, item.firm)
|
||||||
exists = await Firm.find_one(firm_dict)
|
|
||||||
if exists:
|
if exists:
|
||||||
raise HTTPException(status_code=400, detail="Firm already exists")
|
raise HTTPException(status_code=400, detail="Firm already exists")
|
||||||
|
|
||||||
record = Firm(created_by=user.id, updated_by=user.id, owner=user.id, **item.model_dump())
|
record = Firm(created_by=user.id, updated_by=user.id, owner=user.id, **item.model_dump())
|
||||||
o = await record.create()
|
o = await record.create()
|
||||||
user.firms.append(firm_dict)
|
user.firms.append({"instance": item.instance, "firm": item.firm})
|
||||||
await user.save()
|
await user.save()
|
||||||
return FirmRead(**o.model_dump())
|
return FirmRead(**o.model_dump())
|
||||||
|
|
||||||
@router.get("/{id}", response_description="{} record retrieved".format(Firm.__name__))
|
@router.get("/{instance}/{firm}", response_description="Firm retrieved")
|
||||||
async def read_id(id: PydanticObjectId, user=Depends(get_current_user)) -> FirmRead:
|
async def read_id(instance: str, firm: str, user=Depends(get_current_user)) -> FirmRead:
|
||||||
item = await Firm.get(id)
|
item = await Firm.get_by_name(instance, firm)
|
||||||
|
if not item or not user.belong_to(item) not in user.firms:
|
||||||
|
raise HTTPException(status_code=404, detail="Item not found")
|
||||||
|
|
||||||
return FirmRead(**item.model_dump())
|
return FirmRead(**item.model_dump())
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{id}", response_description="{} record updated".format(Firm.__name__))
|
@router.put("/{instance}/{firm}", response_description="Firm updated")
|
||||||
async def update(id: PydanticObjectId, req: FirmUpdate, user=Depends(get_current_user)) -> FirmRead:
|
async def update(instance: str, firm: str, req: FirmUpdate, user=Depends(get_current_user)) -> FirmRead:
|
||||||
item = await Firm.get(id)
|
item = await Firm.get_by_name(instance, firm)
|
||||||
if not item:
|
if not item or not user.belong_to(item) not in user.firms:
|
||||||
raise HTTPException(
|
raise HTTPException(status_code=404, detail="Item not found")
|
||||||
status_code=404,
|
|
||||||
detail="{} record not found!".format(Firm.__name__)
|
|
||||||
)
|
|
||||||
|
|
||||||
if item.owner != user.id:
|
if item.owner != user.id:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=403,
|
status_code=403,
|
||||||
detail="Insufficient credentials to modify {} record".format(Firm.__name__)
|
detail="Insufficient credentials to modify Firm"
|
||||||
)
|
)
|
||||||
|
|
||||||
req = {k: v for k, v in req.model_dump().items() if v is not None}
|
req = {k: v for k, v in req.model_dump().items() if v is not None}
|
||||||
@@ -53,21 +51,19 @@ async def update(id: PydanticObjectId, req: FirmUpdate, user=Depends(get_current
|
|||||||
await item.update(update_query)
|
await item.update(update_query)
|
||||||
return FirmRead(**item.dict())
|
return FirmRead(**item.dict())
|
||||||
|
|
||||||
@router.delete("/{id}", response_description="{} record deleted from the database".format(Firm.__name__))
|
@router.delete("/{instance}/{firm}", response_description="Firm deleted from the database")
|
||||||
async def delete(id: PydanticObjectId, user=Depends(get_current_user)) -> dict:
|
async def delete(instance: str, firm: str, user=Depends(get_current_user)) -> dict:
|
||||||
item = await Firm.get(id)
|
item = await Firm.get_by_name(instance, firm)
|
||||||
if not item:
|
if not item or not user.belong_to(item) not in user.firms:
|
||||||
raise HTTPException(
|
raise HTTPException(status_code=404, detail="Firm not found")
|
||||||
status_code=404,
|
|
||||||
detail="{} record not found!".format(Firm.__name__)
|
|
||||||
)
|
|
||||||
if item.owner != user.id:
|
if item.owner != user.id:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=403,
|
status_code=403,
|
||||||
detail="Insufficient credentials delete {} record".format(Firm.__name__)
|
detail="Insufficient credentials delete Firm"
|
||||||
)
|
)
|
||||||
|
|
||||||
await item.delete()
|
await item.delete()
|
||||||
return {
|
return {
|
||||||
"message": "{} deleted successfully".format(Firm.__name__)
|
"message": "Firm deleted successfully"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,11 @@ from hub.firm import FirmRead
|
|||||||
class UserSchema(BaseUser[PydanticObjectId]):
|
class UserSchema(BaseUser[PydanticObjectId]):
|
||||||
firms: list[FirmRead] = Field()
|
firms: list[FirmRead] = Field()
|
||||||
|
|
||||||
|
def belongs_to(self, firm):
|
||||||
|
for f in self.firms:
|
||||||
|
if f.instance == firm.instance and f.firm == firm.firm :
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
class UserUpdateSchema(BaseUserUpdate):
|
class UserUpdateSchema(BaseUserUpdate):
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user