Skip to content

Commit

Permalink
use bulk job to set project ACLs (#1446)
Browse files Browse the repository at this point in the history
  • Loading branch information
jarosenb authored Oct 4, 2024
1 parent d374e65 commit 453bab5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,41 +155,46 @@ def setup_project_file_system(project_uuid: str, users: list[str]):
# User creates the system and adds their credential
resp = create_workspace_system(service_client, project_uuid)

for username in users:
add_user_to_project_async.apply_async(args=[project_uuid, username])
# Add tg458981 to ensure it can read externally transferred data
acl_users = ["tg458981", *users]

add_users_to_project_async.apply_async(args=[project_uuid, acl_users])

return resp


def add_user_to_project(project_uuid: str, username: str, set_acls=True):
def add_user_to_project(project_uuid: str, username: str):
"""
Give a user POSIX and Tapis permissions on a workspace system.
"""
service_client = service_account()
system_id = f"project-{project_uuid}"
logger.debug("Adding user %s to system %s", username, system_id)
if set_acls:
job_res = submit_workspace_acls_job(username, project_uuid, action="add")
logger.debug(
"Submitted workspace ACL job %s with UUID %s", job_res.name, job_res.uuid
)

service_client.systems.shareSystem(systemId=system_id, users=[username])
set_workspace_permissions(service_client, username, system_id, role="writer")

return project_uuid


def add_users_to_project(project_uuid: str, usernames: list[str]):
"""Add multiple users to a project and set their ACLs using a single Tapis job."""
for username in usernames:
add_user_to_project(project_uuid, username)

job_res = submit_workspace_acls_job(",".join(usernames), project_uuid, action="add")
logger.debug(
"Submitted workspace ACL job %s with UUID %s", job_res.name, job_res.uuid
)


def remove_user_from_project(project_uuid: str, username: str):
"""
Unshare the system and remove all permissions and credentials.
"""
service_client = service_account()
system_id = f"project-{project_uuid}"
logger.debug("Removing user %s from system %s", username, system_id)
job_res = submit_workspace_acls_job(username, project_uuid, action="remove")
logger.debug(
"Submitted workspace ACL job %s with UUID %s", job_res.name, job_res.uuid
)

service_client.systems.unShareSystem(systemId=system_id, users=[username])
service_client.systems.revokeUserPerms(
Expand All @@ -202,20 +207,33 @@ def remove_user_from_project(project_uuid: str, username: str):
return project_uuid


def remove_users_from_project(project_uuid: str, usernames: list[str]):
"""Remove multiple users from project, setting ACLs using a single Tapis job."""
for username in usernames:
remove_user_from_project(project_uuid, username)

acl_usernames = ",".join(usernames)

job_res = submit_workspace_acls_job(acl_usernames, project_uuid, action="remove")
logger.debug(
"Submitted workspace ACL job %s with UUID %s", job_res.name, job_res.uuid
)


##########################################
# ASYNC TASKS FOR USER ADDITION/REMOVAL
##########################################


@shared_task(bind=True)
def add_user_to_project_async(self, project_uuid: str, username: str):
def add_users_to_project_async(self, project_uuid: str, usernames: list[str]):
"""Async wrapper around add_user_to_project"""
with AsyncTaskContext():
add_user_to_project(project_uuid, username)
add_users_to_project(project_uuid, usernames)


@shared_task(bind=True)
def remove_user_from_project_async(self, project_uuid: str, username: str):
def remove_users_from_project_async(self, project_uuid: str, usernames: str):
"""Async wrapper around remove_user_from_project"""
with AsyncTaskContext():
remove_user_from_project(project_uuid, username)
remove_users_from_project(project_uuid, usernames)
4 changes: 2 additions & 2 deletions designsafe/apps/api/projects_v2/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

# pylint: disable=unused-import
from designsafe.apps.api.projects_v2.operations.project_system_operations import (
add_user_to_project_async,
remove_user_from_project_async,
add_users_to_project_async,
remove_users_from_project_async,
)
from designsafe.apps.api.projects_v2.models.project_metadata import ProjectMetadata
from designsafe.apps.api.projects_v2.operations.project_publish_operations import (
Expand Down
20 changes: 10 additions & 10 deletions designsafe/apps/api/projects_v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
from designsafe.apps.api.projects_v2.operations.project_system_operations import (
increment_workspace_count,
setup_project_file_system,
add_user_to_project_async,
remove_user_from_project_async,
add_users_to_project_async,
remove_users_from_project_async,
)
from designsafe.apps.api.projects_v2.schema_models.base import FileObj
from designsafe.apps.api.decorators import tapis_jwt_login
Expand Down Expand Up @@ -176,10 +176,10 @@ def put(self, request: HttpRequest, project_id: str):
BaseProject.model_validate(project.value),
BaseProject.model_validate(updated_project.value),
)
for user_to_add in users_to_add:
add_user_to_project_async.apply_async([project.uuid, user_to_add])
for user_to_remove in users_to_remove:
remove_user_from_project_async.apply_async([project.uuid, user_to_remove])
if users_to_add:
add_users_to_project_async.apply_async([project.uuid, users_to_add])
if users_to_remove:
remove_users_from_project_async.apply_async([project.uuid, users_to_remove])

return JsonResponse({"result": "OK"})

Expand Down Expand Up @@ -207,10 +207,10 @@ def patch(self, request: HttpRequest, project_id: str):
users_to_add, users_to_remove = get_changed_users(
prev_metadata, updated_metadata
)
for user_to_add in users_to_add:
add_user_to_project_async.apply_async([project.uuid, user_to_add])
for user_to_remove in users_to_remove:
remove_user_from_project_async.apply_async([project.uuid, user_to_remove])
if users_to_add:
add_users_to_project_async.apply_async([project.uuid, users_to_add])
if users_to_remove:
remove_users_from_project_async.apply_async([project.uuid, users_to_remove])

return JsonResponse({"result": "OK"})

Expand Down

0 comments on commit 453bab5

Please sign in to comment.