diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 2d2ebab..cbbc4a7 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -126,7 +126,7 @@ jobs: load: true tags: ${{ needs.setup.outputs.image_base }}/api:${{ needs.setup.outputs.test_image_tag }} - name: Scan API container with Trivy - uses: aquasecurity/trivy-action@0.20.0 + uses: aquasecurity/trivy-action@v0.35.0 with: # Scan the locally available image image-ref: ${{ needs.setup.outputs.image_base }}/api:${{ needs.setup.outputs.test_image_tag }} @@ -158,7 +158,7 @@ jobs: load: true tags: ${{ needs.setup.outputs.image_base }}/dashboard:${{ needs.setup.outputs.test_image_tag }} - name: Scan dashboard container with Trivy - uses: aquasecurity/trivy-action@0.20.0 + uses: aquasecurity/trivy-action@v0.35.0 with: # Scan the locally available image image-ref: ${{ needs.setup.outputs.image_base }}/dashboard:${{ needs.setup.outputs.test_image_tag }} diff --git a/app/routers/hydrofabric/router.py b/app/routers/hydrofabric/router.py index 7e103b2..8ce8c42 100644 --- a/app/routers/hydrofabric/router.py +++ b/app/routers/hydrofabric/router.py @@ -1,3 +1,4 @@ +import logging import pathlib import sqlite3 import tempfile @@ -34,6 +35,9 @@ QueryIdType, ) +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + api_router = APIRouter(prefix="/hydrofabric") @@ -94,8 +98,9 @@ async def get_hydrofabric_subset_gpkg( **Returns:** Geopackage file (.gpkg) containing the subset data """ unique_id = str(uuid.uuid4())[:8] - temp_dir = pathlib.Path(tempfile.gettempdir()) - tmp_path = temp_dir / f"subset_{identifier}_{unique_id}.gpkg" + temp_dir = pathlib.Path(tempfile.gettempdir()).resolve() + # Use only the UUID in the filename to avoid user-controlled data in path expressions + tmp_path = temp_dir / f"subset_{unique_id}.gpkg" # Resolve namespace from domain/source combination (outside try block for error handling access) try: @@ -182,13 +187,13 @@ async def get_hydrofabric_subset_gpkg( else: nonspatial_layers[table_name] = layer_data else: - print(f"Warning: {table_name} layer is empty") + logger.warning(f"Warning: {table_name} layer is empty") # Write spatial layers first with pyogrio for table_name, layer_data in spatial_layers.items(): pyogrio.write_dataframe(layer_data, tmp_path, layer=table_name) layers_written += 1 - print(f"Written spatial layer '{table_name}' with {len(layer_data)} records") + logger.info(f"Written spatial layer '{table_name}' with {len(layer_data)} records") # Then write non-spatial layers with sqlite3 if nonspatial_layers: @@ -196,7 +201,7 @@ async def get_hydrofabric_subset_gpkg( for table_name, layer_data in nonspatial_layers.items(): layer_data.to_sql(table_name, conn, if_exists="replace", index=False) layers_written += 1 - print(f"Written non-spatial layer '{table_name}' with {len(layer_data)} records") + logger.info(f"Written non-spatial layer '{table_name}' with {len(layer_data)} records") conn.close() if layers_written == 0: