diff --git a/conf/defaults.config b/conf/defaults.config index eb631e9790..78f044e42e 100644 --- a/conf/defaults.config +++ b/conf/defaults.config @@ -751,6 +751,7 @@ $authen{admin_module} = ['WeBWorK::Authen::Basic_TheLastOption']; view_proctored_tests => "student", view_hidden_work => "ta", + view_unopened_set_info => "guest", view_multiple_sets => "ta", view_unopened_sets => "ta", view_hidden_sets => "ta", diff --git a/lib/WeBWorK/Authz.pm b/lib/WeBWorK/Authz.pm index a238f3fb67..628854ed7a 100644 --- a/lib/WeBWorK/Authz.pm +++ b/lib/WeBWorK/Authz.pm @@ -415,25 +415,27 @@ sub checkSet { $self->{merged_set} = $set; # Now we know that the set is assigned to the appropriate user. - # Check to see if the user is trying to access a set that is not open. - if ( - before($set->open_date) - && !$self->hasPermissions($userName, "view_unopened_sets") - && !( - defined $set->assignment_type - && $set->assignment_type =~ /gateway/ - && $node_name eq 'problem_list' - && $db->countSetVersions($effectiveUserName, $set->set_id) - ) - ) - { - return $c->maketext("Requested set '[_1]' is not yet open.", $setName); - } - # Check to make sure that the set is visible, and that the user is allowed to view hidden sets. + # If the user can view unopened set information, they will be given warning messages vs error message. my $visible = $set && $set->visible ne '0' && $set->visible ne '1' ? 1 : $set->visible; if (!$visible && !$self->hasPermissions($userName, "view_hidden_sets")) { - return $c->maketext("Requested set '[_1]' is not available yet.", $setName); + $c->{viewSetCheck} = 'hidden' + if $node_name eq 'problem_list' && $self->hasPermissions($userName, 'view_unopened_set_info'); + return $c->maketext("Requested set '[_1]' is not available.", $setName); + } + + # Check to see if the user is trying to access a set that is not open. + if (before($set->open_date) && !$self->hasPermissions($userName, 'view_unopened_sets')) { + # Show problem set info if user has permissions, or there exists any test versions. + $c->{viewSetCheck} = 'unopened' + if $node_name eq 'problem_list' + && ( + $self->hasPermissions($userName, 'view_unopened_set_info') + || (defined $set->assignment_type + && $set->assignment_type =~ /gateway/ + && $db->countSetVersions($effectiveUserName, $set->set_id)) + ); + return $c->maketext("Requested set '[_1]' is not yet open.", $setName); } # Check to see if conditional release conditions have been met. @@ -474,7 +476,11 @@ sub checkSet { # Check for ip restrictions. my $badIP = $self->invalidIPAddress($set); - return $badIP if $badIP; + if ($badIP) { + # Allow viewing of set info of restricted sets. + $c->{viewSetCheck} = 'restricted' if $node_name eq 'problem_list'; + return $badIP; + } # If LTI grade passback is enabled and set to 'homework' mode then we need to make sure that there is a sourcedid # for this set before students access it. @@ -530,7 +536,9 @@ sub invalidIPAddress { # if there are no addresses in the locations, return an error that # says this return $c->maketext( - "Client ip address [_1] is not allowed to work this assignment, because the assignment has ip address restrictions and there are no allowed locations associated with the restriction. Contact your professor to have this problem resolved.", + 'Client ip address [_1] is not allowed to work this assignment, because the assignment has ip address ' + . 'restrictions and there are no allowed locations associated with the restriction. Contact your ' + . 'professor to have this problem resolved.', $clientIP->ip() ) if (!@restrictAddresses); @@ -552,17 +560,13 @@ sub invalidIPAddress { # this is slightly complicated by having to check relax_restrict_ip my $badIP = ''; if ($restrictType eq 'RestrictTo' && !$inRestrict) { - $badIP = - "Client ip address " - . $clientIP->ip() - . " is not in the list of addresses from " - . "which this assignment may be worked."; + $badIP = $c->maketext( + 'Client ip address [_1] is not in the list of addresses from which this assignment may be worked.', + $clientIP->ip()); } elsif ($restrictType eq 'DenyFrom' && $inRestrict) { - $badIP = - "Client ip address " - . $clientIP->ip() - . " is in the list of addresses from " - . "which this assignment may not be worked."; + $badIP = $c->maketext( + 'Client ip address [_1] is in the list of addresses from which this assignment may not be worked.', + $clientIP->ip()); } else { return 0; } diff --git a/lib/WeBWorK/ConfigValues.pm b/lib/WeBWorK/ConfigValues.pm index 27ccd65cbb..f4a24ec40f 100644 --- a/lib/WeBWorK/ConfigValues.pm +++ b/lib/WeBWorK/ConfigValues.pm @@ -590,6 +590,15 @@ sub getConfigValues ($ce) { doc2 => x('These users and higher get the "Show Past Answers" button on the problem page.'), type => 'permission' }, + { + var => 'permissionLevels{view_unopened_set_info}', + doc => x('Allowed to view set information for sets which are not open yet'), + doc2 => x( + 'This includes being able to see the set description attached to the links on the assignments ' + . 'page, and seeing the set header on the set information page.' + ), + type => 'permission' + }, { var => 'permissionLevels{view_unopened_sets}', doc => x('Allowed to view problems in sets which are not open yet'), diff --git a/lib/WeBWorK/ContentGenerator/ProblemSet.pm b/lib/WeBWorK/ContentGenerator/ProblemSet.pm index ba77939ec5..97f69c5111 100644 --- a/lib/WeBWorK/ContentGenerator/ProblemSet.pm +++ b/lib/WeBWorK/ContentGenerator/ProblemSet.pm @@ -23,13 +23,11 @@ async sub initialize ($c) { my $ce = $c->ce; my $authz = $c->authz; - # $c->{invalidSet} is set in checkSet which is called by ContentGenerator.pm - return - if $c->{invalidSet} - && ($c->{invalidSet} !~ /^Client ip address .* is not in the list of addresses/ - || $authz->{merged_set}->assignment_type !~ /gateway/); + # $c->{invalidSet} is set in checkSet which is called by ContentGenerator.pm. + # If $c->{viewSetCheck} is also set, we want to view some information unless the set is hidden. + return if $c->{invalidSet} && (!$c->{viewSetCheck} || $c->{viewSetCheck} eq 'hidden'); - # This will all be valid if checkSet did not set $c->{invalidSet}. + # This will all be valid if the above check passes. my $userID = $c->param('user'); my $eUserID = $c->param('effectiveUser'); @@ -161,8 +159,7 @@ sub siblings ($c) { return $c->include('ContentGenerator/ProblemSet/siblings', setIDs => \@setIDs); } -sub info { - my ($c) = @_; +sub info ($c) { return '' unless $c->{pg}; return $c->include('ContentGenerator/ProblemSet/info'); } diff --git a/lib/WeBWorK/ContentGenerator/ProblemSets.pm b/lib/WeBWorK/ContentGenerator/ProblemSets.pm index 3eeb4fb4c3..57be273d63 100644 --- a/lib/WeBWorK/ContentGenerator/ProblemSets.pm +++ b/lib/WeBWorK/ContentGenerator/ProblemSets.pm @@ -118,7 +118,7 @@ sub getSetStatus ($c, $set) { my $db = $c->db; my $authz = $c->authz; my $effectiveUser = $c->param('effectiveUser') || $c->param('user'); - my $canViewUnopened = $authz->hasPermissions($c->param('user'), 'view_unopened_sets'); + my $canViewUnopened = $authz->hasPermissions($c->param('user'), 'view_unopened_set_info'); my @restricted = $ce->{options}{enableConditionalRelease} ? is_restricted($db, $set, $effectiveUser) : (); @@ -134,6 +134,7 @@ sub getSetStatus ($c, $set) { $c->maketext('Will open on [_1].', $c->formatDateTime($set->open_date, $ce->{studentDateDisplayFormat})); push(@$other_messages, $c->restricted_progression_msg(1, $set->restricted_status * 100, @restricted)) if @restricted; + # Test versions are only available on the ProblemSet page, so allow access if there are any test versions. $link_is_active = 0 unless $canViewUnopened || ($set->assignment_type =~ /gateway/ && $db->countSetVersions($effectiveUser, $set->set_id)); diff --git a/templates/ContentGenerator/ProblemSet.html.ep b/templates/ContentGenerator/ProblemSet.html.ep index 62eb24f808..2631b0f41d 100644 --- a/templates/ContentGenerator/ProblemSet.html.ep +++ b/templates/ContentGenerator/ProblemSet.html.ep @@ -1,21 +1,27 @@ % use WeBWorK::Utils::DateTime qw(before between); % -% if ( - % $c->{invalidSet} - % && ($c->{invalidSet} !~ /^Client ip address .* is not in the list of addresses/ - % || $authz->{merged_set}->assignment_type !~ /gateway/) - % ) -% { -
- <%= maketext( - 'The selected problem set ([_1]) is not a valid set for [_2].', - stash('setID'), param('effectiveUser') - ) =%> -
-<%= $c->{invalidSet} %>
-<%= $c->{invalidSet} %>
++ <%= maketext( + 'The selected problem set ([_1]) is not a valid set for [_2].', + stash('setID'), param('effectiveUser') + ) =%> +
+<%= $c->{invalidSet} %>
+<%= maketext('No versions of this test have been taken.') %>