Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import re
import tarfile
from datetime import timedelta
from datetime import timedelta, datetime
from functools import lru_cache
from typing import NewType

Expand All @@ -11,8 +11,10 @@
from django.http import HttpRequest
from ipware import get_client_ip

from .exceptions.http_exceptions import HttpException404, HttpException403
from .inbus import inbus


IPAddressString = NewType("IPAddressString", str)


Expand Down Expand Up @@ -109,3 +111,50 @@ def build_absolute_uri(request, location):
if base_uri:
return "".join([base_uri, location])
return request.build_absolute_uri(location)


def prohibit_during_test(function):
"""
Decorator that restricts access to a page if the student has any ongoing exams.

The decorated function must accept the following parameters:
- request
- assignment_id

During the ongoing test access is granted only for ongoing exams and tasks whose hard deadline ends before the exam starts.
"""

def wrapper(*args, **kwargs):
from .models import AssignedTask
from .task import get_active_exams_at

request = args[0]

if is_teacher(request.user):
return function(*args, **kwargs)

active_exams = get_active_exams_at(request.user, datetime.now(), timedelta(0))

if not active_exams:
return function(*args, **kwargs)

assignment_id = kwargs.get("assignment_id")

try:
assignment = AssignedTask.objects.get(pk=assignment_id)
except AssignedTask.DoesNotExist:
raise HttpException404(f"AssignedTask with id {assignment_id} not found")

# if task is any of ongoing exams allow it
for exam in active_exams:
if exam.pk == assignment_id:
return function(*args, **kwargs)

if assignment.has_hard_deadline() and assignment.deadline is not None:
# check if the deadline has expired before the start of all exams
if all(map(lambda e: assignment.deadline < e.assigned, active_exams)):
return function(*args, **kwargs)

raise HttpException403("Access to this task is prohibited during exam")

return wrapper
46 changes: 39 additions & 7 deletions web/views/student.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import tarfile
import tempfile
from collections import namedtuple
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any, Dict, List, Optional
from zipfile import ZIP_DEFLATED, ZipFile
Expand Down Expand Up @@ -61,8 +62,9 @@
)
from common.plagcheck.moss import PlagiarismMatch, moss_result
from common.submit import SubmitRateLimited, store_submit, SubmitPastHardDeadline
from common.task import get_active_exams_at
from common.upload import MAX_UPLOAD_FILECOUNT, TooManyFilesError
from common.utils import is_teacher
from common.utils import is_teacher, prohibit_during_test
from evaluator.results import EvaluationResult
from evaluator.testsets import TestSet
from kelvin.settings import BASE_DIR, MAX_INLINE_CONTENT_BYTES, MAX_INLINE_LINES
Expand Down Expand Up @@ -318,6 +320,7 @@ def build(match: PlagiarismMatch) -> PlagiarismEntry:


@login_required()
@prohibit_during_test
def task_detail(request, assignment_id, submit_num=None, login=None):
submits = Submit.objects.filter(
assignment__pk=assignment_id,
Expand Down Expand Up @@ -551,6 +554,7 @@ def submit_source(request, submit_id, path):


@login_required
@prohibit_during_test
def submit_diff(request, login, assignment_id, submit_a, submit_b):
submit = get_object_or_404(
Submit, assignment_id=assignment_id, student__username=login, submit_num=submit_a
Expand Down Expand Up @@ -614,6 +618,7 @@ def get_patch(p1, p2):


@login_required
@prohibit_during_test
def submit_comments(request, assignment_id, login, submit_num):
submit = get_object_or_404(
Submit, assignment_id=assignment_id, student__username=login, submit_num=submit_num
Expand Down Expand Up @@ -667,7 +672,19 @@ def dump_comment(comment):
"notification_id": notification_id,
}

currently_active_exams: List[AssignedTask] = get_active_exams_at(
request.user, datetime.now(), timedelta(0)
)

if request.method == "POST":
if not is_teacher(request.user) and len(currently_active_exams) > 0:
return JsonResponse(
{
"error": "It is not allowed to create new comment's during test. Please wait until test is done.."
},
status=400,
)

data = json.loads(request.body)
comment = Comment()
comment.submit = submit
Expand Down Expand Up @@ -774,6 +791,25 @@ def dump_comment(comment):

submit_data: SubmitData = get_submit_data(submit)

priorities = {
"video": 0,
"img": 1,
"source": 2,
}

if not is_teacher(request.user) and len(currently_active_exams) > 0:
return JsonResponse(
{
"sources": sorted(
result.values(), key=lambda f: (priorities[f["type"]], f["path"])
),
"summary_comments": [],
"submits": submits,
"current_submit": submit.submit_num,
"deadline": submit.assignment.deadline,
}
)

# add comments from pipeline
for pipe in submit_data.results:
for source, comments in pipe.comments.items():
Expand Down Expand Up @@ -876,12 +912,6 @@ def can_view_suggestion(state: SuggestionState, user) -> bool:
}
)

priorities = {
"video": 0,
"img": 1,
"source": 2,
}

return JsonResponse(
{
"sources": sorted(result.values(), key=lambda f: (priorities[f["type"]], f["path"])),
Expand Down Expand Up @@ -1088,6 +1118,7 @@ def raw_result_content(request, submit_id, test_name, result_type, file):
raise HttpException404()


@prohibit_during_test
def submit_download(request, assignment_id: int, login: str, submit_num: int):
submit = get_object_or_404(
Submit, assignment_id=assignment_id, student__username=login, submit_num=submit_num
Expand Down Expand Up @@ -1121,6 +1152,7 @@ def ui(request):


@csrf_exempt
@prohibit_during_test
def upload_results(request, assignment_id, submit_num, login):
submit = get_object_or_404(
Submit, assignment_id=assignment_id, submit_num=submit_num, student__username=login
Expand Down
Loading