allow supervisors to view shared exams
This commit is contained in:
+80
-27
@@ -79,6 +79,7 @@ from .forms import (
|
||||
|
||||
from .models import (
|
||||
CidUser,
|
||||
CidUserExam,
|
||||
CidUserGroup,
|
||||
ExamBase,
|
||||
ExamCollection,
|
||||
@@ -171,27 +172,34 @@ class CidManagerRequiredMixin(UserPassesTestMixin):
|
||||
|
||||
def get_user_exams(user, supervisor_view=False):
|
||||
EXAM_ANSWER_MAP = {
|
||||
"physics": (PhysicsUserAnswer, PhysicsExam),
|
||||
"anatomy": (AnatomyUserAnswer, AnatomyExam),
|
||||
"rapids": (RapidsUserAnswer, RapidsExam),
|
||||
"longs": (LongsUserAnswer, LongsExam),
|
||||
"sbas": (SbasUserAnswer, SbasExam),
|
||||
"physics": (PhysicsUserAnswer, PhysicsExam, "physics_exams"),
|
||||
"anatomy": (AnatomyUserAnswer, AnatomyExam, "anatomy_exams"),
|
||||
"rapids": (RapidsUserAnswer, RapidsExam, "rapids_exams"),
|
||||
"longs": (LongsUserAnswer, LongsExam, "longs_exams"),
|
||||
"sbas": (SbasUserAnswer, SbasExam, "sbas_exams"),
|
||||
}
|
||||
kwargs = {
|
||||
"exam_mode": True,
|
||||
"archive": False
|
||||
}
|
||||
kwargs = {"exam_mode": True, "archive": False}
|
||||
|
||||
exams = []
|
||||
|
||||
if supervisor_view:
|
||||
|
||||
kwargs["results_supervisor_visible"] = True
|
||||
del kwargs["archive"]
|
||||
|
||||
exams = []
|
||||
for exam_type in EXAM_ANSWER_MAP:
|
||||
UserAnswer, Exam = EXAM_ANSWER_MAP[exam_type]
|
||||
UserAnswer, Exam, cid_rel = EXAM_ANSWER_MAP[exam_type]
|
||||
exam_answers = UserAnswer.objects.filter(user=user)
|
||||
exam_ids = exam_answers.values_list("exam").distinct()
|
||||
exams_to_add = Exam.objects.filter(id__in=exam_ids, **kwargs)
|
||||
if supervisor_view:
|
||||
extra_exam_ids = CidUserExam.objects.filter(
|
||||
user_user=user,
|
||||
share_with_supervisor=True,
|
||||
content_type=ContentType.objects.get_for_model(Exam),
|
||||
).values_list(cid_rel)
|
||||
|
||||
exams_to_add = exams_to_add | Exam.objects.filter(id__in=extra_exam_ids)
|
||||
if exams_to_add:
|
||||
exams.append((exam_type, exams_to_add))
|
||||
|
||||
@@ -528,7 +536,11 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
if (exam.open_access and exam.active) or user in exam.get_author_objects():
|
||||
return True
|
||||
|
||||
if user.is_authenticated and exam.active and exam.cid_user_exam.filter(user_user=user):
|
||||
if (
|
||||
user.is_authenticated
|
||||
and exam.active
|
||||
and exam.cid_user_exam.filter(user_user=user)
|
||||
):
|
||||
return True
|
||||
|
||||
if marker and user in exam.markers.all():
|
||||
@@ -2091,14 +2103,18 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
if not request.user.supervisor == user.userprofile.supervisor:
|
||||
raise PermissionDenied
|
||||
|
||||
return self.exam_scores_cid_user(request, pk, user=user, supervisor=user.userprofile.supervisor.user)
|
||||
return self.exam_scores_cid_user(
|
||||
request, pk, user=user, supervisor=user.userprofile.supervisor.user
|
||||
)
|
||||
|
||||
@method_decorator(user_passes_test(lambda u: u.is_superuser))
|
||||
def exam_scores_cid_user_admin(self, request, pk, cid):
|
||||
user = CidUser.objects.get(cid=cid)
|
||||
return self.exam_scores_cid_user(request, pk, cid, user.passcode)
|
||||
|
||||
def exam_scores_cid_user(self, request, pk, cid=None, passcode="", user=None, supervisor=None):
|
||||
def exam_scores_cid_user(
|
||||
self, request, pk, cid=None, passcode="", user=None, supervisor=None
|
||||
):
|
||||
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||
|
||||
if not exam.exam_mode:
|
||||
@@ -2110,11 +2126,11 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
if supervisor is None:
|
||||
if not exam.check_cid_user(cid, passcode, request.user):
|
||||
#TODO clear this up
|
||||
# TODO clear this up
|
||||
# Should users be able to access results for exams they do not have access to (if they have results)?
|
||||
if not self.check_user_access(request.user, pk):
|
||||
# raise PermissionDenied
|
||||
#if request.user.supervisor == user.userprofile.supervisor:
|
||||
# if request.user.supervisor == user.userprofile.supervisor:
|
||||
# pass
|
||||
|
||||
# check for supervisor access
|
||||
@@ -2122,10 +2138,10 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
else:
|
||||
if user is None:
|
||||
raise Exception("user must be defined")
|
||||
view_all_results = True
|
||||
view_all_results = True
|
||||
|
||||
if user is not None:
|
||||
request.user = user
|
||||
if user is None:
|
||||
user = request.user
|
||||
|
||||
questions = (
|
||||
exam.get_questions()
|
||||
@@ -2142,7 +2158,6 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
answers_marks = []
|
||||
answers = []
|
||||
|
||||
|
||||
for q in questions:
|
||||
# Get user answer
|
||||
if cid is not None:
|
||||
@@ -2238,6 +2253,8 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
max_score = len(questions)
|
||||
|
||||
cid_user_exam = exam.cid_user_exam.filter(user_user=user).first()
|
||||
print(user)
|
||||
print(f"{cid_user_exam=}")
|
||||
|
||||
template_context = {
|
||||
"exam": exam,
|
||||
@@ -3829,8 +3846,7 @@ def supervisor_overview(request, pk):
|
||||
if not request.user.supervisor == supervisor:
|
||||
raise PermissionDenied()
|
||||
except Supervisor.RelatedObjectDoesNotExist:
|
||||
raise PermissionDenied()
|
||||
|
||||
raise PermissionDenied()
|
||||
|
||||
trainees = User.objects.filter(userprofile__supervisor=supervisor)
|
||||
|
||||
@@ -3849,7 +3865,7 @@ def supervisor_trainee(request, pk, trainee_id):
|
||||
if not request.user.supervisor == supervisor:
|
||||
raise PermissionDenied()
|
||||
except Supervisor.RelatedObjectDoesNotExist:
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied()
|
||||
|
||||
# We do this to check that the supervisor can (should) see the trainee results
|
||||
trainee = User.objects.get(userprofile__supervisor=supervisor, pk=trainee_id)
|
||||
@@ -3866,6 +3882,7 @@ def supervisor_trainee(request, pk, trainee_id):
|
||||
{"supervisor": supervisor, "trainee": trainee, "all_exams": exams},
|
||||
)
|
||||
|
||||
|
||||
def supervisor_request_account(request):
|
||||
if request.method == "POST":
|
||||
email = request.POST.get("email")
|
||||
@@ -3878,9 +3895,14 @@ def supervisor_request_account(request):
|
||||
supervisor = Supervisor.objects.get(email=email)
|
||||
except Supervisor.DoesNotExist:
|
||||
return HttpResponse(f"Invalid email address ({email})")
|
||||
|
||||
|
||||
if supervisor.user:
|
||||
return HttpResponse(format_html("User already exists. Reset your password <a href='{}'>here</a>", reverse("password_reset")))
|
||||
return HttpResponse(
|
||||
format_html(
|
||||
"User already exists. Reset your password <a href='{}'>here</a>",
|
||||
reverse("password_reset"),
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
user_account = User.objects.get(email=email)
|
||||
@@ -3891,13 +3913,44 @@ def supervisor_request_account(request):
|
||||
first, last = supervisor.name.split(" ", 1)
|
||||
except ValueError:
|
||||
first, last = supervisor.name, ""
|
||||
user_account = User.objects.create_user(email=email, username=email, password=secrets.token_hex(nbytes=16), first_name=first, last_name=last)
|
||||
user_account = User.objects.create_user(
|
||||
email=email,
|
||||
username=email,
|
||||
password=secrets.token_hex(nbytes=16),
|
||||
first_name=first,
|
||||
last_name=last,
|
||||
)
|
||||
|
||||
supervisor.user = user_account
|
||||
supervisor.save()
|
||||
|
||||
return HttpResponse(format_html("Account created, you now need to reset your password <a href='{}'>here</a>", reverse("password_reset")))
|
||||
return HttpResponse(
|
||||
format_html(
|
||||
"Account created, you now need to reset your password <a href='{}'>here</a>",
|
||||
reverse("password_reset"),
|
||||
)
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
return render(request, "generic/supervisor_request_account.html", {})
|
||||
|
||||
|
||||
def toggle_share_with_supervisor(request, pk):
|
||||
if request.htmx:
|
||||
cid_user_exam = get_object_or_404(CidUserExam, pk=pk)
|
||||
|
||||
print(request.user)
|
||||
print(cid_user_exam)
|
||||
print(cid_user_exam.user_user)
|
||||
if request.user != cid_user_exam.user_user:
|
||||
return HttpResponse("Incorrect permissions")
|
||||
|
||||
cid_user_exam.share_with_supervisor = not cid_user_exam.share_with_supervisor
|
||||
cid_user_exam.save()
|
||||
|
||||
return HttpResponse(
|
||||
f"Shared with supervisor: {cid_user_exam.share_with_supervisor}"
|
||||
)
|
||||
else:
|
||||
raise PermissionDenied()
|
||||
|
||||
Reference in New Issue
Block a user