Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Add modify_user_roles and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
msathieu committed Mar 10, 2024
1 parent 4a82e08 commit 7e6363a
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 26 deletions.
15 changes: 9 additions & 6 deletions backend/db/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ def to_domain_model(self) -> UserDataclass:


@dataclass()
class Admin(User):
class Admin(Base, AbstractModel):
__tablename__ = "admins"
id: Mapped[int] = mapped_column(ForeignKey(User.id), primary_key=True)
user: Mapped[User] = relationship()

def to_domain_model(self) -> AdminDataclass:
return AdminDataclass(id=self.id, name=self.name, email=self.email)
return AdminDataclass(id=self.id, name=self.user.name, email=self.user.email)


teachers_subjects = Table(
Expand All @@ -68,25 +69,27 @@ def to_domain_model(self) -> AdminDataclass:


@dataclass()
class Teacher(User):
class Teacher(Base, AbstractModel):
__tablename__ = "teachers"
id: Mapped[int] = mapped_column(ForeignKey(User.id), primary_key=True)
user: Mapped[User] = relationship()
subjects: Mapped[list["Subject"]] = relationship(secondary=teachers_subjects, back_populates="teachers")

def to_domain_model(self) -> TeacherDataclass:
return TeacherDataclass(id=self.id, name=self.name, email=self.email)
return TeacherDataclass(id=self.id, name=self.user.name, email=self.user.email)


@dataclass()
class Student(User):
class Student(Base, AbstractModel):
__tablename__ = "students"
id: Mapped[int] = mapped_column(ForeignKey(User.id), primary_key=True)
user: Mapped[User] = relationship()
subjects: Mapped[list["Subject"]] = relationship(secondary=students_subjects, back_populates="students")
groups: Mapped[list["Group"]] = relationship(secondary=students_groups, back_populates="students")
submissions: Mapped[list["Submission"]] = relationship(back_populates="student")

def to_domain_model(self) -> StudentDataclass:
return StudentDataclass(id=self.id, name=self.name, email=self.email)
return StudentDataclass(id=self.id, name=self.user.name, email=self.user.email)


@dataclass()
Expand Down
8 changes: 5 additions & 3 deletions backend/domain/logic/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from sqlalchemy.orm import Session

from db.models.models import Admin
from db.models.models import Admin, User
from domain.logic.basic_operations import get, get_all
from domain.models.AdminDataclass import AdminDataclass


def create_admin(session: Session, name: str, email: str) -> AdminDataclass:
new_admin: Admin = Admin(name=name, email=email)
new_user: User = User(name=name, email=email)
session.add(new_user)
session.commit()
new_admin: Admin = Admin(id=new_user.id)
session.add(new_admin)
session.commit()
return new_admin.to_domain_model()
Expand All @@ -20,7 +23,6 @@ def get_all_admins(session: Session) -> list[AdminDataclass]:
return [admin.to_domain_model() for admin in get_all(session, Admin)]



def is_user_admin(session: Session, user_id: int) -> bool:
admin = session.get(Admin, user_id)
return admin is not None
7 changes: 5 additions & 2 deletions backend/domain/logic/student.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from sqlalchemy.orm import Session

from db.models.models import Student
from db.models.models import Student, User
from domain.logic.basic_operations import get, get_all
from domain.models.StudentDataclass import StudentDataclass


def create_student(session: Session, name: str, email: str) -> StudentDataclass:
new_student: Student = Student(name=name, email=email)
new_user: User = User(name=name, email=email)
session.add(new_user)
session.commit()
new_student: Student = Student(id=new_user.id)
session.add(new_student)
session.commit()
return new_student.to_domain_model()
Expand Down
7 changes: 5 additions & 2 deletions backend/domain/logic/teacher.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from sqlalchemy.orm import Session

from db.models.models import Teacher
from db.models.models import Teacher, User
from domain.logic.basic_operations import get, get_all
from domain.models.TeacherDataclass import TeacherDataclass


def create_teacher(session: Session, name: str, email: str) -> TeacherDataclass:
new_teacher: Teacher = Teacher(name=name, email=email)
new_user: User = User(name=name, email=email)
session.add(new_user)
session.commit()
new_teacher: Teacher = Teacher(id=new_user.id)
session.add(new_teacher)
session.commit()
return new_teacher.to_domain_model()
Expand Down
17 changes: 16 additions & 1 deletion backend/domain/logic/user.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from sqlalchemy.orm import Session

from db.models.models import User
from db.models.models import Admin, Student, Teacher, User
from domain.logic.admin import is_user_admin
from domain.logic.basic_operations import get, get_all
from domain.logic.role_enum import Role
Expand Down Expand Up @@ -31,3 +31,18 @@ def get_user(session: Session, user_id: int) -> UserDataclass:

def get_all_users(session: Session) -> list[UserDataclass]:
return [user.to_domain_model() for user in get_all(session, User)]


def modify_user_roles(session: Session, uid: int, roles: list[Role]) -> None:
if Role.STUDENT in roles and session.get(Student, uid) is None:
student = Student(id=uid)
session.add(student)
if Role.TEACHER in roles and session.get(Teacher, uid) is None:
teacher = Teacher(id=uid)
session.add(teacher)
if Role.ADMIN in roles and session.get(Admin, uid) is None:
admin = Admin(id=uid)
session.add(admin)
if Role.ADMIN not in roles and session.get(Admin, uid) is not None:
session.delete(get(session, Admin, uid))
session.commit()
4 changes: 4 additions & 0 deletions backend/domain/models/SubjectDataclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
class SubjectDataclass(BaseModel):
id: int
name: str


class SubjectInput(BaseModel):
name: str
2 changes: 1 addition & 1 deletion backend/routes/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


@project_router.get("/projects/{project_id}")
def get_subject_project(project_id: int, session: Session = Depends(get_session)) -> ProjectDataclass:
def project_get(project_id: int, session: Session = Depends(get_session)) -> ProjectDataclass:
project: ProjectDataclass = get_project(session, project_id)
ensure_user_authorized_for_subject(project.subject_id)
return project
11 changes: 4 additions & 7 deletions backend/routes/teacher.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from db.sessions import get_session
from domain.logic.subject import create_subject, get_subjects_of_teacher
from domain.models.SubjectDataclass import SubjectDataclass
from domain.models.SubjectDataclass import SubjectDataclass, SubjectInput
from domain.models.TeacherDataclass import TeacherDataclass
from routes.dependencies.role_dependencies import get_authenticated_teacher

Expand All @@ -13,19 +13,16 @@

@teacher_router.get("/teacher/subjects")
def subjects_of_teacher_get(
session: Session = Depends(get_session),
teacher: TeacherDataclass = Depends(get_authenticated_teacher),
session: Session = Depends(get_session),
teacher: TeacherDataclass = Depends(get_authenticated_teacher),
) -> list[SubjectDataclass]:
return get_subjects_of_teacher(session, teacher.id)


@teacher_router.post("/teacher/subjects", dependencies=[Depends(get_authenticated_teacher)])
def create_subject_post(
subject: SubjectDataclass,
subject: SubjectInput,
session: Session = Depends(get_session),
) -> Response:
create_subject(session, name=subject.name)
return Response(status_code=status.HTTP_201_CREATED)



15 changes: 11 additions & 4 deletions backend/routes/user.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, Response, status
from sqlalchemy.orm import Session

from db.models.models import User
from db.sessions import get_session
from domain.logic.basic_operations import get, get_all
from domain.logic.user import convert_user
from domain.logic.role_enum import Role
from domain.logic.user import convert_user, modify_user_roles
from domain.models.APIUser import APIUser
from domain.models.UserDataclass import UserDataclass
from routes.dependencies.role_dependencies import get_authenticated_admin, get_authenticated_user
Expand All @@ -14,8 +15,8 @@

@users_router.get("/user")
def get_current_user(
session: Session = Depends(get_session),
user_id: int = Depends(get_authenticated_user),
session: Session = Depends(get_session),
user_id: int = Depends(get_authenticated_user),
) -> APIUser:
user: UserDataclass = get(session, User, user_id).to_domain_model()
return convert_user(session, user)
Expand All @@ -31,3 +32,9 @@ def get_users(session: Session = Depends(get_session)) -> list[APIUser]:
def get_user(uid: int, session: Session = Depends(get_session)) -> APIUser:
user: UserDataclass = get(session, User, uid).to_domain_model()
return convert_user(session, user)


@users_router.patch("/users/{uid}", dependencies=[Depends(get_authenticated_admin)])
def modify_user(uid: int, roles: list[Role], session: Session = Depends(get_session)) -> Response:
modify_user_roles(session, uid, roles)
return Response(status_code=status.HTTP_204_NO_CONTENT)

0 comments on commit 7e6363a

Please sign in to comment.