diff --git a/backend/main.py b/backend/main.py index e889389db3a3ff12d2e2fef9853e47e66da3ef4e..3b9af59a20b603ec2b778f22df81bd3ff8a422d3 100644 --- a/backend/main.py +++ b/backend/main.py @@ -37,12 +37,22 @@ def add_item(item: schemas.ItemCreatePrepareShipping, db: Session = Depends(get_ return utils.prepare_item_shipping(db, item) +@app.post("/item/update/{item_uuid}", response_model=schemas.Item) +def update_item( + item_uuid: str, data: schemas.ItemUpdate, db: Session = Depends(get_db) +): + item = utils.get_item_by_uuid(db, UUID(item_uuid)) + if not item: + raise HTTPException(status_code=404, detail="Item not found") + return utils.update_item(db, item, data) + + @app.get("/item/{item_uuid}", response_model=schemas.Item) def get_item(item_uuid: str, db: Session = Depends(get_db)): item = utils.get_item_by_uuid(db, UUID(item_uuid)) if not item: raise HTTPException(status_code=404, detail="Item not found") - return utils.get_item_by_uuid(db, UUID(item_uuid)) + return item @app.get("/tag/{tag}", response_model=schemas.Item) @@ -50,7 +60,7 @@ def get_item_by_tag(tag: str, db: Session = Depends(get_db)): item = utils.get_item_by_tag(db, tag) if not item: raise HTTPException(status_code=404, detail="Item not found") - return utils.get_item_by_tag(db, tag) + return item @app.get("/storages", response_model=list[schemas.Storage]) diff --git a/backend/models.py b/backend/models.py index fafdc65c8000fd195d6c7a9a3243917f941f8c3c..84c1cdbed82fa8036e9b9053f3b814e941dd4b95 100644 --- a/backend/models.py +++ b/backend/models.py @@ -4,7 +4,6 @@ from sqlalchemy import Column as sql_Column from sqlalchemy import DateTime as sql_DateTime from sqlalchemy import ForeignKey as sql_ForeignKey from sqlalchemy import Integer as sql_Integer -from sqlalchemy import LargeBinary as sql_LargeBinary from sqlalchemy import String as sql_String from sqlalchemy import Uuid as sql_Uuid from sqlalchemy.orm import relationship as sql_relationship @@ -28,7 +27,7 @@ class Item(db_Base): deployed = sql_Column(sql_String(64), nullable=True, default=None) deployed_at = sql_Column(sql_DateTime(timezone=True), nullable=True, default=None) - verification = sql_Column(sql_LargeBinary(57), nullable=True, default=None) + verification = sql_Column(sql_String(114), nullable=True, default=None) tag = sql_Column(sql_String(6), nullable=True, default=None) storage = sql_Column( diff --git a/backend/schemas.py b/backend/schemas.py index 5ecec4a32f6afe9813b44a0bdcd7df95dac2682f..27f025e3fd556f674e46934809098545c8673eb3 100644 --- a/backend/schemas.py +++ b/backend/schemas.py @@ -12,7 +12,7 @@ class Image(BaseModel): class ItemCreatePrepareShipping(BaseModel): - verification: bytes + verification: str addressee: Union[str, None] = None team: Union[str, None] = None @@ -28,6 +28,13 @@ class ItemCheckin(BaseModel): amount: Union[int, None] = 1 +class ItemUpdate(BaseModel): + addressee: Union[str, None] = None + team: Union[str, None] = None + amount: Union[int, None] = None + signature: str + + class Item(BaseModel): uuid: UUID4 amount: int @@ -41,7 +48,7 @@ class Item(BaseModel): deployed: Union[str, None] = None deployed_at: Union[datetime, None] = None - verification: Union[bytes, None] = None + verification: Union[str, None] = None tag: Union[str, None] = None storage: Union[str, None] = None diff --git a/backend/utils.py b/backend/utils.py index 35e435f19bec89599c10b303bbfe20caa601bc3f..26068dd4be06af6b0b6f896dc7fcd24b6a4c23d3 100644 --- a/backend/utils.py +++ b/backend/utils.py @@ -1,6 +1,8 @@ from datetime import datetime from secrets import token_hex +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PublicKey from pydantic import UUID4 from sqlalchemy.orm import Session @@ -40,6 +42,27 @@ def prepare_item_shipping(db: Session, item: schemas.ItemCreatePrepareShipping): return new_item +def update_item(db: Session, item: schemas.Item, data: schemas.ItemUpdate): + public_key = Ed448PublicKey.from_public_bytes(bytes.fromhex(item.verification)) + verify = "" + if data.addressee: + verify += data.addressee + item.addressee = data.addressee + if data.team: + verify += data.team + item.team = data.team + if data.amount: + verify += str(data.amount) + item.amount = data.amount + try: + public_key.verify(bytes.fromhex(data.signature), bytes(verify, "utf-8")) + except InvalidSignature: + return None + db.commit() + db.refresh(item) + return item + + def receive_item_with_image(db: Session, item: schemas.ItemCreateByImageAtStorage): new_item = models.Item(storage_uuid=item.storage_uuid) db.add(new_item) diff --git a/requirements.txt b/requirements.txt index 0b123ed90a494602ea277e9ae0b79da0ee73f784..eab79be612cede5d6cbc159823389523c162a6c6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +cryptography==41.0.1 fastapi==0.95.1 Jinja2==3.1.2 python-multipart==0.0.6