From bd9db99078be492ce113edec4143e460566f61d4 Mon Sep 17 00:00:00 2001
From: Glenn Rice <grice1@missouriwestern.edu>
Date: Thu, 12 Dec 2024 15:31:48 -0600
Subject: [PATCH] TODO

---
 lib/WeBWorK.pm                                |  1 +
 lib/WeBWorK/Authen/Proctor.pm                 | 13 +++-
 lib/WeBWorK/ContentGenerator/GatewayQuiz.pm   | 23 +++++---
 .../ContentGenerator/GatewayQuiz.html.ep      | 59 ++++++++-----------
 4 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/lib/WeBWorK.pm b/lib/WeBWorK.pm
index 319ea19c82..95499668ca 100644
--- a/lib/WeBWorK.pm
+++ b/lib/WeBWorK.pm
@@ -217,6 +217,7 @@ async sub dispatch ($c) {
 				# current server time during a gateway quiz, and that definitely should not revoke proctor
 				# authorization.
 				delete $c->authen->session->{proctor_authorization_granted};
+				delete $c->authen->session->{acting_proctor};
 			}
 			return 1;
 		} else {
diff --git a/lib/WeBWorK/Authen/Proctor.pm b/lib/WeBWorK/Authen/Proctor.pm
index 2cd91db890..272098df2b 100644
--- a/lib/WeBWorK/Authen/Proctor.pm
+++ b/lib/WeBWorK/Authen/Proctor.pm
@@ -96,10 +96,17 @@ sub verify_normal_user {
 	# is 'No', then the verify method will have returned 1, and this never happens.  For an ongoing login session, only
 	# a key with versioned set information is accepted, and that version must match the requested set version.  The set
 	# id will not have a version when opening a new version. For that new proctor credentials are required.
-	if ($self->{login_type} eq 'proctor_login'
-		&& $c->stash('setID') =~ /,v\d+$/
+	if (
+		$self->{login_type} eq 'proctor_login'
 		&& $c->authen->session('proctor_authorization_granted')
-		&& $c->authen->session('proctor_authorization_granted') eq $c->stash('setID'))
+		&& (
+			(
+				$c->stash('setID') =~ /,v\d+$/
+				&& $c->authen->session('proctor_authorization_granted') eq $c->stash('setID')
+			)
+			|| $c->authen->session('acting_proctor')
+		)
+		)
 	{
 		return 1;
 	} else {
diff --git a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm
index 6a007a388b..7f19bdd936 100644
--- a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm
+++ b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm
@@ -610,7 +610,7 @@ async sub pre_header_initialize ($c) {
 				)
 			{
 
-				$c->{invalidSet} = $c->maketext(
+				$c->stash->{actingConfirmationMessage} = $c->maketext(
 					'You are acting as user [_1].  If you continue, you will create a new version of '
 						. 'this test for that user, which will count against their allowed maximum '
 						. 'number of versions for the current time interval.  In general, this is not '
@@ -618,8 +618,8 @@ async sub pre_header_initialize ($c) {
 						. 'the "Create New Test Version" button below.  Alternatively, click "Cancel".',
 					$effectiveUserID
 				);
-				$c->{invalidVersionCreation}  = 1;
-				$c->{confirmSubmitForStudent} = 1;
+				++$setVersionNumber;
+				$c->stash->{actingConfirmation} = 1;
 
 			} elsif ($effectiveUserID ne $userID) {
 				$c->{invalidSet} = $c->maketext(
@@ -627,7 +627,6 @@ async sub pre_header_initialize ($c) {
 						. 'when acting as another user.',
 					$effectiveUserID
 				);
-				$c->{invalidVersionCreation} = 1;
 
 			} elsif (($maxAttemptsPerVersion == 0 || $currentNumAttempts < $maxAttemptsPerVersion)
 				&& $c->submitTime < $set->due_date() + $ce->{gatewayGracePeriod})
@@ -665,7 +664,7 @@ async sub pre_header_initialize ($c) {
 					# student which is dangerous for open test versions. Give a warning unless the user
 					# has already confirmed they understand the risk.
 					if ($effectiveUserID ne $userID && !$c->param('submit_for_student_ok')) {
-						$c->{invalidSet} = $c->maketext(
+						$c->stash->{actingConfirmationMessage} = $c->maketext(
 							'You are trying to view an open test version for [_1] and have the permission to submit '
 								. 'answers for that user.  This is dangerous, as your answers can overwrite the '
 								. q/student's answers as you move between test pages, preview, or check answers.  /
@@ -675,7 +674,7 @@ async sub pre_header_initialize ($c) {
 								. 'before viewing open test versions.',
 							$effectiveUserID
 						);
-						$c->{confirmSubmitForStudent} = 1;
+						$c->stash->{actingConfirmation} = 2;
 					}
 				}
 			}
@@ -694,6 +693,14 @@ async sub pre_header_initialize ($c) {
 		else                   { delete $c->authen->session->{proctor_authorization_granted}; }
 	}
 
+	if ($c->stash->{actingConfirmation}) {
+		$c->authen->session(acting_proctor => 1)
+			if defined $c->{assignment_type} && $c->{assignment_type} eq 'proctored_gateway';
+		return;
+	}
+
+	delete $c->authen->session->{acting_proctor};
+
 	# If the set or problem is invalid, then delete any proctor session keys and return.
 	if ($c->{invalidSet}) {
 		if (defined $c->{assignment_type} && $c->{assignment_type} eq 'proctored_gateway') {
@@ -1368,7 +1375,7 @@ sub path ($c, $args) {
 		$args,
 		'WeBWorK'   => $navigation_allowed ? $c->url_for('root')     : '',
 		$courseName => $navigation_allowed ? $c->url_for('set_list') : '',
-		$setID eq 'Undefined_Set' || $c->{invalidSet}
+		$setID eq 'Undefined_Set' || $c->{invalidSet} || $c->stash->{actingConfirmation}
 		? ($setID => '')
 		: (
 			$c->{set}->set_id           => $c->url_for('problem_list', setID => $c->{set}->set_id),
@@ -1382,7 +1389,7 @@ sub nav ($c, $args) {
 	my $userID          = $c->param('user');
 	my $effectiveUserID = $c->param('effectiveUser');
 
-	return '' if $c->{invalidSet};
+	return '' if $c->{invalidSet} || $c->stash->{actingConfirmation};
 
 	# Set up and display a student navigation for those that have permission to act as a student.
 	if ($c->authz->hasPermissions($userID, 'become_student') && $effectiveUserID ne $userID) {
diff --git a/templates/ContentGenerator/GatewayQuiz.html.ep b/templates/ContentGenerator/GatewayQuiz.html.ep
index fcaaaf38f2..03a7836f1a 100644
--- a/templates/ContentGenerator/GatewayQuiz.html.ep
+++ b/templates/ContentGenerator/GatewayQuiz.html.ep
@@ -65,42 +65,35 @@
 % my $userID          = param('user');
 % my $effectiveUserID = param('effectiveUser');
 %
-% # If the set or problem is invalid, then show that information and exit.
+% # If the set is invalid, then show that information and exit.
 % if ($c->{invalidSet}) {
 	<div class="alert alert-danger mb-2">
-		% if (!$c->{confirmSubmitForStudent} || $c->{invalidVersionCreation}) {
-			<div class="mb-2">
-				% if ($c->{invalidVersionCreation}) {
-					<%= maketext(
-						'The selected test ([_1]) is not a valid test for [_2] (acted as by [_3]).',
-						$setID, $effectiveUserID, $userID
-					) =%>
-				% } else {
-					<%= maketext(
-						'The selected test ([_1]) is not a valid test for [_2].',
-						$setID, $effectiveUserID
-					) =%>
-				% }
-			</div>
-		% }
+		<div class="mb-2">
+			<%= maketext('The selected test ([_1]) is not a valid test for [_2].', $setID, $effectiveUserID) =%>
+		</div>
 		<div><%= $c->{invalidSet} %></div>
-		% if ($c->{confirmSubmitForStudent}) {
-			<div class="mt-3">
-				<%= link_to $c->{invalidVersionCreation}
-					? maketext('Create New Test Version') : maketext('View Test Version') => $c->systemLink(
-						url_for,
-						params => { effectiveUser => $effectiveUserID, user => $userID, submit_for_student_ok => 1 }
-					),
-					class => 'btn btn-primary'
-				=%>
-				<%= link_to maketext('Cancel') => $c->systemLink(
-						url_for('problem_list', setID => $setID =~ s/,v\d+$//r),
-						params => { effectiveUser => $effectiveUserID, user => $userID }
-					),
-					class => 'btn btn-primary'
-				=%>
-			</div>
-		% }
+	</div>
+	% last;
+% }
+%
+% if (stash->{actingConfirmation}) {
+	<div class="alert alert-danger mb-2">
+		<div><%= stash->{actingConfirmationMessage} %></div>
+		<div class="mt-3">
+			<%= link_to stash->{actingConfirmation} == 1
+				? maketext('Create New Test Version') : maketext('View Test Version') => $c->systemLink(
+					url_for,
+					params => { effectiveUser => $effectiveUserID, user => $userID, submit_for_student_ok => 1 }
+				),
+				class => 'btn btn-primary'
+			=%>
+			<%= link_to maketext('Cancel') => $c->systemLink(
+					url_for('problem_list', setID => $setID =~ s/,v\d+$//r),
+					params => { effectiveUser => $effectiveUserID, user => $userID }
+				),
+				class => 'btn btn-primary'
+			=%>
+		</div>
 	</div>
 	%
 	% last;