diff --git a/backend/capellacollab/projects/users/routes.py b/backend/capellacollab/projects/users/routes.py index b0a5d3c33..5f1cc8f31 100644 --- a/backend/capellacollab/projects/users/routes.py +++ b/backend/capellacollab/projects/users/routes.py @@ -51,17 +51,23 @@ def get_project_user_association_or_raise( db: orm.Session, project: projects_models.DatabaseProject, user: users_models.DatabaseUser, -) -> models.ProjectUserAssociation: - if not ( - project_user := crud.get_project_user_association(db, project, user) - ): - raise fastapi.HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail={ - "reason": f"User {user.name} does not exist in project {project.slug}" - }, +) -> models.ProjectUserAssociation | models.ProjectUser: + if project_user := crud.get_project_user_association(db, project, user): + return project_user + + if project.visibility == projects_models.Visibility.INTERNAL: + return models.ProjectUser( + role=models.ProjectUserRole.USER, + permission=models.ProjectUserPermission.READ, + user=user, ) - return project_user + + raise fastapi.HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail={ + "reason": f"User {user.name} does not exist in project {project.slug}" + }, + ) @router.get("/current", response_model=models.ProjectUser) diff --git a/backend/tests/projects/test_projects_users_routes.py b/backend/tests/projects/test_projects_users_routes.py new file mode 100644 index 000000000..f0c655b2d --- /dev/null +++ b/backend/tests/projects/test_projects_users_routes.py @@ -0,0 +1,169 @@ +# SPDX-FileCopyrightText: Copyright DB Netz AG and the capella-collab-manager contributors +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from fastapi import testclient +from sqlalchemy import orm + +from capellacollab.projects import crud as projects_crud +from capellacollab.projects import models as projects_models +from capellacollab.projects.users import crud as projects_users_crud +from capellacollab.projects.users import models as projects_users_models +from capellacollab.users import crud as users_crud +from capellacollab.users import models as users_models + + +def test_assign_read_write_permission_when_adding_manager( + db: orm.Session, + client: testclient.TestClient, + executor_name: str, + unique_username: str, + project: projects_models.DatabaseProject, +): + users_crud.create_user(db, executor_name, users_models.Role.ADMIN) + user = users_crud.create_user(db, unique_username, users_models.Role.USER) + + response = client.post( + f"/api/v1/projects/{project.slug}/users/", + json={ + "role": projects_users_models.ProjectUserRole.MANAGER.value, + "permission": projects_users_models.ProjectUserPermission.READ.value, + "username": user.name, + "reason": "", + }, + ) + + project_user = projects_users_crud.get_project_user_association( + db, project, user + ) + + assert response.status_code == 200 + assert project_user + assert project_user.role == projects_users_models.ProjectUserRole.MANAGER + assert ( + project_user.permission + == projects_users_models.ProjectUserPermission.WRITE + ) + + +def test_assign_read_write_permission_when_changing_project_role_to_manager( + db: orm.Session, + client: testclient.TestClient, + executor_name: str, + unique_username: str, + project: projects_models.DatabaseProject, +): + users_crud.create_user(db, executor_name, users_models.Role.ADMIN) + user = users_crud.create_user(db, unique_username, users_models.Role.USER) + + projects_users_crud.add_user_to_project( + db, + project, + user, + projects_users_models.ProjectUserRole.USER, + projects_users_models.ProjectUserPermission.READ, + ) + + response = client.patch( + f"/api/v1/projects/{project.slug}/users/{user.id}", + json={ + "role": projects_users_models.ProjectUserRole.MANAGER.value, + "reason": "", + }, + ) + + project_user = projects_users_crud.get_project_user_association( + db, project, user + ) + + assert response.status_code == 204 + assert project_user + assert project_user.role == projects_users_models.ProjectUserRole.MANAGER + assert ( + project_user.permission + == projects_users_models.ProjectUserPermission.WRITE + ) + + +def test_http_exception_when_updating_permission_of_manager( + db: orm.Session, + client: testclient.TestClient, + executor_name: str, + unique_username: str, + project: projects_models.DatabaseProject, +): + users_crud.create_user(db, executor_name, users_models.Role.ADMIN) + user = users_crud.create_user(db, unique_username, users_models.Role.USER) + + projects_users_crud.add_user_to_project( + db, + project, + user, + projects_users_models.ProjectUserRole.MANAGER, + projects_users_models.ProjectUserPermission.WRITE, + ) + + response = client.patch( + f"/api/v1/projects/{project.slug}/users/{user.id}", + json={ + "permission": projects_users_models.ProjectUserPermission.READ.value, + "reason": "", + }, + ) + + assert response.status_code == 403 + assert response.json() == { + "detail": { + "reason": "You are not allowed to set the permission of project leads!" + } + } + + +@pytest.mark.usefixtures("unique_username") +def test_current_user_rights_for_internal_project( + db: orm.Session, + client: testclient.TestClient, + executor_name: str, + project: projects_models.DatabaseProject, +): + projects_crud.update_project( + db, + project, + projects_models.PatchProject( + visibility=projects_models.Visibility.INTERNAL + ), + ) + users_crud.create_user(db, executor_name, users_models.Role.USER) + + response = client.get( + f"/api/v1/projects/{project.slug}/users/current", + ) + + assert response.status_code == 200 + assert response.json()["role"] == "user" + assert response.json()["permission"] == "read" + + +@pytest.mark.usefixtures("unique_username") +def test_no_user_rights_on_internal_permissions( + db: orm.Session, + client: testclient.TestClient, + executor_name: str, + project: projects_models.DatabaseProject, +): + projects_crud.update_project( + db, + project, + projects_models.PatchProject( + visibility=projects_models.Visibility.PRIVATE + ), + ) + users_crud.create_user(db, executor_name, users_models.Role.USER) + + response = client.get( + f"/api/v1/projects/{project.slug}/users/current", + ) + + assert response.status_code == 404 + assert "detail" in response.json() + assert "reason" in response.json()["detail"] diff --git a/backend/tests/sessions/test_projects_users_routes.py b/backend/tests/sessions/test_projects_users_routes.py deleted file mode 100644 index 1deaa1075..000000000 --- a/backend/tests/sessions/test_projects_users_routes.py +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB Netz AG and the capella-collab-manager contributors -# SPDX-License-Identifier: Apache-2.0 - -from capellacollab.projects.users.crud import ( - add_user_to_project, - get_project_user_association, -) -from capellacollab.projects.users.models import ( - ProjectUserPermission, - ProjectUserRole, -) -from capellacollab.users.crud import create_user -from capellacollab.users.models import Role - - -def test_assign_read_write_permission_when_adding_manager( - db, client, executor_name, unique_username, project -): - create_user(db, executor_name, Role.ADMIN) - user = create_user(db, unique_username, Role.USER) - - response = client.post( - f"/api/v1/projects/{project.slug}/users/", - json={ - "role": ProjectUserRole.MANAGER.value, - "permission": ProjectUserPermission.READ.value, - "username": user.name, - "reason": "", - }, - ) - - project_user = get_project_user_association(db, project, user) - - assert response.status_code == 200 - assert project_user - assert project_user.role == ProjectUserRole.MANAGER - assert project_user.permission == ProjectUserPermission.WRITE - - -def test_assign_read_write_permission_when_changing_project_role_to_manager( - db, client, executor_name, unique_username, project -): - create_user(db, executor_name, Role.ADMIN) - user = create_user(db, unique_username, Role.USER) - - add_user_to_project( - db, project, user, ProjectUserRole.USER, ProjectUserPermission.READ - ) - - response = client.patch( - f"/api/v1/projects/{project.slug}/users/{user.id}", - json={ - "role": ProjectUserRole.MANAGER.value, - "reason": "", - }, - ) - - project_user = get_project_user_association(db, project, user) - - assert response.status_code == 204 - assert project_user - assert project_user.role == ProjectUserRole.MANAGER - assert project_user.permission == ProjectUserPermission.WRITE - - -def test_http_exception_when_updating_permission_of_manager( - db, client, executor_name, unique_username, project -): - create_user(db, executor_name, Role.ADMIN) - user = create_user(db, unique_username, Role.USER) - - add_user_to_project( - db, project, user, ProjectUserRole.MANAGER, ProjectUserPermission.WRITE - ) - - response = client.patch( - f"/api/v1/projects/{project.slug}/users/{user.id}", - json={ - "permission": ProjectUserPermission.READ.value, - "reason": "", - }, - ) - - assert response.status_code == 403 - assert response.json() == { - "detail": { - "reason": "You are not allowed to set the permission of project leads!" - } - }