diff --git a/cumulus_lambda_functions/uds_api/collections_api.py b/cumulus_lambda_functions/uds_api/collections_api.py index 6a7c2d2e..9564ae50 100644 --- a/cumulus_lambda_functions/uds_api/collections_api.py +++ b/cumulus_lambda_functions/uds_api/collections_api.py @@ -10,14 +10,14 @@ from cumulus_lambda_functions.lib.uds_db.uds_collections import UdsCollections -from cumulus_lambda_functions.uds_api.fast_api_utils import FastApiUtils +from cumulus_lambda_functions.uds_api.fast_api_utils import FastApiUtils, uds_api_authorize, api_authorized_collections from cumulus_lambda_functions.lib.authorization.uds_authorizer_factory import UDSAuthorizerFactory from cumulus_lambda_functions.lib.authorization.uds_authorizer_abstract import UDSAuthorizorAbstract from cumulus_lambda_functions.lib.lambda_logger_generator import LambdaLoggerGenerator -from fastapi import APIRouter, HTTPException, Request, Response +from fastapi import APIRouter, HTTPException, Request, Response, Depends from cumulus_lambda_functions.uds_api.dapa.collections_dapa_cnm import CnmRequestBody, CollectionsDapaCnm from cumulus_lambda_functions.uds_api.dapa.collections_dapa_creation import CollectionDapaCreation, \ @@ -35,8 +35,8 @@ responses={404: {"description": "Not found"}}, ) -@router.put("") -@router.put("/") +@router.put("/{collection_id}", dependencies=[Depends(uds_api_authorize)]) +@router.put("/{collection_id}/", dependencies=[Depends(uds_api_authorize)]) async def ingest_cnm_dapa(request: Request, new_cnm_body: CnmRequestBody, response: Response, response_class=JSONResponse): """ Ingestion of Granules for a given collection via CNM @@ -44,28 +44,6 @@ async def ingest_cnm_dapa(request: Request, new_cnm_body: CnmRequestBody, respon This is a facade endpoint which will trigger another endpoint which takes some time to execute ingestion """ LOGGER.debug(f'starting ingest_cnm_dapa') - collection_id = new_cnm_body.model_dump() - if 'features' not in collection_id or len(collection_id['features']) < 1 or 'collection' not in collection_id['features'][0]: - raise HTTPException(status_code=500, detail=json.dumps({ - 'message': 'missing collection_id in request_body["features"][0]["collection"]' - })) - collection_id = collection_id['features'][0]['collection'] - collection_id = collection_id.split('___')[0] # split id, version and only keeping id. TODO need this? - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.create, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: cnm_prep_result = CollectionsDapaCnm(new_cnm_body.model_dump()).start_facade(request.url) except Exception as e: @@ -77,8 +55,8 @@ async def ingest_cnm_dapa(request: Request, new_cnm_body: CnmRequestBody, respon raise HTTPException(status_code=cnm_prep_result['statusCode'], detail=cnm_prep_result['body']) -@router.put("/actual") -@router.put("/actual/") +@router.put("/{collection_id}/actual", dependencies=[Depends(uds_api_authorize)]) +@router.put("/{collection_id}/actual/", dependencies=[Depends(uds_api_authorize)]) async def ingest_cnm_dapa_actual(request: Request, new_cnm_body: CnmRequestBody, response_class=JSONResponse): """ Real ingestion of Granules for a given collection via CNM @@ -98,8 +76,8 @@ async def ingest_cnm_dapa_actual(request: Request, new_cnm_body: CnmRequestBody, raise HTTPException(status_code=cnm_result['statusCode'], detail=cnm_result['body']) -@router.post("") -@router.post("/") +@router.post("/{collection_id}", dependencies=[Depends(uds_api_authorize)]) +@router.post("/{collection_id}/", dependencies=[Depends(uds_api_authorize)]) async def create_new_collection(request: Request, new_collection: CumulusCollectionModel, response: Response): """ Creating a new Cumulus Collection @@ -107,28 +85,6 @@ async def create_new_collection(request: Request, new_collection: CumulusCollect This is a facade endpoint which will trigger another endpoint which takes some time to hit Cumulus collection creation endpoint. """ LOGGER.debug(f'starting create_new_collection') - new_collection = new_collection.model_dump() - collection_id = new_collection - if 'id' not in collection_id: - raise HTTPException(status_code=500, detail=json.dumps({ - 'message': 'missing collection_id in request_body["id"]' - })) - collection_id = new_collection['id'] - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.create, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: # new_collection = request.body() bearer_token = request.headers.get('Authorization', '') @@ -143,36 +99,13 @@ async def create_new_collection(request: Request, new_collection: CumulusCollect raise HTTPException(status_code=creation_result['statusCode'], detail=creation_result['body']) -@router.post("/actual") -@router.post("/actual/") -async def create_new_collection_real(request: Request, new_collection: CumulusCollectionModel): +@router.post("/{collection_id}/actual", dependencies=[Depends(uds_api_authorize)]) +@router.post("/{collection_id}/actual/", dependencies=[Depends(uds_api_authorize)]) +async def create_new_collection_real(request: Request, collection_id: str, new_collection: CumulusCollectionModel): """ Actual endpoint to create a new Cumulus Collection """ LOGGER.debug(f'starting create_new_collection_real') - new_collection = new_collection.model_dump() - collection_id = new_collection - if 'id' not in collection_id: - raise HTTPException(status_code=500, detail=json.dumps({ - 'message': 'missing collection_id in request_body["id"]' - })) - collection_id = new_collection['id'] - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.create, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) - try: creation_result = CollectionDapaCreation(new_collection).create() except Exception as e: @@ -182,32 +115,11 @@ async def create_new_collection_real(request: Request, new_collection: CumulusCo return creation_result['body'], creation_result['statusCode'] raise HTTPException(status_code=creation_result['statusCode'], detail=creation_result['body']) -@router.get("/{collection_id}") -@router.get("/{collection_id}/") +@router.get("/{collection_id}", dependencies=[Depends(uds_api_authorize)]) +@router.get("/{collection_id}/, dependencies=[Depends(uds_api_authorize)]") async def get_single_collection(request: Request, collection_id: str, limit: Union[int, None] = 10, offset: Union[int, None] = 0, ): LOGGER.debug(f'starting get_single_collection: {collection_id}') LOGGER.debug(f'starting get_single_collection request: {request}') - - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - uds_collections = UdsCollections(es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')), es_type=os.getenv('ES_TYPE', 'AWS')) - if collection_id is None or collection_id == '': - raise HTTPException(status_code=500, detail=f'missing or invalid collection_id: {collection_id}') - collection_identifier = uds_collections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) - try: custom_params = {} if limit > CollectionDapaQuery.max_limit: @@ -229,36 +141,21 @@ async def get_single_collection(request: Request, collection_id: str, limit: Uni @router.get("") @router.get("/") -async def query_collections(request: Request, collection_id: Union[str, None] = None, limit: Union[int, None] = 10, offset: Union[int, None] = 0, ): +async def query_collections(request: Request, collection_id: Union[str, None] = None, limit: Union[int, None] = 10, offset: Union[int, None] = 0, authorized_collections = Depends(api_authorized_collections)): LOGGER.debug(f'starting query_collections: {collection_id}') LOGGER.debug(f'starting query_collections request: {request}') - - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) uds_collections = UdsCollections(es_url=os.getenv('ES_URL'), es_port=int(os.getenv('ES_PORT', '443')), es_type=os.getenv('ES_TYPE', 'AWS')) if collection_id is not None: - collection_identifier = uds_collections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) - else: - collection_regexes = authorizer.get_authorized_collections(DBConstants.read, auth_info['ldap_groups']) - LOGGER.info(f'collection_regexes: {collection_regexes}') - authorized_collections = uds_collections.get_collections(collection_regexes) - LOGGER.info(f'authorized_collections: {authorized_collections}') - collection_id = [k[DBConstants.collection_id] for k in authorized_collections] - LOGGER.info(f'authorized_collection_ids: {collection_id}') - # NOTE: 2022-11-21: only pass collections. not versions + raise HTTPException(status_code=301, detail=f'Pls use collection_id as path parameter to retrieve a single collection.') + + # collection_regexes = authorizer.get_authorized_collections(DBConstants.read, auth_info['ldap_groups']) + LOGGER.info(f'collection_regexes: {authorized_collections}') + authorized_collections = uds_collections.get_collections(collection_regexes) + LOGGER.info(f'authorized_collections: {authorized_collections}') + collection_id = [k[DBConstants.collection_id] for k in authorized_collections] + LOGGER.info(f'authorized_collection_ids: {collection_id}') + # NOTE: 2022-11-21: only pass collections. not versions try: custom_params = {} @@ -279,32 +176,12 @@ async def query_collections(request: Request, collection_id: Union[str, None] = return collections_result['body'] raise HTTPException(status_code=collections_result['statusCode'], detail=collections_result['body']) -@router.delete("/{collection_id}") -@router.delete("/{collection_id}/") +@router.delete("/{collection_id}", dependencies=[Depends(uds_api_authorize)]) +@router.delete("/{collection_id}/", dependencies=[Depends(uds_api_authorize)]) async def delete_single_collection(request: Request, collection_id: str): LOGGER.debug(f'starting delete_single_collection: {collection_id}') LOGGER.debug(f'starting delete_single_collection request: {request}') - - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - uds_collections = UdsCollections(es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')), es_type=os.getenv('ES_TYPE', 'AWS')) - if collection_id is None or collection_id == '': - raise HTTPException(status_code=500, detail=f'missing or invalid collection_id: {collection_id}') - collection_identifier = uds_collections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.delete, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) - + collection_identifier = UdsCollections.decode_identifier(collection_id) granules_count = GranulesDbIndex().get_size(collection_identifier.tenant, collection_identifier.venue, collection_id) LOGGER.debug(f'granules_count: {granules_count} for {collection_id}') diff --git a/cumulus_lambda_functions/uds_api/fast_api_utils.py b/cumulus_lambda_functions/uds_api/fast_api_utils.py index ffece58a..57e98914 100644 --- a/cumulus_lambda_functions/uds_api/fast_api_utils.py +++ b/cumulus_lambda_functions/uds_api/fast_api_utils.py @@ -6,9 +6,13 @@ from mdps_ds_lib.lib.constants import Constants +from cumulus_lambda_functions.lib.authorization.uds_authorizer_abstract import UDSAuthorizorAbstract +from cumulus_lambda_functions.lib.authorization.uds_authorizer_factory import UDSAuthorizerFactory from cumulus_lambda_functions.lib.lambda_logger_generator import LambdaLoggerGenerator from fastapi import APIRouter, HTTPException, Request, Response +from cumulus_lambda_functions.lib.uds_db.db_constants import DBConstants +from cumulus_lambda_functions.lib.uds_db.uds_collections import UdsCollections from cumulus_lambda_functions.uds_api.web_service_constants import WebServiceConstants LOGGER = LambdaLoggerGenerator.get_logger(__name__, LambdaLoggerGenerator.get_level_from_env()) @@ -20,6 +24,7 @@ def get_authorization_info(request: Request): """ :return: """ + # TODO this can be a factory method action = request.method resource = request.url.path bearer_token = request.headers.get('Authorization', '') @@ -90,3 +95,53 @@ def prep_stac_browser(): FastApiUtils.replace_in_folder(temp_static_parent_dir, f'"{WebServiceConstants.SETTING_PLACEHOLDER}"', json.dumps(stac_browser_settings)) FastApiUtils.replace_in_folder(temp_static_parent_dir, f"'{WebServiceConstants.SETTING_PLACEHOLDER}'", json.dumps(stac_browser_settings)) return stac_browser_prefix, temp_static_parent_dir + + +async def api_authorized_collections(request: Request): + auth_info = FastApiUtils.get_authorization_info(request) # TODO how to get different authorization info? + + authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ + .get_instance(os.getenv('AUTHORIZER_TYPE'), + es_url=os.getenv('ES_URL'), + es_port=int(os.getenv('ES_PORT', '443')), + use_ssl=os.getenv('ES_USE_SSL', 'TRUE').strip() is True, + ) + collection_regexes = authorizer.get_authorized_collections(DBConstants.read, auth_info['ldap_groups']) + return collection_regexes + +async def uds_api_authorize(request: Request): + db_constants_map = { + 'GET': DBConstants.read, + 'DELETE': DBConstants.delete, + 'PUT': DBConstants.create, + 'POST': DBConstants.create, + 'PATCH': DBConstants.create, # TODO Update? + } + authorization_type = db_constants_map[request.method] + if request.method not in db_constants_map: + raise HTTPException(status_code=405, detail=json.dumps({ + 'message': f'unknown HTTP method for authorization. Pls use these {db_constants_map}' + })) + if 'collection_id' not in request.path_params: + raise HTTPException(status_code=400, detail=json.dumps({ + 'message': 'collection_id is needed as path parameter for authorization.' + })) + collection_id = request.path_params['collection_id'] + auth_info = FastApiUtils.get_authorization_info(request) # TODO how to get different authorization info? + + authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ + .get_instance(os.getenv('AUTHORIZER_TYPE'), + es_url=os.getenv('ES_URL'), + es_port=int(os.getenv('ES_PORT', '443')), + use_ssl=os.getenv('ES_USE_SSL', 'TRUE').strip() is True, + ) + collection_identifier = UdsCollections.decode_identifier(collection_id) + if not authorizer.is_authorized_for_collection(authorization_type, collection_id, + auth_info['ldap_groups'], + collection_identifier.tenant, + collection_identifier.venue): + LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') + raise HTTPException(status_code=403, detail=json.dumps({ + 'message': 'not authorized to execute this action' + })) + return True diff --git a/cumulus_lambda_functions/uds_api/granules_api.py b/cumulus_lambda_functions/uds_api/granules_api.py index 0e74887f..c0515be0 100644 --- a/cumulus_lambda_functions/uds_api/granules_api.py +++ b/cumulus_lambda_functions/uds_api/granules_api.py @@ -10,7 +10,7 @@ from cumulus_lambda_functions.uds_api.dapa.granules_dapa_query_es import GranulesDapaQueryEs from cumulus_lambda_functions.lib.uds_db.granules_db_index import GranulesDbIndex -from cumulus_lambda_functions.uds_api.fast_api_utils import FastApiUtils +from cumulus_lambda_functions.uds_api.fast_api_utils import FastApiUtils, uds_api_authorize from cumulus_lambda_functions.lib.authorization.uds_authorizer_abstract import UDSAuthorizorAbstract @@ -22,7 +22,7 @@ from cumulus_lambda_functions.lib.lambda_logger_generator import LambdaLoggerGenerator -from fastapi import APIRouter, HTTPException, Request, Query, Path +from fastapi import APIRouter, HTTPException, Request, Query, Path, Depends from cumulus_lambda_functions.uds_api.dapa.pagination_links_generator import PaginationLinksGenerator from cumulus_lambda_functions.uds_api.web_service_constants import WebServiceConstants @@ -36,25 +36,10 @@ ) # https://docs.ogc.org/per/20-025r1.html#_get_collectionscollectionidvariables -@router.get("/{collection_id}/variables") -@router.get("/{collection_id}/variables/") +@router.get("/{collection_id}/variables", dependencies=[Depends(uds_api_authorize)]) +@router.get("/{collection_id}/variables/", dependencies=[Depends(uds_api_authorize)]) async def get_granules_dapa(request: Request, collection_id: str): - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) - try: granules_db_index = GranulesDbIndex() granule_index_mapping = granules_db_index.get_latest_index(collection_identifier.tenant, collection_identifier.venue) @@ -68,8 +53,8 @@ async def get_granules_dapa(request: Request, collection_id: str): return custom_metadata -@router.get("/{collection_id}/items") -@router.get("/{collection_id}/items/") +@router.get("/{collection_id}/items", dependencies=[Depends(uds_api_authorize)]) +@router.get("/{collection_id}/items/", dependencies=[Depends(uds_api_authorize)]) async def get_granules_dapa(request: Request, collection_id: str=Path(description="Collection ID. To query across different collections, use '*'. Example: 'URN:NASA:UNITY:MY_TENANT:DEV:\\*'"), limit: Union[int, None] = Query(10, description='Number of items in each page.'), offset: Union[str, None] = Query(None, description='Pagination Item from current page to get the next page'), @@ -80,21 +65,6 @@ async def get_granules_dapa(request: Request, collection_id: str=Path(descriptio ): # https://docs.ogc.org/DRAFTS/24-030.html#sortby-parameter # https://docs.ogc.org/DRAFTS/24-030.html#_declaring_default_sort_order - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: pagination_links = PaginationLinksGenerator(request) @@ -110,24 +80,9 @@ async def get_granules_dapa(request: Request, collection_id: str=Path(descriptio raise HTTPException(status_code=granules_result['statusCode'], detail=granules_result['body']) -@router.get("/{collection_id}/items/{granule_id}") -@router.get("/{collection_id}/items/{granule_id}/") +@router.get("/{collection_id}/items/{granule_id}", dependencies=[Depends(uds_api_authorize)]) +@router.get("/{collection_id}/items/{granule_id}/", dependencies=[Depends(uds_api_authorize)]) async def get_single_granule_dapa(request: Request, collection_id: str, granule_id: str): - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: api_base_prefix = FastApiUtils.get_api_base_prefix() pg_link_generator = PaginationLinksGenerator(request) @@ -140,24 +95,10 @@ async def get_single_granule_dapa(request: Request, collection_id: str, granule_ raise HTTPException(status_code=404, detail={'message': f'no granule with id: {granule_id} in collection: {collection_id}'}) return granules_result -@router.delete("/{collection_id}/items/{granule_id}") -@router.delete("/{collection_id}/items/{granule_id}/") +@router.delete("/{collection_id}/items/{granule_id}", dependencies=[Depends(uds_api_authorize)]) +@router.delete("/{collection_id}/items/{granule_id}/", dependencies=[Depends(uds_api_authorize)]) async def delete_single_granule_dapa_actual(request: Request, collection_id: str, granule_id: str): - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.delete, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: LOGGER.debug(f'deleting granule: {granule_id}') include_cumulus = os.getenv('CUMULUS_INCLUSION', 'TRUE').upper().strip() == 'TRUE' @@ -252,25 +193,10 @@ class StacGranuleModel(BaseModel): stac_version: str type: str -@router.put("/{collection_id}/items/{granule_id}") -@router.put("/{collection_id}/items/{granule_id}/") + +@router.put("/{collection_id}/items/{granule_id}", dependencies=[Depends(uds_api_authorize)]) +@router.put("/{collection_id}/items/{granule_id}/", dependencies=[Depends(uds_api_authorize)]) async def add_single_granule_dapa(request: Request, collection_id: str, granule_id: str, new_granule: StacGranuleModel, response: Response): - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')), - use_ssl=os.getenv('ES_USE_SSL', 'TRUE').strip() is True, - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.create, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: LOGGER.debug(f'adding granule: {granule_id}') new_granule = new_granule.model_dump() @@ -297,24 +223,9 @@ async def add_single_granule_dapa(request: Request, collection_id: str, granule_ raise HTTPException(status_code=500, detail=str(e)) return {} -# @router.delete("/{collection_id}/items/{granule_id}") -# @router.delete("/{collection_id}/items/{granule_id}/") +# @router.delete("/{collection_id}/items/{granule_id}", dependencies=[Depends(uds_api_authorize)]) +# @router.delete("/{collection_id}/items/{granule_id}/", dependencies=[Depends(uds_api_authorize)]) # async def delete_single_granule_dapa_facade(request: Request, collection_id: str, granule_id: str, response: Response, response_class=JSONResponse): -# authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ -# .get_instance(UDSAuthorizerFactory.cognito, -# es_url=os.getenv('ES_URL'), -# es_port=int(os.getenv('ES_PORT', '443')) -# ) -# auth_info = FastApiUtils.get_authorization_info(request) -# collection_identifier = UdsCollections.decode_identifier(collection_id) -# if not authorizer.is_authorized_for_collection(DBConstants.delete, collection_id, -# auth_info['ldap_groups'], -# collection_identifier.tenant, -# collection_identifier.venue): -# LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') -# raise HTTPException(status_code=403, detail=json.dumps({ -# 'message': 'not authorized to execute this action' -# })) # try: # LOGGER.debug(f'deleting granule: {granule_id}') # granules_dapa_query = GranulesDapaQueryEs(collection_id, -1, -1, None, None, None, '') diff --git a/cumulus_lambda_functions/uds_api/granules_archive_api.py b/cumulus_lambda_functions/uds_api/granules_archive_api.py index 39fc302e..91b8471f 100644 --- a/cumulus_lambda_functions/uds_api/granules_archive_api.py +++ b/cumulus_lambda_functions/uds_api/granules_archive_api.py @@ -7,7 +7,7 @@ from cumulus_lambda_functions.uds_api.dapa.daac_archive_crud import DaacArchiveCrud, DaacDeleteModel, DaacAddModel, \ DaacUpdateModel -from cumulus_lambda_functions.uds_api.fast_api_utils import FastApiUtils +from cumulus_lambda_functions.uds_api.fast_api_utils import FastApiUtils, uds_api_authorize from cumulus_lambda_functions.lib.authorization.uds_authorizer_abstract import UDSAuthorizorAbstract @@ -19,7 +19,7 @@ from cumulus_lambda_functions.lib.lambda_logger_generator import LambdaLoggerGenerator -from fastapi import APIRouter, HTTPException, Request +from fastapi import APIRouter, HTTPException, Request, Depends from cumulus_lambda_functions.uds_api.web_service_constants import WebServiceConstants @@ -31,25 +31,13 @@ responses={404: {"description": "Not found"}}, ) -@router.put("/{collection_id}/archive") -@router.put("/{collection_id}/archive/") + +@router.put("/{collection_id}/archive", dependencies=[Depends(uds_api_authorize)]) +@router.put("/{collection_id}/archive/", dependencies=[Depends(uds_api_authorize)]) async def dapa_archive_add_config(request: Request, collection_id: str, new_body: DaacAddModel): LOGGER.debug(f'started dapa_archive_add_config. {new_body.model_dump()}') - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) auth_info = FastApiUtils.get_authorization_info(request) collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) if '___' not in collection_identifier.id: raise HTTPException(status_code=500, detail=json.dumps({ 'message': f'missing version in collection ID. collection_id: {collection_id}' @@ -60,25 +48,13 @@ async def dapa_archive_add_config(request: Request, collection_id: str, new_body return add_result['body'] raise HTTPException(status_code=add_result['statusCode'], detail=add_result['body']) -@router.post("/{collection_id}/archive") -@router.post("/{collection_id}/archive/") + +@router.post("/{collection_id}/archive", dependencies=[Depends(uds_api_authorize)]) +@router.post("/{collection_id}/archive/", dependencies=[Depends(uds_api_authorize)]) async def dapa_archive_update_config(request: Request, collection_id: str, new_body: DaacUpdateModel): LOGGER.debug(f'started dapa_archive_add_config. {new_body.model_dump()}') - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) auth_info = FastApiUtils.get_authorization_info(request) collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) if '___' not in collection_identifier.id: raise HTTPException(status_code=500, detail=json.dumps({ 'message': f'missing version in collection ID. collection_id: {collection_id}' @@ -89,25 +65,12 @@ async def dapa_archive_update_config(request: Request, collection_id: str, new_b return add_result['body'] raise HTTPException(status_code=add_result['statusCode'], detail=add_result['body']) -@router.delete("/{collection_id}/archive") -@router.delete("/{collection_id}/archive/") +@router.delete("/{collection_id}/archive", dependencies=[Depends(uds_api_authorize)]) +@router.delete("/{collection_id}/archive/", dependencies=[Depends(uds_api_authorize)]) async def dapa_archive_delete_config(request: Request, collection_id: str, new_body: DaacDeleteModel): LOGGER.debug(f'started dapa_archive_add_config. {new_body.model_dump()}') - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) auth_info = FastApiUtils.get_authorization_info(request) collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) if '___' not in collection_identifier.id: raise HTTPException(status_code=500, detail=json.dumps({ 'message': f'missing version in collection ID. collection_id: {collection_id}' @@ -118,49 +81,20 @@ async def dapa_archive_delete_config(request: Request, collection_id: str, new_b return add_result['body'] raise HTTPException(status_code=add_result['statusCode'], detail=add_result['body']) -@router.get("/{collection_id}/archive") -@router.get("/{collection_id}/archive/") +@router.get("/{collection_id}/archive", dependencies=[Depends(uds_api_authorize)]) +@router.get("/{collection_id}/archive/", dependencies=[Depends(uds_api_authorize)]) async def dapa_archive_get_config(request: Request, collection_id: str): # TODO return UDS SNS to accept DAAC messages here - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) daac_crud = DaacArchiveCrud(auth_info, collection_id, {}) add_result = daac_crud.get_config() if add_result['statusCode'] == 200: return add_result['body'] raise HTTPException(status_code=add_result['statusCode'], detail=add_result['body']) -@router.put("/{collection_id}/archive/{granule_id}") -@router.put("/{collection_id}/archive/{granule_id}/") +@router.put("/{collection_id}/archive/{granule_id}", dependencies=[Depends(uds_api_authorize)]) +@router.put("/{collection_id}/archive/{granule_id}/", dependencies=[Depends(uds_api_authorize)]) async def archive_single_granule_dapa(request: Request, collection_id: str, granule_id: str): - authorizer: UDSAuthorizorAbstract = UDSAuthorizerFactory() \ - .get_instance(UDSAuthorizerFactory.cognito, - es_url=os.getenv('ES_URL'), - es_port=int(os.getenv('ES_PORT', '443')) - ) - auth_info = FastApiUtils.get_authorization_info(request) - collection_identifier = UdsCollections.decode_identifier(collection_id) - if not authorizer.is_authorized_for_collection(DBConstants.read, collection_id, - auth_info['ldap_groups'], - collection_identifier.tenant, - collection_identifier.venue): - LOGGER.debug(f'user: {auth_info["username"]} is not authorized for {collection_id}') - raise HTTPException(status_code=403, detail=json.dumps({ - 'message': 'not authorized to execute this action' - })) try: api_base_prefix = FastApiUtils.get_api_base_prefix() pg_link_generator = PaginationLinksGenerator(request)