From 7472e071681237bca63f9973e80eea1272ce7678 Mon Sep 17 00:00:00 2001 From: Solomon Negusse Date: Tue, 30 Apr 2024 22:00:56 +0300 Subject: [PATCH] add permissions docs --- app/routes/assets/asset.py | 23 +++++++++++++++++++- app/routes/datasets/asset.py | 2 ++ app/routes/datasets/dataset.py | 10 ++++++++- app/routes/datasets/versions.py | 38 ++++++++++++++++++++++++++------- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/app/routes/assets/asset.py b/app/routes/assets/asset.py index 0d39879be..4781afc13 100644 --- a/app/routes/assets/asset.py +++ b/app/routes/assets/asset.py @@ -8,6 +8,7 @@ cannot rely on full integrity. We can only assume that unmanaged are based on the same version and do not know the processing history. """ + from typing import List, Optional, Union from uuid import UUID @@ -104,7 +105,10 @@ async def update_asset( request: AssetUpdateIn, is_authorized: bool = Depends(is_admin), ) -> AssetResponse: - """Update Asset metadata.""" + """Update Asset metadata. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ input_data = request.dict(exclude_none=True, by_alias=True) @@ -136,6 +140,8 @@ async def delete_asset( For managed assets, all resources will be deleted. For non-managed assets, only the link will be deleted. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. """ try: @@ -342,6 +348,10 @@ async def get_field_metadata(*, asset_id: UUID = Path(...), field_name: str): async def update_field_metadata( *, asset_id: UUID = Path(...), field_name: str, request: FieldMetadataUpdate ): + """Update the field metadata for an asset. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ input_data = request.dict(exclude_none=True, by_alias=True) metadata = await metadata_crud.get_asset_metadata(asset_id) field_metadata: ORMFieldMetadata = await metadata_crud.update_field_metadata( @@ -375,6 +385,10 @@ async def get_metadata(asset_id: UUID = Path(...)): response_model=AssetMetadataResponse, ) async def create_metadata(*, asset_id: UUID = Path(...), request: AssetMetadata): + """Create metadata record for an asset. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ input_data = request.dict(exclude_none=True, by_alias=True) asset = await assets.get_asset(asset_id) @@ -397,6 +411,10 @@ async def create_metadata(*, asset_id: UUID = Path(...), request: AssetMetadata) response_model=AssetMetadataResponse, ) async def update_metadata(*, asset_id: UUID = Path(...), request: AssetMetadataUpdate): + """Update metadata record for an asset. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ input_data = request.dict(exclude_none=True, by_alias=True) @@ -420,7 +438,10 @@ async def update_metadata(*, asset_id: UUID = Path(...), request: AssetMetadataU response_model=AssetMetadataResponse, ) async def delete_metadata(asset_id: UUID = Path(...)): + """Delete an asset's metadata record. + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ try: asset = await assets.get_asset(asset_id) asset.metadata = await metadata_crud.delete_asset_metadata(asset_id) diff --git a/app/routes/datasets/asset.py b/app/routes/datasets/asset.py index e90163fad..fbdbd125c 100644 --- a/app/routes/datasets/asset.py +++ b/app/routes/datasets/asset.py @@ -127,6 +127,8 @@ async def add_new_asset( If the asset is not managed, you need to specify an Asset URI to link to. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. """ dataset, version = dv diff --git a/app/routes/datasets/dataset.py b/app/routes/datasets/dataset.py index d80e5b07e..5bdf16c6c 100644 --- a/app/routes/datasets/dataset.py +++ b/app/routes/datasets/dataset.py @@ -55,7 +55,11 @@ async def create_dataset( is_authorized: bool = Depends(is_admin), response: Response, ) -> DatasetResponse: - """Create or update a dataset.""" + """Create a dataset. a “dataset” is largely a metadata concept: it represents + a data product that may have multiple versions or file formats over time. + + This operation requires a `MANAGER` or an `ADMIN` user role. + """ input_data: Dict = request.dict(exclude_none=True, by_alias=True) @@ -90,6 +94,8 @@ async def update_dataset( Only metadata field can be updated. All other fields will be ignored. + + Only the dataset owner or a user with `ADMIN` user role can do this operation. """ input_data: Dict = request.dict(exclude_none=True, by_alias=True) row: ORMDataset = await datasets.update_dataset(dataset, **input_data) @@ -113,6 +119,8 @@ async def delete_dataset( By the time users are allowed to delete datasets, there should be no versions and assets left. So only thing beside deleting the dataset row is to drop the schema in the database. + + Only the dataset owner or a user with `ADMIN` user role can do this operation. """ version_rows: List[ORMVersion] = await versions.get_versions(dataset) diff --git a/app/routes/datasets/versions.py b/app/routes/datasets/versions.py index 50cdf0356..45506d60e 100644 --- a/app/routes/datasets/versions.py +++ b/app/routes/datasets/versions.py @@ -8,6 +8,7 @@ assets and activate additional endpoints to view and query the dataset. Available assets and endpoints to choose from depend on the source type. """ + from collections import defaultdict from copy import deepcopy from typing import Any, Dict, List, Optional, Sequence, Tuple, Union @@ -124,7 +125,10 @@ async def add_new_version( is_authorized: bool = Depends(is_admin), response: Response, ): - """Create or update a version for a given dataset.""" + """Create a version for a given dataset uploading the geospatial/tabular asset. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ input_data = request.dict(exclude_none=True, by_alias=True) creation_options = input_data.pop("creation_options") @@ -171,7 +175,9 @@ async def update_version( ): """Partially update a version of a given dataset. - Update metadata or change latest tag + Update metadata or change latest tag. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. """ dataset, version = dv input_data = request.dict(exclude_none=True, by_alias=True) @@ -219,6 +225,8 @@ async def append_to_version( Schema of input file must match or be a subset of previous input files. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. """ dataset, version = dv _verify_source_file_access(request.dict()["source_uri"]) @@ -257,12 +265,13 @@ async def delete_version( is_authorized: bool = Depends(is_admin), background_tasks: BackgroundTasks, ): - """Delete a version. Only delete version if it is not tagged as `latest` or if it is the only version associated with dataset. All associated, managed assets will be deleted in consequence. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. """ dataset, version = dv row: Optional[ORMVersion] = None @@ -381,6 +390,7 @@ async def get_metadata( False, description="Whether to include dataset metadata." ), ): + """Get metadata record for a dataset version.""" dataset, version = dv try: @@ -406,6 +416,10 @@ async def create_metadata( is_authorized: bool = Depends(is_admin), request: VersionMetadataIn, ): + """Create a metadata record for a dataset version. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ dataset, version = dv input_data = request.dict(exclude_none=True, by_alias=True) try: @@ -429,6 +443,10 @@ async def delete_metadata( dv: Tuple[str, str] = Depends(dataset_version_dependency), is_authorized: bool = Depends(is_admin), ): + """Delete metadata record for a dataset version. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ dataset, version = dv try: @@ -453,6 +471,10 @@ async def update_metadata( is_authorized: bool = Depends(is_admin), request: VersionMetadataUpdate, ): + """Update metadata record for a dataset version. + + Only the parent dataset's owner or a user with `ADMIN` user role can do this operation. + """ dataset, version = dv input_data = request.dict(exclude_none=True, by_alias=True) @@ -477,16 +499,16 @@ async def _get_raster_fields(asset: ORMAsset) -> List[RasterBandMetadata]: logger.debug(f"Processing data environment f{raster_data_environment}") for layer in raster_data_environment.layers: - field_kwargs: Dict[str, Any] = { - "pixel_meaning": layer.name - } + field_kwargs: Dict[str, Any] = {"pixel_meaning": layer.name} if layer.raster_table: field_kwargs["values_table"] = cast(Dict[str, Any], {}) field_kwargs["values_table"]["rows"] = [ - row for row in layer.raster_table.rows + row for row in layer.raster_table.rows ] if layer.raster_table.default_meaning: - field_kwargs["values_table"]["default_meaning"] = layer.raster_table.default_meaning + field_kwargs["values_table"][ + "default_meaning" + ] = layer.raster_table.default_meaning fields.append(RasterBandMetadata(**field_kwargs))