From d1f42acff83cd3b7dad9949ada651982ba666847 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Wed, 6 May 2026 06:36:51 -0500 Subject: [PATCH] Fix grading proctored tests that require proctor authorization to do so. The `can_recordAnswers` method of the `WeBWorK::ContentGenerator::GatewayQuiz` package can not call any of the `WeBWorK::ContentGenerator::GatewayQuiz` methods because it is called directly by the `WeBWorK::ContentGenerator::LoginProctor` module without a `WeBWorK::ContentGenerator::GatewayQuiz` object. Attempting to do so will cause an exception. This is a bit annoying as the conditions of the `can_gradeUnsubmittedTest` method (including the conditions of the `can_showProblemGrader` method it calls) must be directly used by the `can_recordAnswers` method. There is no way around that though. This definitely should be considered for a hotfix. --- lib/WeBWorK/ContentGenerator/GatewayQuiz.pm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm index f97712269f..ca6a947308 100644 --- a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm +++ b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm @@ -118,6 +118,10 @@ sub can_showSolutions ($c, $user, $permissionLevel, $effectiveUser, $set, $probl # Allow for a version_last_attempt_time which is the time the set was submitted. If that is present we use that instead # of the current time to decide if answers can be recorded. This deals with the time between the submission time and # the proctor authorization. +# IMPORTANT: This method is called directly by the LoginProctor.pm package without a proper GatewayQuiz object, and so +# it can not call any of the object methods in the GatewayQuiz package or use anything that is not set for a generic +# ContentGenerator object. Also make sure that the conditions for recording an unsubmitted test are kept in sync with +# the conditions of the can_gradeUnsubmittedTest method. sub can_recordAnswers ($c, $user, $permissionLevel, $effectiveUser, $set, $problem, $tmplSet = 0, $submitAnswers = 0) { my $authz = $c->authz; @@ -130,8 +134,12 @@ sub can_recordAnswers ($c, $user, $permissionLevel, $effectiveUser, $set, $probl # allow that between the open and close dates, and so drop out of this conditional to the usual one. return 1 if $authz->hasPermissions($user->user_id, 'record_answers_when_acting_as_student') - || $c->can_gradeUnsubmittedTest($user, $permissionLevel, $effectiveUser, $set, $problem, $tmplSet, - $submitAnswers); + || (!$submitAnswers + && $authz->hasPermissions($user->user_id, 'access_instructor_tools') + && $authz->hasPermissions($user->user_id, 'problem_grader') + && !$c->{invalidSet} + && after($set->due_date + $c->ce->{gatewayGracePeriod}) + && !$set->version_last_attempt_time); return 0 if !$authz->hasPermissions($user->user_id, 'record_set_version_answers_when_acting_as_student'); }