diff --git a/app/api/subsetter/app/db.py b/app/api/subsetter/app/db.py index 2a9688fb..c373b07d 100644 --- a/app/api/subsetter/app/db.py +++ b/app/api/subsetter/app/db.py @@ -1,3 +1,4 @@ +import re from enum import Enum from functools import lru_cache from typing import List, Optional, Tuple @@ -48,6 +49,10 @@ class User(BeanieBaseUser, Document): given_name: Optional[str] = None family_name: Optional[str] = None + @property + def bucket_name(self): + return re.sub("[^A-Za-z0-9\.-]", "", re.sub("[@]", ".at.", self.username.lower())) + async def update_profile(self): async def get_profile(token: str) -> Tuple[str, str]: async with httpx.AsyncClient() as client: diff --git a/app/api/subsetter/app/routers/argo/router.py b/app/api/subsetter/app/routers/argo/router.py index 2b8a8da9..c36701a2 100644 --- a/app/api/subsetter/app/routers/argo/router.py +++ b/app/api/subsetter/app/routers/argo/router.py @@ -36,7 +36,7 @@ api_instance = workflow_service_api.WorkflowServiceApi(api_client) -def parflow_submission_body(hucs: list, username: str, workflow_name: str): +def parflow_submission_body(hucs: list, bucket_name: str, workflow_name: str): return { "resourceKind": "WorkflowTemplate", "resourceName": "parflow-subset-v1-by-huc-minio", @@ -44,7 +44,7 @@ def parflow_submission_body(hucs: list, username: str, workflow_name: str): "name": workflow_name, "parameters": [ f"output-path=argo_workflows/parflow/{workflow_name}", - f"output-bucket={username}", + f"output-bucket={bucket_name}", "hucs=" + ",".join(hucs), ], }, @@ -52,7 +52,7 @@ def parflow_submission_body(hucs: list, username: str, workflow_name: str): def nwm1_submission_body( - y_south: float, x_west: float, y_north: float, x_east: float, username: str, workflow_name: str + y_south: float, x_west: float, y_north: float, x_east: float, bucket_name: str, workflow_name: str ): return { "resourceKind": "WorkflowTemplate", @@ -60,7 +60,7 @@ def nwm1_submission_body( "submitOptions": { "name": workflow_name, "parameters": [ - f"output-bucket={username}", + f"output-bucket={bucket_name}", f"output-path=argo_workflows/nwm1/{workflow_name}", f"y_south={y_south}", f"x_west={x_west}", @@ -72,7 +72,7 @@ def nwm1_submission_body( def nwm2_submission_body( - y_south: float, x_west: float, y_north: float, x_east: float, username: str, workflow_name: str + y_south: float, x_west: float, y_north: float, x_east: float, bucket_name: str, workflow_name: str ): return { "resourceKind": "WorkflowTemplate", @@ -80,7 +80,7 @@ def nwm2_submission_body( "submitOptions": { "name": workflow_name, "parameters": [ - f"output-bucket={username}", + f"output-bucket={bucket_name}", f"output-path=argo_workflows/nwm2/{workflow_name}", f"y_south={y_south}", f"x_west={x_west}", @@ -113,7 +113,7 @@ async def submit_parflow( workflow_id = str(uuid.uuid4()) api_response = api_instance.submit_workflow( namespace=get_settings().argo_namespace, - body=parflow_submission_body(hucs, user.username, workflow_id), + body=parflow_submission_body(hucs, user.bucket_name, workflow_id), _preload_content=False, ) log.info(api_response.json()) @@ -129,7 +129,7 @@ async def submit_nwm1( workflow_id = str(uuid.uuid4()) api_response = api_instance.submit_workflow( namespace=get_settings().argo_namespace, - body=nwm1_submission_body(y_south, x_west, y_north, x_east, user.username, workflow_id), + body=nwm1_submission_body(y_south, x_west, y_north, x_east, user.bucket_name, workflow_id), _preload_content=False, ) log.info(api_response.json()) @@ -145,7 +145,7 @@ async def submit_nwm2( workflow_id = str(uuid.uuid4()) api_response = api_instance.submit_workflow( namespace=get_settings().argo_namespace, - body=nwm2_submission_body(y_south, x_west, y_north, x_east, user.username, workflow_id), + body=nwm2_submission_body(y_south, x_west, y_north, x_east, user.bucket_name, workflow_id), _preload_content=False, ) log.info(api_response.json()) @@ -223,7 +223,7 @@ async def signed_url_minio(workflow_params: WorkflowDep) -> UrlResponseModel: submission = workflow_params.user.get_submission(workflow_params.workflow_id) url = get_minio_client().presigned_get_object( "subsetter-outputs", - f"{workflow_params.user.username}/{submission.workflow_name}/{submission.workflow_id}/all.gz", + f"{workflow_params.user.bucket_name}/{submission.workflow_name}/{submission.workflow_id}/all.gz", ) return {'url': url} diff --git a/app/api/subsetter/app/users.py b/app/api/subsetter/app/users.py index f69312c8..4ad939a9 100644 --- a/app/api/subsetter/app/users.py +++ b/app/api/subsetter/app/users.py @@ -51,8 +51,9 @@ class UserManager(ObjectIDIDMixin, BaseUserManager[User, PydanticObjectId]): async def on_after_register(self, user: User, request: Optional[Request] = None): await user.update_profile() - if not get_minio_client().bucket_exists(user.username): - get_minio_client().make_bucket(user.username) + if not get_minio_client().bucket_exists(user.bucket_name): + get_minio_client().make_bucket(user.bucket_name) + print(f"created bucket: {user.bucket_name}") print(f"User {user.id} has registered.") async def on_after_forgot_password(self, user: User, token: str, request: Optional[Request] = None):