diff --git a/api/urls.py b/api/urls.py index c4362fcef..5cd2d35ff 100644 --- a/api/urls.py +++ b/api/urls.py @@ -12,7 +12,7 @@ path("task-list/", default_view.tasks_list_all), path("student-list", default_view.student_list), path("submits/", default_view.create_submit), - path("info", default_view.info), + path("info", default_view.info, name="api_info"), path("classes", default_view.class_detail_list), path("classes/all", default_view.all_classes), path("classes//add_students", default_view.add_student_to_class), diff --git a/quiz/middleware.py b/quiz/middleware.py index fef86f299..cbdb7525f 100644 --- a/quiz/middleware.py +++ b/quiz/middleware.py @@ -1,7 +1,9 @@ from django.http import HttpResponseRedirect from django.urls import reverse, resolve, Resolver404 from enum import Enum -from quiz.models import EnrolledQuiz +from kelvin.settings import DEBUG +from debug_toolbar.toolbar import DebugToolbar +from quiz.quiz_utils import quiz_running_for_user class SubmitType(Enum): @@ -19,28 +21,33 @@ def __init__(self, get_response): self.get_response = get_response def __call__(self, request): - try: - enrolled_quiz = EnrolledQuiz.objects.get(student=request.user.id, submitted=False) + enrolled_quiz = quiz_running_for_user(request.user) + if enrolled_quiz is not None: fill_url = reverse("quiz_fill") allowed_urls = [ fill_url, reverse("api_quiz_results", args=[enrolled_quiz.id, SubmitType.PERIODIC.value]), reverse("api_quiz_results", args=[enrolled_quiz.id, SubmitType.MANUAL.value]), + reverse("api_info"), + reverse("notification_all"), + reverse("notification_mark_as_read_all"), reverse("cas_ng_logout"), ] try: - if resolve(request.path_info).url_name == "quiz_asset": + resolved_path = resolve(request.path_info).url_name + if resolved_path == "quiz_asset": + allowed_urls.append(request.path_info) + elif resolved_path == "notification_mark_as_read_single": allowed_urls.append(request.path_info) except Resolver404: pass - if request.path_info not in allowed_urls: + debug_toolbar = DEBUG and DebugToolbar.is_toolbar_request(request) + if not debug_toolbar and request.path_info not in allowed_urls: return HttpResponseRedirect(fill_url) - except EnrolledQuiz.DoesNotExist: - pass response = self.get_response(request) diff --git a/quiz/quiz_utils.py b/quiz/quiz_utils.py index 2816b398e..52e564c4e 100644 --- a/quiz/quiz_utils.py +++ b/quiz/quiz_utils.py @@ -1,5 +1,6 @@ from django.contrib.auth.models import User +from typing import Optional from common.models import Class from quiz.models import Quiz, AssignedQuiz, EnrolledQuiz from web.markdown_utils import process_markdown @@ -13,6 +14,17 @@ class QuizException(Exception): pass +def quiz_running_for_user(user: User) -> Optional[EnrolledQuiz]: + """ + Returns currently running quiz for given user. + If user is not running a quiz at the moment, None is returned. + """ + try: + return EnrolledQuiz.objects.get(student=user.id, submitted=False) + except EnrolledQuiz.DoesNotExist: + return None + + def quiz_assigned_classes(quiz: Quiz, requested_by: int): """ Function that returns a list of classes that are/can be assigned to the quiz. diff --git a/web/urls.py b/web/urls.py index ca294e571..2331d52a3 100644 --- a/web/urls.py +++ b/web/urls.py @@ -69,9 +69,17 @@ ), path("submit//pipeline", student_view.pipeline_status), # notifications - path("notification/all", notification_view.all_notifications), - path("notification/mark_as_read", notification_view.mark_as_read), - path("notification/mark_as_read/", notification_view.mark_as_read), + path("notification/all", notification_view.all_notifications, name="notification_all"), + path( + "notification/mark_as_read", + notification_view.mark_as_read, + name="notification_mark_as_read_all", + ), + path( + "notification/mark_as_read/", + notification_view.mark_as_read, + name="notification_mark_as_read_single", + ), # teacher path("teacher/task/", teacher_view.teacher_task, name="teacher_task"), path("teacher/task/.tar", student_view.teacher_task_tar, name="teacher_task_tar"),