Parent Directory
|
Revision Log
Revision 5779 - (view) (download) (as text)
| 1 : | sh002i | 455 | ################################################################################ |
| 2 : | sh002i | 1663 | # WeBWorK Online Homework Delivery System |
| 3 : | sh002i | 5319 | # Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 : | glarose | 5779 | # $CVSHeader: webwork2/lib/WeBWorK/Authz.pm,v 1.36 2007/08/13 22:59:54 sh002i Exp $ |
| 5 : | sh002i | 1663 | # |
| 6 : | # This program is free software; you can redistribute it and/or modify it under | ||
| 7 : | # the terms of either: (a) the GNU General Public License as published by the | ||
| 8 : | # Free Software Foundation; either version 2, or (at your option) any later | ||
| 9 : | # version, or (b) the "Artistic License" which comes with this package. | ||
| 10 : | # | ||
| 11 : | # This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 : | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 13 : | # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the | ||
| 14 : | # Artistic License for more details. | ||
| 15 : | sh002i | 455 | ################################################################################ |
| 16 : | |||
| 17 : | malsyned | 390 | package WeBWorK::Authz; |
| 18 : | |||
| 19 : | sh002i | 455 | =head1 NAME |
| 20 : | |||
| 21 : | WeBWorK::Authz - check user permissions. | ||
| 22 : | |||
| 23 : | sh002i | 3058 | =head1 SYNOPSIS |
| 24 : | |||
| 25 : | # create new authorizer -- $r is a WeBWorK::Request object. | ||
| 26 : | my $authz = new WeBWorK::Authz($r); | ||
| 27 : | |||
| 28 : | # tell authorizer to cache permission level of user spammy. | ||
| 29 : | $authz->setCachedUser("spammy"); | ||
| 30 : | |||
| 31 : | # this call will use the cached data. | ||
| 32 : | if ($authz->hasPermissions("spammy", "eat_breakfast")) { | ||
| 33 : | eat_breakfast(); | ||
| 34 : | } | ||
| 35 : | |||
| 36 : | # this call will not use the cached data, and will cause a database lookup. | ||
| 37 : | if ($authz->hasPermissions("hammy", "go_to_bed")) { | ||
| 38 : | go_to_bed(); | ||
| 39 : | } | ||
| 40 : | |||
| 41 : | =head1 DESCRIPTION | ||
| 42 : | |||
| 43 : | WeBWorK::Authen determines if a user is authorized to perform a specific | ||
| 44 : | activity, based on the user's PermissionLevel record in the WeBWorK database and | ||
| 45 : | the contents of the %permissionLevels hash in the course environment. | ||
| 46 : | |||
| 47 : | =head2 Format of the %permissionLevels hash | ||
| 48 : | |||
| 49 : | %permissionLevels maps text strings describing activities to numeric permission | ||
| 50 : | levels. The definitive list of activities is contained in the default version of | ||
| 51 : | %permissionLevels, in the file F<conf/global.conf.dist>. | ||
| 52 : | |||
| 53 : | A user is able to engage in an activity if their permission level is greater | ||
| 54 : | than or equal to the level associated with the activity. If the level associated | ||
| 55 : | with an activity is undefiend, then no user is permitted to perform the | ||
| 56 : | activity, regardless of their permission level. | ||
| 57 : | |||
| 58 : | sh002i | 455 | =cut |
| 59 : | |||
| 60 : | malsyned | 441 | use strict; |
| 61 : | use warnings; | ||
| 62 : | sh002i | 3672 | use Carp qw/croak/; |
| 63 : | glarose | 4907 | # FIXME SET: set-level auth add |
| 64 : | use WeBWorK::Utils qw(before after between); | ||
| 65 : | use WeBWorK::Authen::Proctor; | ||
| 66 : | use Net::IP; | ||
| 67 : | malsyned | 390 | |
| 68 : | sh002i | 3058 | ################################################################################ |
| 69 : | gage | 3053 | |
| 70 : | sh002i | 3058 | =head1 CONSTRUCTOR |
| 71 : | |||
| 72 : | =over | ||
| 73 : | |||
| 74 : | =item WeBWorK::Authz->new($r) | ||
| 75 : | |||
| 76 : | Creates a new authorizer instance. $r is a WeBWorK::Request object. It must | ||
| 77 : | already have its C<ce> and C<db> fields set. | ||
| 78 : | |||
| 79 : | =cut | ||
| 80 : | |||
| 81 : | sh002i | 1885 | sub new { |
| 82 : | sh002i | 3058 | my ($invocant, $r) = @_; |
| 83 : | malsyned | 390 | my $class = ref($invocant) || $invocant; |
| 84 : | sh002i | 1885 | my $self = { |
| 85 : | r => $r, | ||
| 86 : | }; | ||
| 87 : | gage | 3053 | |
| 88 : | malsyned | 390 | bless $self, $class; |
| 89 : | return $self; | ||
| 90 : | } | ||
| 91 : | |||
| 92 : | sh002i | 3058 | =back |
| 93 : | gage | 3053 | |
| 94 : | sh002i | 3058 | =cut |
| 95 : | |||
| 96 : | ################################################################################ | ||
| 97 : | |||
| 98 : | =head1 METHODS | ||
| 99 : | |||
| 100 : | =over | ||
| 101 : | |||
| 102 : | =item setCachedUser($userID) | ||
| 103 : | |||
| 104 : | Caches the PermissionLevel of the user $userID in an existing authorizer. If a | ||
| 105 : | user's PermissionLevel is cached, it will be used whenever hasPermissions() is | ||
| 106 : | called on the same user. Only one user can be cached at a time. This is used by | ||
| 107 : | WeBWorK to cache the "real" user. | ||
| 108 : | |||
| 109 : | =cut | ||
| 110 : | |||
| 111 : | sub setCachedUser { | ||
| 112 : | my ($self, $userID) = @_; | ||
| 113 : | my $r = $self->{r}; | ||
| 114 : | my $db = $r->db; | ||
| 115 : | |||
| 116 : | delete $self->{userID}; | ||
| 117 : | delete $self->{PermissionLevel}; | ||
| 118 : | |||
| 119 : | if (defined $userID) { | ||
| 120 : | $self->{userID} = $userID; | ||
| 121 : | my $PermissionLevel = $db->getPermissionLevel($userID); # checked | ||
| 122 : | if (defined $PermissionLevel) { | ||
| 123 : | # store permission level record in database to avoid later database calls | ||
| 124 : | $self->{PermissionLevel} = $PermissionLevel; | ||
| 125 : | } | ||
| 126 : | } else { | ||
| 127 : | sh002i | 4002 | warn "setCachedUser() called with userID undefined."; |
| 128 : | sh002i | 3058 | } |
| 129 : | } | ||
| 130 : | |||
| 131 : | =item hasPermissions($userID, $activity) | ||
| 132 : | |||
| 133 : | Checks the %permissionLevels hash in the course environment to determine if the | ||
| 134 : | user $userID has permission to engage in the activity $activity. If the user's | ||
| 135 : | permission level is greater than or equal to the level associated with $activty, | ||
| 136 : | a true value is returned. Otherwise, a false value is returned. | ||
| 137 : | |||
| 138 : | If $userID has been cached using the setCachedUser() call, the cached data is | ||
| 139 : | used. Otherwise, the user's PermissionLevel is looked up in the WeBWorK | ||
| 140 : | database. | ||
| 141 : | |||
| 142 : | If the user does not have a PermissionLevel record, the permission level record | ||
| 143 : | is empty, or the activity does not appear in %permissionLevels, hasPermissions() | ||
| 144 : | assumes that the user does not have permission. | ||
| 145 : | |||
| 146 : | =cut | ||
| 147 : | |||
| 148 : | malsyned | 676 | # This currently only uses two of it's arguments, but it accepts any number, in |
| 149 : | # case in the future calculating certain permissions requires more information. | ||
| 150 : | malsyned | 390 | sub hasPermissions { |
| 151 : | sh002i | 3599 | if (@_ != 3) { |
| 152 : | shift @_; # get rid of self | ||
| 153 : | my $nargs = @_; | ||
| 154 : | sh002i | 3672 | croak "hasPermissions called with $nargs arguments instead of the expected 2: '@_'" |
| 155 : | sh002i | 3599 | } |
| 156 : | sh002i | 3597 | |
| 157 : | sh002i | 3058 | my ($self, $userID, $activity) = @_; |
| 158 : | my $r = $self->{r}; | ||
| 159 : | my $ce = $r->ce; | ||
| 160 : | my $db = $r->db; | ||
| 161 : | |||
| 162 : | sh002i | 3834 | # this may need to be changed if we get other permission level data sources |
| 163 : | return 0 unless defined $db; | ||
| 164 : | |||
| 165 : | # this may need to be changed if we want to control what unauthenticated users | ||
| 166 : | # can do with the permissions system | ||
| 167 : | return 0 unless defined $userID and $userID ne ""; | ||
| 168 : | |||
| 169 : | sh002i | 3058 | my $PermissionLevel; |
| 170 : | |||
| 171 : | my $cachedUserID = $self->{userID}; | ||
| 172 : | if (defined $cachedUserID and $cachedUserID ne "" and $cachedUserID eq $userID) { | ||
| 173 : | # this is the same user -- we can skip the database call | ||
| 174 : | $PermissionLevel = $self->{PermissionLevel}; | ||
| 175 : | } else { | ||
| 176 : | # a different user, or no user was defined before | ||
| 177 : | sh002i | 3672 | #my $prettyCachedUserID = defined $cachedUserID ? "'$cachedUserID'" : "undefined"; |
| 178 : | sh002i | 3058 | #warn "hasPermissions called with user '$userID', but cached user is $prettyCachedUserID. Accessing database.\n"; |
| 179 : | $PermissionLevel = $db->getPermissionLevel($userID); # checked | ||
| 180 : | } | ||
| 181 : | |||
| 182 : | my $permission_level; | ||
| 183 : | |||
| 184 : | if (defined $PermissionLevel) { | ||
| 185 : | $permission_level = $PermissionLevel->permission; | ||
| 186 : | } else { | ||
| 187 : | # uh, oh. this user has no permission level record! | ||
| 188 : | sh002i | 4002 | warn "User '$userID' has no PermissionLevel record -- assuming no permission."; |
| 189 : | sh002i | 3058 | return 0; |
| 190 : | } | ||
| 191 : | |||
| 192 : | unless (defined $permission_level and $permission_level ne "") { | ||
| 193 : | sh002i | 4002 | warn "User '$userID' has empty permission level -- assuming no permission."; |
| 194 : | sh002i | 3058 | return 0; |
| 195 : | } | ||
| 196 : | |||
| 197 : | sh002i | 3672 | my $userRoles = $ce->{userRoles}; |
| 198 : | sh002i | 3058 | my $permissionLevels = $ce->{permissionLevels}; |
| 199 : | sh002i | 3672 | |
| 200 : | sh002i | 2505 | if (exists $permissionLevels->{$activity}) { |
| 201 : | sh002i | 3672 | my $activity_role = $permissionLevels->{$activity}; |
| 202 : | if (defined $activity_role) { | ||
| 203 : | if (exists $userRoles->{$activity_role}) { | ||
| 204 : | my $role_permlevel = $userRoles->{$activity_role}; | ||
| 205 : | if (defined $role_permlevel) { | ||
| 206 : | return $permission_level >= $role_permlevel; | ||
| 207 : | } else { | ||
| 208 : | sh002i | 4002 | warn "Role '$activity_role' has undefined permisison level -- assuming no permission."; |
| 209 : | sh002i | 3672 | return 0; |
| 210 : | } | ||
| 211 : | } else { | ||
| 212 : | sh002i | 4002 | warn "Role '$activity_role' for activity '$activity' not found in \%userRoles -- assuming no permission."; |
| 213 : | sh002i | 3672 | return 0; |
| 214 : | } | ||
| 215 : | sh002i | 2505 | } else { |
| 216 : | sh002i | 3672 | return 0; # undefiend $activity_role, no one has permission to perform $activity |
| 217 : | sh002i | 2505 | } |
| 218 : | sh002i | 817 | } else { |
| 219 : | sh002i | 4002 | warn "Activity '$activity' not found in \%permissionLevels -- assuming no permission."; |
| 220 : | sh002i | 3058 | return 0; |
| 221 : | sh002i | 817 | } |
| 222 : | malsyned | 390 | } |
| 223 : | |||
| 224 : | glarose | 4907 | #### set-level authorization routines |
| 225 : | |||
| 226 : | sub checkSet { | ||
| 227 : | my $self = shift; | ||
| 228 : | my $r = $self->{r}; | ||
| 229 : | my $ce = $r->ce; | ||
| 230 : | my $db = $r->db; | ||
| 231 : | my $urlPath = $r->urlpath; | ||
| 232 : | |||
| 233 : | my $node_name = $urlPath->type; | ||
| 234 : | |||
| 235 : | # first check to see if we have to worried about set-level access | ||
| 236 : | # restrictions | ||
| 237 : | return 0 unless (grep {/^$node_name$/} | ||
| 238 : | (qw(problem_list problem_detail gateway_quiz | ||
| 239 : | glarose | 4909 | proctored_gateway_quiz))); |
| 240 : | glarose | 4907 | |
| 241 : | # to check set restrictions we need a set and a user | ||
| 242 : | my $setName = $urlPath->arg("setID"); | ||
| 243 : | my $userName = $r->param("user"); | ||
| 244 : | my $effectiveUserName = $r->param("effectiveUser"); | ||
| 245 : | |||
| 246 : | glarose | 4909 | # if there is no input userName, then the content generator will |
| 247 : | # be forcing a login, so just bail | ||
| 248 : | return 0 if ( ! $userName || ! $effectiveUserName ); | ||
| 249 : | |||
| 250 : | glarose | 4918 | # do we have a cached set that we can use? |
| 251 : | my $set = $self->{merged_set}; | ||
| 252 : | |||
| 253 : | glarose | 4907 | if ( $setName =~ /,v(\d+)$/ ) { |
| 254 : | my $verNum = $1; | ||
| 255 : | $setName =~ s/,v\d+$//; | ||
| 256 : | glarose | 4918 | |
| 257 : | if ( $set && $set->set_id eq $setName && | ||
| 258 : | $set->user_id eq $effectiveUserName && | ||
| 259 : | $set->version_id eq $verNum ) { | ||
| 260 : | # then we can just use this set and skip the rest | ||
| 261 : | |||
| 262 : | glarose | 5779 | } elsif ( $setName eq 'Undefined_Set' and |
| 263 : | $self->hasPermissions($userName, "access_instructor_tools") ) { | ||
| 264 : | # this is the case of previewing a problem | ||
| 265 : | # from a 'try it' link | ||
| 266 : | return 0; | ||
| 267 : | glarose | 4907 | } else { |
| 268 : | glarose | 4918 | if ($db->existsSetVersion($effectiveUserName,$setName,$verNum)) { |
| 269 : | $set = $db->getMergedSetVersion($effectiveUserName,$setName,$verNum); | ||
| 270 : | } else { | ||
| 271 : | return "Requested version ($verNum) of set " . | ||
| 272 : | "'$setName' is not assigned to user " . | ||
| 273 : | "$effectiveUserName."; | ||
| 274 : | } | ||
| 275 : | glarose | 4907 | } |
| 276 : | if ( ! $set ) { | ||
| 277 : | return "Requested set '$setName' could not be found " . | ||
| 278 : | glarose | 4909 | "in the database for user $effectiveUserName."; |
| 279 : | glarose | 4907 | } |
| 280 : | } else { | ||
| 281 : | glarose | 4918 | |
| 282 : | if ( $set && $set->set_id eq $setName && | ||
| 283 : | $set->user_id eq $effectiveUserName ) { | ||
| 284 : | # then we can just use this set, and skip the rest | ||
| 285 : | |||
| 286 : | glarose | 4907 | } else { |
| 287 : | glarose | 4918 | if ( $db->existsUserSet($effectiveUserName,$setName) ) { |
| 288 : | $set = $db->getMergedSet($effectiveUserName,$setName); | ||
| 289 : | jj | 5263 | } elsif ( $setName eq 'Undefined_Set' and |
| 290 : | $self->hasPermissions($userName, "access_instructor_tools") ) { | ||
| 291 : | glarose | 5248 | # this is the weird case of the library |
| 292 : | # browser, when we don't actually have | ||
| 293 : | jj | 5263 | # a set to look at, but this only happens among |
| 294 : | # instructor tool users. | ||
| 295 : | glarose | 5248 | return 0; |
| 296 : | glarose | 4918 | } else { |
| 297 : | return "Requested set '$setName' is not " . | ||
| 298 : | "assigned to user $effectiveUserName."; | ||
| 299 : | } | ||
| 300 : | glarose | 4907 | } |
| 301 : | if ( ! $set ) { | ||
| 302 : | return "Requested set '$setName' could not be found " . | ||
| 303 : | glarose | 4909 | "in the database for user $effectiveUserName."; |
| 304 : | glarose | 4907 | } |
| 305 : | } | ||
| 306 : | # cache the set for future use as needed. this should probably | ||
| 307 : | # be more sophisticated than this | ||
| 308 : | $self->{merged_set} = $set; | ||
| 309 : | |||
| 310 : | # now we know that the set is assigned to the appropriate user; | ||
| 311 : | # check to see if we're trying to access a set that's not open | ||
| 312 : | if ( before($set->open_date) && | ||
| 313 : | glarose | 4909 | ! $self->hasPermissions($userName, "view_unopened_sets") ) { |
| 314 : | glarose | 4907 | return "Requested set '$setName' is not yet open."; |
| 315 : | } | ||
| 316 : | |||
| 317 : | # also check to make sure that the set is published, or that we're | ||
| 318 : | # allowed to view unpublished setes | ||
| 319 : | # (do we need to worry about published not being set at this point?) | ||
| 320 : | my $published = ( $set && $set->published ne '0' && | ||
| 321 : | $set->published ne '1' ) ? 1 : $set->published; | ||
| 322 : | if ( ! $published && | ||
| 323 : | glarose | 4909 | ! $self->hasPermissions($userName, "view_unpublished_sets") ) { |
| 324 : | glarose | 4907 | return "Requested set '$setName' is not available yet."; |
| 325 : | } | ||
| 326 : | |||
| 327 : | # check to be sure that gateways are being sent to the correct | ||
| 328 : | # content generator | ||
| 329 : | if (defined($set->assignment_type) && | ||
| 330 : | $set->assignment_type =~ /gateway/ && | ||
| 331 : | ($node_name eq 'problem_list' || $node_name eq 'problem_detail')) { | ||
| 332 : | return "Requested set '$setName' is a test/quiz assignment " . | ||
| 333 : | "but the regular homework assignment content " . | ||
| 334 : | glarose | 4909 | "generator $node_name was called. Try re-entering " . |
| 335 : | "the set from the problem sets listing page."; | ||
| 336 : | glarose | 4911 | } elsif ( (! defined($set->assignment_type) || |
| 337 : | $set->assignment_type eq 'homework') && | ||
| 338 : | $node_name =~ /gateway/ ) { | ||
| 339 : | return "Requested set '$setName' is a homework assignment " . | ||
| 340 : | "but the gateway/quiz content " . | ||
| 341 : | "generator $node_name was called. Try re-entering " . | ||
| 342 : | "the set from the problem sets listing page."; | ||
| 343 : | glarose | 4907 | } |
| 344 : | glarose | 4911 | |
| 345 : | glarose | 4907 | # and check that if we're entering a proctored assignment that we |
| 346 : | # have a valid proctor login; this is necessary to make sure that | ||
| 347 : | # someone doesn't use the unproctored url path to obtain access | ||
| 348 : | # to a proctored assignment. | ||
| 349 : | if (defined($set->assignment_type) && | ||
| 350 : | $set->assignment_type =~ /proctored/ && | ||
| 351 : | ! WeBWorK::Authen::Proctor->new($r,$ce,$db)->verify() ) { | ||
| 352 : | return "Requested set '$setName' is a proctored test/quiz " . | ||
| 353 : | "assignment, but no valid proctor authorization " . | ||
| 354 : | "has been obtained."; | ||
| 355 : | } | ||
| 356 : | |||
| 357 : | # and whether there are ip restrictions that we need to check | ||
| 358 : | glarose | 4909 | my $badIP = $self->invalidIPAddress($set); |
| 359 : | return $badIP if $badIP; | ||
| 360 : | glarose | 4907 | |
| 361 : | glarose | 4909 | return 0; |
| 362 : | } | ||
| 363 : | glarose | 4907 | |
| 364 : | glarose | 4909 | sub invalidIPAddress { |
| 365 : | # this exists as a separate routine because we need to check multiple | ||
| 366 : | # sets in Hardcopy; having this routine to check the set allows us to do | ||
| 367 : | # that for all sets individually there. | ||
| 368 : | glarose | 4907 | |
| 369 : | glarose | 4909 | my $self = shift; |
| 370 : | my $set = shift; | ||
| 371 : | glarose | 4907 | |
| 372 : | glarose | 4909 | my $r = $self->{r}; |
| 373 : | my $db = $r->db; | ||
| 374 : | my $urlPath = $r->urlpath; | ||
| 375 : | glarose | 4926 | # my $setName = $urlPath->arg("setID"); # not always defined |
| 376 : | my $setName = $set->set_id; | ||
| 377 : | glarose | 4909 | my $userName = $r->param("user"); |
| 378 : | my $effectiveUserName = $r->param("effectiveUser"); | ||
| 379 : | glarose | 4907 | |
| 380 : | glarose | 5265 | return 0 if ($set->restrict_ip eq '' || $set->restrict_ip eq 'No' || |
| 381 : | glarose | 4909 | $self->hasPermissions($userName,'view_ip_restricted_sets')); |
| 382 : | |||
| 383 : | my $clientIP = new Net::IP($r->connection->remote_ip); | ||
| 384 : | glarose | 4916 | # make sure that we're using the non-versioned set name |
| 385 : | $setName =~ s/,v\d+$//; | ||
| 386 : | glarose | 4909 | |
| 387 : | my $restrictType = $set->restrict_ip; | ||
| 388 : | glarose | 4916 | my @restrictLocations = $db->getAllMergedSetLocations($effectiveUserName,$setName); |
| 389 : | glarose | 4909 | my @locationIDs = ( map {$_->location_id} @restrictLocations ); |
| 390 : | my @restrictAddresses = ( map {$db->listLocationAddresses($_)} @locationIDs ); | ||
| 391 : | |||
| 392 : | glarose | 4918 | # if there are no addresses in the locations, return an error that |
| 393 : | # says this | ||
| 394 : | return "Client ip address " . $clientIP->ip() . " is not allowed to " . | ||
| 395 : | "work this assignment, because the assignment has ip address " . | ||
| 396 : | "restrictions and there are no allowed locations associated " . | ||
| 397 : | "with the restriction. Contact your professor to have this " . | ||
| 398 : | "problem resolved." if ( ! @restrictAddresses ); | ||
| 399 : | |||
| 400 : | glarose | 4909 | # build a set of IP objects to match against |
| 401 : | my @restrictIPs = ( map {new Net::IP($_)} @restrictAddresses ); | ||
| 402 : | |||
| 403 : | # and check the clientAddress against these: is $clientIP | ||
| 404 : | # in @restrictIPs? | ||
| 405 : | my $inRestrict = 0; | ||
| 406 : | foreach my $rIP ( @restrictIPs ) { | ||
| 407 : | if ($rIP->overlaps($clientIP) == $IP_B_IN_A_OVERLAP || | ||
| 408 : | $rIP->overlaps($clientIP) == $IP_IDENTICAL) { | ||
| 409 : | glarose | 4916 | $inRestrict = $rIP->ip(); |
| 410 : | glarose | 4909 | last; |
| 411 : | glarose | 4907 | } |
| 412 : | } | ||
| 413 : | glarose | 4909 | |
| 414 : | glarose | 4918 | # this is slightly complicated by having to check relax_restrict_ip |
| 415 : | my $badIP = ''; | ||
| 416 : | glarose | 4909 | if ( $restrictType eq 'RestrictTo' && ! $inRestrict ) { |
| 417 : | glarose | 4918 | $badIP = "Client ip address " . $clientIP->ip() . |
| 418 : | glarose | 4909 | " is not in the list of addresses from " . |
| 419 : | "which this assignment may be worked."; | ||
| 420 : | } elsif ( $restrictType eq 'DenyFrom' && $inRestrict ) { | ||
| 421 : | glarose | 4918 | $badIP = "Client ip address " . $clientIP->ip() . |
| 422 : | glarose | 4909 | " is in the list of addresses from " . |
| 423 : | "which this assignment may not be worked."; | ||
| 424 : | } else { | ||
| 425 : | return 0; | ||
| 426 : | } | ||
| 427 : | glarose | 4918 | |
| 428 : | # if we're here, we failed the IP check, and so need to consider | ||
| 429 : | # if ip restrictions were relaxed. the set we were passed in | ||
| 430 : | # is either the merged userset or the merged versioned userset, | ||
| 431 : | # depending on whether the set is versioned or not | ||
| 432 : | |||
| 433 : | my $relaxRestrict = $set->relax_restrict_ip; | ||
| 434 : | return $badIP if ( $relaxRestrict eq 'No' ); | ||
| 435 : | |||
| 436 : | if ( $set->assignment_type =~ /gateway/ ) { | ||
| 437 : | if ( $relaxRestrict eq 'AfterAnswerDate' ) { | ||
| 438 : | # in this case we need to go and get the userset, | ||
| 439 : | # not the versioned set (which we already have) | ||
| 440 : | # drat! | ||
| 441 : | my $userset = $db->getMergedSet($set->user_id,$setName); | ||
| 442 : | return( ! $userset || before($userset->answer_date) | ||
| 443 : | ? $badIP : 0 ); | ||
| 444 : | } else { | ||
| 445 : | # this is easier; just look at the current answer date | ||
| 446 : | return( before($set->answer_date) ? $badIP : 0 ); | ||
| 447 : | } | ||
| 448 : | } else { | ||
| 449 : | # the set isn't versioned, so assume that $relaxRestrict | ||
| 450 : | # is 'AfterAnswerDate', regardless of what it actually | ||
| 451 : | # is; 'AfterVersionAnswerDate' doesn't make sense in | ||
| 452 : | # this case | ||
| 453 : | return( before($set->answer_date) ? $badIP : 0 ); | ||
| 454 : | } | ||
| 455 : | glarose | 4907 | } |
| 456 : | |||
| 457 : | sh002i | 3058 | =back |
| 458 : | |||
| 459 : | =cut | ||
| 460 : | |||
| 461 : | =head1 AUTHOR | ||
| 462 : | |||
| 463 : | Written by Dennis Lambe, malsyned at math.rochester.edu. Modified by Sam | ||
| 464 : | Hathaway, sh002i at math.rochester.edu. | ||
| 465 : | |||
| 466 : | =cut | ||
| 467 : | |||
| 468 : | malsyned | 390 | 1; |
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |