Skip to content

Commit

Permalink
backend: add delete from group endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
xerbalind committed May 5, 2024
1 parent 66c58cd commit 7e11cd6
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 18 deletions.
14 changes: 13 additions & 1 deletion backend/src/group/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,24 @@ async def create_group_validation(
raise NotAuthorized()


async def groups_permission_validation(
group_id: int,
user: User = Depends(get_authenticated_user),
db: AsyncSession = Depends(get_async_db)
):

from src.group.utils import has_group_privileges
if not await has_group_privileges(group_id, user, db, False):
raise NotAuthorized()


async def join_group(
group_id: int,
uid: Optional[str] = None,
db: AsyncSession = Depends(get_async_db),
user: User = Depends(get_authenticated_user)
) -> Group:

if not uid:
uid = user.uid

Expand All @@ -67,4 +79,4 @@ async def join_group(
raise MaxCapacity()

await service.join_group(db, group_id, uid)
return group
return await service.get_group_by_id(db, group_id)
21 changes: 13 additions & 8 deletions backend/src/group/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from src.dependencies import get_async_db
from src.group.dependencies import (
create_group_validation,
groups_permission_validation,
retrieve_group,
retrieve_groups_by_project,
)
from src.group.dependencies import join_group as join_group_dependency
from src.group.exceptions import GroupNotFound
Expand All @@ -27,11 +27,6 @@
)


@router.get("/")
async def get_groups(groups: list[Group] = Depends(retrieve_groups_by_project)):
return groups


@router.post("/", status_code=201, dependencies=[Depends(create_group_validation)])
async def create_group(group: GroupCreate, db: AsyncSession = Depends(get_async_db)):
return await service.create_group(db, group)
Expand All @@ -42,7 +37,12 @@ async def get_group(group: Group = Depends(retrieve_group)):
return group


@router.delete("/{group_id}", status_code=200)
@router.delete("/{group_id}", dependencies=[Depends(groups_permission_validation)])
async def delete_group(group_id: int, db: AsyncSession = Depends(get_async_db)):
await service.delete_group(db, group_id)


@router.post("/{group_id}/leave", status_code=200)
async def leave_group(
group: Group = Depends(retrieve_group),
user: User = Depends(get_authenticated_user),
Expand All @@ -66,6 +66,11 @@ async def list_submissions(group_id: int,
return await get_submissions_by_group(db, group_id)


@router.post("/{group_id}/{uid}", status_code=201,)
@router.post("/{group_id}/{uid}", status_code=201, dependencies=[Depends(groups_permission_validation)])
async def join_group_by_uid(group: Group = Depends(join_group_dependency)) -> Group:
return group


@router.delete("/{group_id}/{uid}", status_code=200, dependencies=[Depends(groups_permission_validation)])
async def remove_user_from_group(group_id: int, uid: str, db: AsyncSession = Depends(get_async_db)):
await service.leave_group(db, group_id, uid)
7 changes: 6 additions & 1 deletion backend/src/group/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ async def create_group(db: AsyncSession, group: schemas.GroupCreate) -> Group:
async def join_group(db: AsyncSession, team_id: int, user_id: str):
insert_stmnt = StudentGroup.insert().values(team_id=team_id, uid=user_id)
await db.execute(insert_stmnt)
await db.flush()
await db.commit()


async def leave_group(db: AsyncSession, team_id: int, user_id: str):
await db.execute(delete(StudentGroup).filter_by(team_id=team_id, uid=user_id))
await db.commit()


async def delete_group(db: AsyncSession, group_id: int):
await db.execute(delete(Group).filter_by(id=group_id))
await db.commit()
5 changes: 3 additions & 2 deletions backend/src/group/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
async def has_group_privileges(
group_id: int,
user: User,
db: AsyncSession
db: AsyncSession,
or_member=True
) -> bool:
group = await retrieve_group(group_id, db)
project = await retrieve_project(group.project_id, user, db)
return await has_subject_privileges(project.subject_id, user, db) or user in group.members
return await has_subject_privileges(project.subject_id, user, db) or (or_member and user in group.members)
1 change: 0 additions & 1 deletion backend/src/project/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,4 @@ async def patch_permission_validation(
):
await user_permission_validation(project.subject_id, user, db)


delete_permission_validation = patch_permission_validation
2 changes: 1 addition & 1 deletion backend/src/project/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ProjectBase(BaseModel):
deadline: datetime
description: str
subject_id: int
is_visible: bool = Field(default=False)
is_visible: bool = Field(default=True)
capacity: int = Field(gt=0)
requirements: List[Requirement] = []

Expand Down
15 changes: 13 additions & 2 deletions backend/tests/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,20 @@ async def test_join_user(client: AsyncClient, group_id: int):
@pytest.mark.asyncio
async def test_remove_user(client: AsyncClient, group_id: int):
response = await client.post(f"/api/groups/{group_id}")
response = await client.delete(f"/api/groups/{group_id}")
response = await client.post(f"/api/groups/{group_id}/leave")
assert response.status_code == 200
response = await client.post(f"/api/groups/{group_id}/leave")
assert response.status_code == 404


@pytest.mark.asyncio
async def test_delete_group(client: AsyncClient, group_id: int, db: AsyncSession):
response = await client.delete(f"/api/groups/{group_id}")
assert response.status_code == 403 # Forbidden
await set_teacher(db, "test", True)
response = await client.delete(f"/api/groups/{group_id}")
assert response.status_code == 200
response = await client.get(f"/api/groups/{group_id}")
assert response.status_code == 404


Expand All @@ -87,7 +98,7 @@ async def test_list_submissions(client: AsyncClient, group_id: int, db: AsyncSes
assert response.status_code == 200
assert response.json() == []

response = await client.delete(f"/api/groups/{group_id}")
response = await client.post(f"/api/groups/{group_id}/leave")

response = await client.get(f"/api/groups/{group_id}/submissions")
assert response.status_code == 403 # No permission again
Expand Down
4 changes: 2 additions & 2 deletions backend/tests/test_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async def test_create_submission(client: AsyncClient, group_id: int):
assert response.status_code == 201

# Leave group
await client.delete(f"/api/groups/{group_id}")
await client.post(f"/api/groups/{group_id}/leave")

# List files
id = response.json()['id']
Expand All @@ -48,7 +48,7 @@ async def test_create_submission(client: AsyncClient, group_id: int):
assert response.json()[0]["filename"] in ["testfile1.txt", "testfile2.txt"]

# Leave group
await client.delete(f"/api/groups/{group_id}")
await client.post(f"/api/groups/{group_id}/leave")

response = await client.get(f"/api/submissions/{id}/files/testfile1.txt")
assert response.status_code == NotAuthorized().status_code # Not authorized
Expand Down

0 comments on commit 7e11cd6

Please sign in to comment.