diff --git a/backend/app.py b/backend/app.py index 52bf6714..1ec9e990 100644 --- a/backend/app.py +++ b/backend/app.py @@ -6,6 +6,7 @@ from db.errors.database_errors import ActionAlreadyPerformedError, ItemNotFoundError from routes.errors.authentication import InvalidRoleCredentialsError, NoAccessToSubjectError +from routes.group import group_router from routes.project import project_router from routes.student import student_router from routes.subject import subject_router @@ -20,6 +21,7 @@ app.include_router(users_router, prefix="/api") app.include_router(project_router, prefix="/api") app.include_router(subject_router, prefix="/api") +app.include_router(group_router, prefix="/api") # Koppel de exception handlers diff --git a/backend/domain/logic/group.py b/backend/domain/logic/group.py index 76c2582c..788e95d8 100644 --- a/backend/domain/logic/group.py +++ b/backend/domain/logic/group.py @@ -1,4 +1,3 @@ - from sqlalchemy.orm import Session from db.errors.database_errors import ActionAlreadyPerformedError @@ -51,6 +50,18 @@ def add_student_to_group(session: Session, student_id: int, group_id: int) -> No session.commit() +def remove_student_from_group(session: Session, student_id: int, group_id: int) -> None: + student: Student = get(session, Student, ident=student_id) + group: Group = get(session, Group, ident=group_id) + + if student not in group.students: + msg = f"Student with id {student_id} is not in group with id {group_id}" + raise ActionAlreadyPerformedError(msg) + + group.students.remove(student) + session.commit() + + def get_students_of_group(session: Session, group_id: int) -> list[StudentDataclass]: group: Group = get(session, Group, ident=group_id) students: list[Student] = group.students diff --git a/backend/fill_database_mock.py b/backend/fill_database_mock.py index 880048fa..98d1b126 100644 --- a/backend/fill_database_mock.py +++ b/backend/fill_database_mock.py @@ -8,7 +8,7 @@ from domain.logic.group import add_student_to_group, create_group from domain.logic.project import create_project from domain.logic.student import create_student -from domain.logic.subject import add_teacher_to_subject, create_subject +from domain.logic.subject import add_student_to_subject, add_teacher_to_subject, create_subject from domain.logic.teacher import create_teacher if __name__ == "__main__": @@ -83,6 +83,8 @@ add_teacher_to_subject(session, teacher2.id, algoritmen.id) add_teacher_to_subject(session, teacher3.id, webtech.id) + add_student_to_subject(session, student1.id, objeprog.id) + # Add students to groups add_student_to_group(session, student1.id, groep1_objprog.id) add_student_to_group(session, student2.id, groep1_objprog.id) diff --git a/backend/routes/dependencies/role_dependencies.py b/backend/routes/dependencies/role_dependencies.py index 78ddfbd5..9de95992 100644 --- a/backend/routes/dependencies/role_dependencies.py +++ b/backend/routes/dependencies/role_dependencies.py @@ -3,7 +3,8 @@ from db.sessions import get_session from domain.logic.admin import get_admin, is_user_admin -from domain.logic.project import get_project, get_projects_of_teacher +from domain.logic.group import get_group +from domain.logic.project import get_project, get_projects_of_student, get_projects_of_teacher from domain.logic.student import get_student, is_user_student from domain.logic.subject import get_subjects_of_student, get_subjects_of_teacher, is_user_authorized_for_subject from domain.logic.teacher import get_teacher, is_user_teacher @@ -93,3 +94,15 @@ def ensure_teacher_authorized_for_project( if project_id not in [project.id for project in projects_of_teacher]: raise NoAccessToSubjectError return teacher + + +def ensure_student_authorized_for_group( + group_id: int, + session: Session = Depends(get_session), + student: StudentDataclass = Depends(get_authenticated_student), +) -> StudentDataclass: + group = get_group(session, group_id) + projects_of_student = get_projects_of_student(session, student.id) + if group.project_id not in [project.id for project in projects_of_student]: + raise NoAccessToSubjectError + return student diff --git a/backend/routes/group.py b/backend/routes/group.py index e69de29b..22623654 100644 --- a/backend/routes/group.py +++ b/backend/routes/group.py @@ -0,0 +1,27 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session + +from db.sessions import get_session +from domain.logic.group import add_student_to_group, remove_student_from_group +from domain.models.StudentDataclass import StudentDataclass +from routes.dependencies.role_dependencies import ensure_student_authorized_for_group + +group_router = APIRouter() + + +@group_router.post("/groups/{group_id}/join") +def group_join( + group_id: int, + student: StudentDataclass = Depends(ensure_student_authorized_for_group), + session: Session = Depends(get_session), +) -> None: + add_student_to_group(session, student.id, group_id) + + +@group_router.post("/groups/{group_id}/leave") +def group_leave( + group_id: int, + student: StudentDataclass = Depends(ensure_student_authorized_for_group), + session: Session = Depends(get_session), +) -> None: + remove_student_from_group(session, student.id, group_id)