From 1ef102de8a9d1c575c04cecb0cf25d19f2f88e17 Mon Sep 17 00:00:00 2001 From: kompotkot Date: Wed, 14 Aug 2024 13:16:12 +0000 Subject: [PATCH] Updated and delete registered contract using resources --- engineapi/engineapi/contracts_actions.py | 27 +++++++++++----- engineapi/engineapi/routes/metatx.py | 40 ++++++++++++++++++++---- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/engineapi/engineapi/contracts_actions.py b/engineapi/engineapi/contracts_actions.py index b3cb0f46..bb26a6ec 100644 --- a/engineapi/engineapi/contracts_actions.py +++ b/engineapi/engineapi/contracts_actions.py @@ -204,6 +204,16 @@ def delete_resource_for_registered_contract(resource_id: uuid.UUID) -> None: logger.info(f"Delete resource with ID: {resource.id} for registered contract") +def clean_metatx_requester_id(db_session: Session, metatx_requester_id: uuid.UUID): + query = db_session.query(RegisteredContract).filter( + RegisteredContract.metatx_requester_id == metatx_requester_id + ) + r_contracts = query.all() + + if len(r_contracts) == 0: + delete_resource_for_registered_contract(resource_id=metatx_requester_id) + + def register_contract( db_session: Session, blockchain_name: str, @@ -267,7 +277,7 @@ def register_contract( def update_registered_contract( db_session: Session, - metatx_requester_id: uuid.UUID, + metatx_requester_ids: List[uuid.UUID], contract_id: uuid.UUID, title: Optional[str] = None, description: Optional[str] = None, @@ -283,7 +293,7 @@ def update_registered_contract( .join(Blockchain, Blockchain.id == RegisteredContract.blockchain_id) .filter( RegisteredContract.id == contract_id, - RegisteredContract.metatx_requester_id == metatx_requester_id, + RegisteredContract.metatx_requester_id.in_(metatx_requester_ids), ) .one() ) @@ -364,17 +374,18 @@ def lookup_registered_contracts( def delete_registered_contract( db_session: Session, - metatx_requester_id: uuid.UUID, + metatx_requester_ids: List[uuid.UUID], registered_contract_id: uuid.UUID, ) -> Tuple[RegisteredContract, Blockchain]: """ Delete a registered contract """ + try: contract_with_blockchain = ( db_session.query(RegisteredContract, Blockchain) .join(Blockchain, Blockchain.id == RegisteredContract.blockchain_id) - .filter(RegisteredContract.metatx_requester_id == metatx_requester_id) + .filter(RegisteredContract.metatx_requester_id.in_(metatx_requester_ids)) .filter(RegisteredContract.id == registered_contract_id) .one() ) @@ -790,7 +801,7 @@ def handle_delete(args: argparse.Namespace) -> None: deleted_contract = delete_registered_contract( db_session=db_session, registered_contract_id=args.id, - moonstream_user_id=args.user_id, + moonstream_user_ids=[args.resource_id], ) except Exception as err: logger.error(err) @@ -982,11 +993,11 @@ def generate_cli() -> argparse.ArgumentParser: help="The ID of the contract to delete", ) delete_parser.add_argument( - "-u", - "--user-id", + "-r", + "--resource-id", type=uuid.UUID, required=True, - help="The ID of the Moonstream user whose contract to delete", + help="The ID of the Moonstream resource whose contract to delete", ) delete_parser.set_defaults(func=handle_delete) diff --git a/engineapi/engineapi/routes/metatx.py b/engineapi/engineapi/routes/metatx.py index c2424487..5e7667f3 100644 --- a/engineapi/engineapi/routes/metatx.py +++ b/engineapi/engineapi/routes/metatx.py @@ -11,7 +11,7 @@ from typing import Dict, List, Optional, Set, Tuple from uuid import UUID from bugout.data import BugoutUser -from fastapi import Body, Depends, FastAPI, Form, Path, Query, Request +from fastapi import BackgroundTasks, Body, Depends, FastAPI, Form, Path, Query, Request from sqlalchemy.exc import NoResultFound from sqlalchemy.orm import Session from web3 import Web3 @@ -220,18 +220,25 @@ async def update_contract_route( user_authorization: Tuple[BugoutUser, UUID] = Depends(request_user_auth), db_session: Session = Depends(db.yield_db_session), ) -> data.RegisteredContractResponse: - user, _ = user_authorization + _, token = user_authorization try: + metatx_requester_ids = contracts_actions.fetch_metatx_requester_ids(token=token) + contract_with_blockchain = contracts_actions.update_registered_contract( db_session=db_session, - metatx_requester_id=user.id, + metatx_requester_ids=metatx_requester_ids, contract_id=contract_id, title=update_info.title, description=update_info.description, image_uri=update_info.image_uri, ignore_nulls=update_info.ignore_nulls, ) + except contracts_actions.MetatxRequestersNotFound: + raise EngineHTTPException( + status_code=404, + detail="Metatx requester IDs not found", + ) except NoResultFound: raise EngineHTTPException( status_code=404, @@ -252,6 +259,7 @@ async def update_contract_route( response_model=data.RegisteredContractResponse, ) async def delete_contract_route( + background_tasks: BackgroundTasks, contract_id: UUID = Path(...), user_authorization: Tuple[BugoutUser, UUID] = Depends(request_user_auth), db_session: Session = Depends(db.yield_db_session), @@ -259,22 +267,42 @@ async def delete_contract_route( """ Allows users to delete contracts that they have registered. """ - user, _ = user_authorization + _, token = user_authorization try: + metatx_requester_ids = contracts_actions.fetch_metatx_requester_ids(token=token) + deleted_contract_with_blockchain = contracts_actions.delete_registered_contract( db_session=db_session, - metatx_requester_id=user.id, + metatx_requester_ids=metatx_requester_ids, registered_contract_id=contract_id, ) + except contracts_actions.MetatxRequestersNotFound: + raise EngineHTTPException( + status_code=404, + detail="Metatx requester IDs not found", + ) + except NoResultFound: + raise EngineHTTPException( + status_code=404, + detail="Either there is not contract with that ID or you do not have access to that contract.", + ) except Exception as err: logger.error(repr(err)) raise EngineHTTPException(status_code=500) - return contracts_actions.parse_registered_contract_response( + parsed_registered_contract = contracts_actions.parse_registered_contract_response( deleted_contract_with_blockchain ) + background_tasks.add_task( + contracts_actions.clean_metatx_requester_id, + db_session=db_session, + metatx_requester_id=parsed_registered_contract.metatx_requester_id, + ) + + return parsed_registered_contract + # TODO(kompotkot): route `/contracts/types` deprecated @app.get("/contracts/types", tags=["contracts"])