Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conf/defaults.config
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
60 changes: 32 additions & 28 deletions lib/WeBWorK/Authz.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);

Expand All @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions lib/WeBWorK/ConfigValues.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down
13 changes: 5 additions & 8 deletions lib/WeBWorK/ContentGenerator/ProblemSet.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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');
}
Expand Down
3 changes: 2 additions & 1 deletion lib/WeBWorK/ContentGenerator/ProblemSets.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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) : ();

Expand All @@ -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));
Expand Down
50 changes: 33 additions & 17 deletions templates/ContentGenerator/ProblemSet.html.ep
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
% 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/)
% )
% {
<div class="alert alert-danger">
<p class="mb-3">
<%= maketext(
'The selected problem set ([_1]) is not a valid set for [_2].',
stash('setID'), param('effectiveUser')
) =%>
</p>
<p class="mb-0"><%= $c->{invalidSet} %></p>
</div>
% last;
% if ($c->{invalidSet}) {
% # If $c->{viewSetCheck} is set, show some set information.
% if ($c->{viewSetCheck}) {
% # Do nothing unless the set is hidden, then show a warning message instead of an error.
% if ($c->{viewSetCheck} eq 'hidden') {
<div class="alert alert-warning">
<p class="mb-0"><%= $c->{invalidSet} %></p>
</div>
% last;
% }
% } else {
<div class="alert alert-danger">
<p class="mb-3">
<%= maketext(
'The selected problem set ([_1]) is not a valid set for [_2].',
stash('setID'), param('effectiveUser')
) =%>
</p>
<p class="mb-0"><%= $c->{invalidSet} %></p>
</div>
% last;
% }
% }
%
% my $set = $c->{set};
%
% # Stats message displays the current status of the set and states the next important date.
<%= include 'ContentGenerator/Base/set_status', set => $set =%>
%
% # Shows warning about restricted IP settings.
% if ($c->{viewSetCheck} && $c->{viewSetCheck} eq 'restricted') {
<div class="alert alert-warning"><%= $c->{invalidSet} %></div>
% }
%
<%= include 'ContentGenerator/ProblemSet/auxiliary_tools' =%>
%
<%= $set->assignment_type =~ /gateway/ ? $c->gateway_body : $c->problem_list =%>
% # Always show test versions, but only show problem list if the set has no restrictions.
% if ($set->assignment_type =~ /gateway/) {
<%= $c->gateway_body =%>
% } elsif (!$c->{viewSetCheck}) {
<%= $c->problem_list =%>
% }
5 changes: 5 additions & 0 deletions templates/ContentGenerator/ProblemSet/auxiliary_tools.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
showSolutions => '',
) =%>
</div>
% # If viewing a restricted set, don't show anymore buttons.
% if ($c->{viewSetCheck}) {
</div>
% last;
% }
% if ($ce->{achievementsEnabled} && $ce->{achievementItemsEnabled}) {
% my $achievementItems = $c->{achievementItems};
% if ($achievementItems && @$achievementItems) {
Expand Down
9 changes: 3 additions & 6 deletions templates/ContentGenerator/ProblemSet/version_list.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
%
% my $routeName = $set->assignment_type =~ /proctored/ ? 'proctored_gateway_quiz' : 'gateway_quiz';
%
% if ($c->{invalidSet}) {
% # If this is an invalidSet it is because the IP address is not allowed to access the set.
% # Display that message here. Note that the set is valid so the set versions can still be displayed,
% # but the "Start New Test" or "Continue Test" buttons should not be.
<div class="alert alert-warning"><%= $c->{invalidSet} %></div>
% if ($c->{viewSetCheck}) {
% # If we are viewing a restricted set, then only show existing set versions and no other information.
% } elsif ($continueVersion) {
% # Display information about the current test and a continue open test button.
% if ($timeLimit > 0) {
Expand Down Expand Up @@ -249,6 +246,6 @@
% } else {
<%= $version_list->() =%>
% }
% } else {
% } elsif (!$c->{viewSetCheck}) {
<div><p><%= maketext('No versions of this test have been taken.') %></p></div>
% }
12 changes: 8 additions & 4 deletions templates/layouts/system.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,15 @@
<%= content =%>
</div>
% if ($c->can('info')) {
<div id="info-panel-right" class="col-md-4 mb-md-0 mb-2 order-md-last order-first">
<div class="info-box bg-light">
<%= $c->info =%>
% # Only show info div if the content is not empty.
% my $info = $c->info;
% if ($info !~ /^\s*$/) {
<div id="info-panel-right" class="col-md-4 mb-md-0 mb-2 order-md-last order-first">
<div class="info-box bg-light">
<%= $info =%>
</div>
</div>
</div>
% }
% }
</div>
%
Expand Down