Skip to content

Commit

Permalink
fix: project permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
EwoutV committed May 22, 2024
1 parent 3dea579 commit 889757a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 22 deletions.
53 changes: 32 additions & 21 deletions backend/api/permissions/project_permissions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from api.models.assistant import Assistant
from api.models.student import Student
from api.models.teacher import Teacher
from api.permissions.role_permissions import (is_assistant, is_student,
is_teacher)
from authentication.models import User
Expand All @@ -11,38 +14,46 @@ class ProjectPermission(BasePermission):

def has_permission(self, request: Request, view: ViewSet) -> bool:
"""Check if user has permission to view a general project endpoint."""
user: User = request.user

# We only allow teachers and assistants to create new projects.
return is_teacher(user) or is_assistant(user)
return is_teacher(request.user) or is_assistant(request.user) or request.method in SAFE_METHODS

def has_object_permission(self, request: Request, view: ViewSet, project) -> bool:
"""Check if user has permission to view a detailed project endpoint"""
user: User = request.user
course = project.course
teacher_or_assistant = is_teacher(user) and user.teacher.courses.filter(id=course.id).exists() or \
is_assistant(user) and user.assistant.courses.filter(id=course.id).exists()
user = request.user

# Check if the user is a teacher that has the course linked to the project.
teacher = Teacher.objects.filter(id=user.id).first()
assistant = Assistant.objects.filter(id=user.id).first()
student = Student.objects.filter(id=user.id).first()

# Get the individual permission clauses.
teacher_permission = teacher is not None and teacher.courses.filter(id=project.course.id).exists()
assistant_permission = assistant is not None and assistant.courses.filter(id=project.course.id).exists()
student_permission = student is not None and student.courses.filter(id=project.course.id).exists()

if request.method in SAFE_METHODS:
# Users that are linked to the course can view the project.
return teacher_or_assistant or (is_student(user) and user.student.courses.filter(id=course.id).exists())
return teacher_permission or assistant_permission or student_permission

# We only allow teachers and assistants to modify specified projects.
return teacher_or_assistant
return teacher_permission or assistant_permission


class ProjectGroupPermission(BasePermission):
"""Permission class for project related group endpoints"""
def has_permission(self, request: Request, view: ViewSet) -> bool:
"""Check if user has permission to view a general project group endpoint."""
return is_teacher(request.user) or is_assistant(request.user) or request.method in SAFE_METHODS

def has_object_permission(self, request: Request, view: ViewSet, project) -> bool:
user: User = request.user
course = project.course
teacher_or_assistant = is_teacher(user) and user.teacher.courses.filter(id=course.id).exists() or \
is_assistant(user) and user.assistant.courses.filter(id=course.id).exists()
"""Check if user has permission to view a detailed project group endpoint"""
user = request.user

if request.method in SAFE_METHODS:
# Users that are linked to the course can view the group.
return teacher_or_assistant or (is_student(user) and user.student.courses.filter(id=course.id).exists())
# Check if the user is a teacher that has the course linked to the project.
teacher = Teacher.objects.filter(id=user.id).first()
assistant = Assistant.objects.filter(id=user.id).first()
student = Student.objects.filter(id=user.id).first()

# Get the individual permission clauses.
teacher_permission = teacher is not None and teacher.courses.filter(id=project.course.id).exists()
assistant_permission = assistant is not None and assistant.courses.filter(id=project.course.id).exists()
student_permission = student is not None and student.courses.filter(id=project.course.id).exists()

# We only allow teachers and assistants to create new groups.
return teacher_or_assistant
return teacher_permission or assistant_permission or student_permission
2 changes: 1 addition & 1 deletion backend/api/views/project_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ProjectViewSet(RetrieveModelMixin,
serializer_class = ProjectSerializer
permission_classes = [IsAdminUser | ProjectPermission] # GroupPermission has exact the same logic as for a project

@action(detail=True, permission_classes=[IsAdminUser | ProjectGroupPermission | IsStudent], url_path='student-group')
@action(detail=True, permission_classes=[IsAdminUser | ProjectGroupPermission], url_path='student-group')
def student_group(self, request: Request, **_) -> Response:
"""Returns the group of the student for the given project"""

Expand Down

0 comments on commit 889757a

Please sign in to comment.