Skip to content

Commit e839aeb

Browse files
refactor permission
1 parent 0bf381e commit e839aeb

File tree

7 files changed

+48
-73
lines changed

7 files changed

+48
-73
lines changed

classroom/filters/classroom.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,24 @@ class Meta:
1515
@property
1616
def qs(self):
1717
parent = super().qs
18-
teacher = self.request.user
19-
classrooms_pks = teacher.classrooms_teaching.all().values_list('pk', flat=True)
20-
qs = parent.filter(pk__in=list(classrooms_pks))\
18+
19+
if self.request.user.is_teacher():
20+
classrooms = self.teacher_classrooms
21+
else:
22+
classrooms = self.student_classrooms
23+
classrooms_pks = list(classrooms.values_list('pk', flat=True))
24+
25+
qs = parent.filter(pk__in=classrooms_pks)\
2126
.select_related('teacher')\
2227
.prefetch_related('students')
2328
return qs
29+
30+
@property
31+
def teacher_classrooms(self):
32+
teacher = self.request.user
33+
return teacher.classrooms_teaching.all()
34+
35+
@property
36+
def student_classrooms(self):
37+
student = self.request.user
38+
return student.classrooms_studying.all()

classroom/filters/exercise.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ class Meta:
1515
@property
1616
def qs(self):
1717
parent = super().qs
18-
teacher = self.request.user
19-
exercises_pks = teacher.reading_exercises_created.all().values_list('pk', flat=True)
20-
qs = parent.filter(pk__in=list(exercises_pks))\
21-
.select_related('creator')
18+
user = self.request.user
19+
20+
if user.is_teacher():
21+
qs = parent.filter(creator=user)
22+
else:
23+
qs = parent.filter(classrooms__in=user.classrooms_studying.all()) # TODO: test
24+
qs = qs.select_related('creator')
25+
2226
return qs

classroom/filters/question.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ class Meta:
1414
def qs(self):
1515
parent = super().qs
1616
user = self.request.user
17-
exercises = user.reading_exercises_created.all()
18-
questions_pks = ReadingQuestion.objects.filter(exercise__in=exercises).values_list('pk', flat=True)
19-
qs = parent.filter(pk__in=list(questions_pks))\
20-
.select_related('exercise__creator')
17+
18+
if user.is_teacher():
19+
qs = parent.filter(exercise__creator=user)
20+
else:
21+
qs = parent.filter(exercise__classrooms__in=user.classrooms_studying.all()) # TODO: test
22+
qs = qs.select_related('exercise__creator')
23+
2124
return qs

classroom/permissions.py

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,15 @@
11
from django.utils.translation import gettext_lazy as _
2-
from rest_framework.permissions import IsAuthenticated
2+
from rest_framework.permissions import SAFE_METHODS, IsAuthenticated
33

44

5-
class IsTeacher(IsAuthenticated):
6-
message = _('Only teacher has permission for this.')
5+
class IsTeacherOrReadOnly(IsAuthenticated):
6+
message = _('Only teacher can edit this resource, student can only read.')
77

88
def has_permission(self, request, view):
9+
is_authenticated = super().has_permission(request, view)
10+
is_teacher = request.user.is_teacher()
911
return (
10-
super().has_permission(request, view) and
11-
request.user.is_teacher()
12-
)
13-
14-
15-
class IsClassroomTeacher(IsTeacher):
16-
message = _('Only teacher of this class room has permission for this.')
17-
18-
def has_object_permission(self, request, view, classroom):
19-
return (
20-
super().has_object_permission(request, view, classroom) and
21-
request.user == classroom.teacher
22-
)
23-
24-
25-
class IsTeacherOwnsExercise(IsTeacher):
26-
message = _('Only teacher who owns this exercise has permission for this.')
27-
28-
def has_object_permission(self, request, view, exercise):
29-
return (
30-
super().has_object_permission(request, view, exercise) and
31-
request.user == exercise.creator
32-
)
33-
34-
35-
class IsTeacherOwnsQuestion(IsTeacher):
36-
message = _('Only teacher who owns this question has permission for this.')
37-
38-
def has_object_permission(self, request, view, question):
39-
return (
40-
super().has_object_permission(request, view, question) and
41-
request.user == question.exercise.creator
42-
)
43-
44-
45-
class IsStudent(IsAuthenticated):
46-
message = _('Only student has permission for this.')
47-
48-
def has_permission(self, request, view):
49-
return (
50-
super().has_permission(request, view) and
51-
request.user.is_student()
52-
)
53-
54-
55-
class IsClassroomStudent(IsStudent):
56-
message = _('Only student of this class room has permission for this.')
57-
58-
def has_object_permission(self, request, view, classroom):
59-
return (
60-
super().has_object_permission(request, view, classroom) and
61-
request.user in classroom.students.all()
12+
is_authenticated and (
13+
request.method in SAFE_METHODS or is_teacher
14+
)
6215
)

classroom/views/classroom.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from classroom.business.teacher import classroom as teacher_business
77
from classroom.filters import ClassroomFilter
88
from classroom.models import Classroom
9-
from classroom.permissions import IsClassroomTeacher
9+
from classroom.permissions import IsTeacherOrReadOnly
1010
from classroom.serializers import (AddReadingExerciseSerializer,
1111
AddStudentSerializer, ClassroomSerializer,
1212
RemoveReadingExerciseSerializer,
@@ -17,7 +17,7 @@ class ClassroomViewSet(ModelViewSet):
1717
queryset = Classroom.objects.all()
1818
serializer_class = ClassroomSerializer
1919
filterset_class = ClassroomFilter
20-
permission_classes = [IsClassroomTeacher]
20+
permission_classes = [IsTeacherOrReadOnly]
2121
ordering_fields = ['create_datetime', 'name']
2222
ordering = ['-create_datetime']
2323

@@ -64,7 +64,7 @@ def remove_students(self, request, pk):
6464

6565
@action(
6666
methods=['POST'], detail=True, url_path='add-reading-exercises',
67-
serializer_class=AddReadingExerciseSerializer
67+
serializer_class=AddReadingExerciseSerializer,
6868
)
6969
def add_reading_exercises(self, request, pk):
7070
serializer = self.get_serializer(data=request.data, many=True)

classroom/views/exercise.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
from classroom.filters import ReadingExerciseFilter
44
from classroom.models import ReadingExercise
5-
from classroom.permissions import IsTeacherOwnsExercise
5+
from classroom.permissions import IsTeacherOrReadOnly
66
from classroom.serializers import ReadingExerciseSerializer
77

88

99
class ReadingExerciseViewSet(ModelViewSet):
1010
queryset = ReadingExercise.objects.all()
1111
serializer_class = ReadingExerciseSerializer
1212
filterset_class = ReadingExerciseFilter
13-
permission_classes = [IsTeacherOwnsExercise]
13+
permission_classes = [IsTeacherOrReadOnly]
1414
ordering_fields = ['identifier']
1515
ordering = ['identifier']

classroom/views/question.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
from classroom.filters import ReadingQuestionFilter
44
from classroom.models import ReadingQuestion
5-
from classroom.permissions import IsTeacherOwnsQuestion
5+
from classroom.permissions import IsTeacherOrReadOnly
66
from classroom.serializers import ReadingQuestionSerializer
77

88

99
class ReadingQuestionViewSet(ModelViewSet):
1010
queryset = ReadingQuestion.objects.all()
1111
serializer_class = ReadingQuestionSerializer
1212
filterset_class = ReadingQuestionFilter
13-
permission_classes = [IsTeacherOwnsQuestion]
13+
permission_classes = [IsTeacherOrReadOnly]
1414
ordering_fields = ['from_number']
1515
ordering = ['from_number']

0 commit comments

Comments
 (0)