Skip to content

Commit

Permalink
feat: download log files
Browse files Browse the repository at this point in the history
  • Loading branch information
Topvennie committed May 13, 2024
1 parent 74fbb0d commit e9552e6
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 7 deletions.
59 changes: 59 additions & 0 deletions backend/api/permissions/submission_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from typing import cast

from api.models.submission import (ExtraCheckResult, StructureCheckResult,
Submission)
from api.permissions.role_permissions import (is_assistant, is_student,
is_teacher)
from authentication.models import User
from rest_framework.permissions import SAFE_METHODS, BasePermission
from rest_framework.request import Request
from rest_framework.views import APIView


class SubmissionPermission(BasePermission):
def has_permission(self, request: Request, view: APIView) -> bool:
if request.method not in SAFE_METHODS:
return False

user: User = cast(User, request.user)

return user.is_staff or is_teacher(user) or is_assistant(user)

def has_object_permission(self, request: Request, view: APIView, obj: Submission) -> bool:
if request.method not in SAFE_METHODS:
return False

user: User = cast(User, request.user)

if user.is_staff:
return True

if is_teacher(user) or is_assistant(user):
return True

return obj.group.students.filter(id=user.id).exists()


class StructureCheckResultPermission(SubmissionPermission):
def has_object_permission(self, request: Request, view: APIView, obj: StructureCheckResult) -> bool:
return super().has_object_permission(request, view, obj.submission)


class ExtraCheckResultPermission(SubmissionPermission):
def has_object_permission(self, request: Request, view: APIView, obj: ExtraCheckResult) -> bool:
return super().has_object_permission(request, view, obj.submission)


class ExtraCheckResultLogPermission(ExtraCheckResultPermission):
def has_object_permission(self, request: Request, view: APIView, obj: ExtraCheckResult) -> bool:
result = super().has_object_permission(request, view, obj)

if not result:
return False

user: User = cast(User, request.user)

if is_student(user):
return obj.extra_check.show_log

return True
6 changes: 5 additions & 1 deletion backend/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from api.views.group_view import GroupViewSet
from api.views.project_view import ProjectViewSet
from api.views.student_view import StudentViewSet
from api.views.submission_view import SubmissionViewSet
from api.views.submission_view import (ExtraCheckResultViewSet,
StructureCheckResultViewSet,
SubmissionViewSet)
from api.views.teacher_view import TeacherViewSet
from api.views.user_view import UserViewSet
from django.urls import include, path
Expand All @@ -29,6 +31,8 @@
router.register(r"file-extensions", FileExtensionViewSet, basename="file-extension")
router.register(r"faculties", FacultyViewSet, basename="faculty")
router.register(r"docker-images", DockerImageViewSet, basename="docker-image")
router.register(r"structure-check-results", StructureCheckResultViewSet, basename="structure-check-results")
router.register(r"extra-check-results", ExtraCheckResultViewSet, basename="extra-check-results")

urlpatterns = [
path("", include(router.urls)),
Expand Down
44 changes: 38 additions & 6 deletions backend/api/views/submission_view.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,51 @@
from api.models.submission import (ExtraCheckResult, StructureCheckResult,
Submission)
from api.permissions.submission_permissions import (
ExtraCheckResultLogPermission, ExtraCheckResultPermission,
StructureCheckResultPermission, SubmissionPermission)
from api.serializers.submission_serializer import (
ExtraCheckResultSerializer, StructureCheckResultSerializer,
SubmissionSerializer)
from django.http import FileResponse
from rest_framework import viewsets
from django.utils.translation import gettext as _
from rest_framework.decorators import action
from rest_framework.mixins import RetrieveModelMixin

from ..models.submission import Submission
from ..serializers.submission_serializer import SubmissionSerializer
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet


# TODO: Permission to ask for logs
class SubmissionViewSet(RetrieveModelMixin, viewsets.GenericViewSet):
class SubmissionViewSet(RetrieveModelMixin, GenericViewSet):
queryset = Submission.objects.all()
serializer_class = SubmissionSerializer
permission_classes = [SubmissionPermission]

@action(detail=True)
def zip(self, request, **_):
def zip(self, request, **__):
submission: Submission = self.get_object()

if not submission.zip:
return Response({"message": _("submission.download.zip")}, status=404)

return FileResponse(open(submission.zip.path, "rb"), as_attachment=True)


class StructureCheckResultViewSet(RetrieveModelMixin, GenericViewSet):
queryset = StructureCheckResult.objects.all()
serializer_class = StructureCheckResultSerializer
permission_classes = [StructureCheckResultPermission]


class ExtraCheckResultViewSet(RetrieveModelMixin, GenericViewSet):
queryset = ExtraCheckResult.objects.all()
serializer_class = ExtraCheckResultSerializer
permission_classes = [ExtraCheckResultPermission]

@action(detail=True, permission_classes=[ExtraCheckResultLogPermission])
def log(self, request, **__):
extra_check_result: ExtraCheckResult = self.get_object()

if not extra_check_result.log_file:
return Response({"message": _("extra_check_result.download.log")}, status=404)

return FileResponse(open(extra_check_result.log_file.path, "rb"), as_attachment=True)

0 comments on commit e9552e6

Please sign in to comment.