[LON-CAPA-cvs] cvs: loncom /homework bridgetask.pm inputtags.pm lonhomework.pm structuretags.pm /html/adm/helper newslot.helper /interface slotrequest.pm

raeburn raeburn at source.lon-capa.org
Sun Oct 4 22:35:52 EDT 2015


raeburn		Mon Oct  5 02:35:52 2015 EDT

  Modified files:              
    /loncom/homework	bridgetask.pm lonhomework.pm structuretags.pm 
                    	inputtags.pm 
    /loncom/interface	slotrequest.pm 
    /loncom/html/adm/helper	newslot.helper 
  Log:
  - Slots can now require each student to check-in from a unique IP address
    when using a particular slot for a specific resource. The IP address of
    the student's computer is then tied to that student's access to the resource
    thereafter, until the end date of the slot. 
    (Intended use case is high stakes online testing where students are using 
    computers with statically assigned IP addresses).
  
  
-------------- next part --------------
Index: loncom/homework/bridgetask.pm
diff -u loncom/homework/bridgetask.pm:1.264 loncom/homework/bridgetask.pm:1.265
--- loncom/homework/bridgetask.pm:1.264	Sun May 18 09:59:57 2014
+++ loncom/homework/bridgetask.pm	Mon Oct  5 02:35:40 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: bridgetask.pm,v 1.264 2014/05/18 09:59:57 raeburn Exp $
+# $Id: bridgetask.pm,v 1.265 2015/10/05 02:35:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -83,7 +83,7 @@
 		}
 	    }
 	    if ($authenticated) {
-		my $check = &check_in($type,$user,$domain,$slot_name);
+		my $check = &check_in($type,$user,$domain,$slot_name,$slot->{'iptied'});
                 if ($check =~ /^error:/) {
                     return 0;
                 }
@@ -95,25 +95,30 @@
 }
 
 sub check_in {
-    my ($type,$user,$domain,$slot_name) = @_;
+    my ($type,$user,$domain,$slot_name,$needsiptied) = @_;
     my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
+    my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
     if ( $useslots eq 'map_map') {
-	my $result = &check_in_sequence($user,$domain,$slot_name);
+	my $result = &check_in_sequence($user,$domain,$slot_name,$ip,$needsiptied);
         if ($result =~ /^error: /) {
             return $result;
         }
     } else {
-	&create_new_version($type,$user,$domain,$slot_name);
-	&Apache::structuretags::finalize_storage();
+        my ($symb) = &Apache::lonnet::whichuser();
+	my $result = &create_new_version($type,$user,$domain,$slot_name,$symb,$ip,$needsiptied);
+        if ($result eq 'ok') {
+	    &Apache::structuretags::finalize_storage();
+        }
+        return $result; 
     }
     return 1;
 }
 
 sub check_in_sequence {
-    my ($user,$domain,$slot_name) = @_;
+    my ($user,$domain,$slot_name,$ip,$needsiptied) = @_;
     my $navmap = Apache::lonnavmaps::navmap->new();
     if (!defined($navmap)) {
-        return 'error: ';
+        return 'error: No navmap';
     }
     my ($symb) = &Apache::lonnet::whichuser();
     my ($map)  = &Apache::lonnet::decode_symb($symb);
@@ -122,20 +127,43 @@
     my %old_history = %Apache::lonhomework::history;
     my %old_results = %Apache::lonhomework::results;
 
+    my $errorcount;
     foreach my $res (@resources) {
 	&Apache::lonxml::debug("doing ".$res->src);
 	&Apache::structuretags::initialize_storage($res->symb);
 	my $type = ($res->is_task()) ? 'Task' : 'problem';
-	&create_new_version($type,$user,$domain,$slot_name);
-	&Apache::structuretags::finalize_storage($res->symb);
+	my $result = &create_new_version($type,$user,$domain,$slot_name,$res->symb,$ip,$needsiptied);
+        if ($result eq 'ok') {
+	    &Apache::structuretags::finalize_storage($res->symb);
+        } else {
+            $errorcount ++;
+        }
     }
     
     %Apache::lonhomework::history = %old_history;
     %Apache::lonhomework::results = %old_results;
+    if ($errorcount) {
+        return 'error: IP taken';
+    }
 }
 
 sub create_new_version {
-    my ($type,$user,$domain,$slot_name) = @_;
+    my ($type,$user,$domain,$slot_name,$symb,$ip,$needsiptied) = @_;
+
+    if ($needsiptied) {
+        my $uniqkey = "$slot_name\0$symb\0$ip";
+        my ($cdom,$cnum);
+        if ($env{'request.course.id'}) {
+            my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+            my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+            my %hash = (
+                          "$slot_name\0$symb\0$ip" => $env{'user.name'}.':'.$env{'user.domain'}, 
+                       );
+            unless (&Apache::lonnet::newput('slot_uniqueips',\%hash,$cdom,$cnum) eq 'ok') {
+                return 'error: IP taken';
+            }
+        }
+    }
     
     my $id = '0';
     if ($type eq 'Task') {
@@ -169,11 +197,13 @@
 
     $Apache::lonhomework::results{"resource.$id.checkedin"}=
 	$user.':'.$domain;
+    $Apache::lonhomework::results{"resource.$id.checkedin.ip"}=$ip;
 
     if (defined($slot_name)) {
 	$Apache::lonhomework::results{"resource.$id.checkedin.slot"}=
 	    $slot_name;
     }
+    return 'ok'; 
 }
 
 sub get_version {
@@ -709,10 +739,14 @@
 	if ((($status eq 'CAN_ANSWER') || ($status eq 'NOT_YET_VIEWED')) && ($version eq '')) {
 	    # CAN_ANSWER or NOT_YET_VIEWED mode, and no current version, unproctored access
 	    # thus self-checkedin
-	    my $check = &check_in('Task',undef,undef,$slot_name);
-            if ($check =~ /^error: /) {
+            my $needsiptied;
+            if (ref($slot)) {
+                $needsiptied = $slot->{'iptied'};
+            }
+	    my $check = &check_in('Task',undef,undef,$slot_name,$needsiptied);
+            if ($check =~ /^error:\s+(.*)$/) {
                 my $symb=&Apache::lonnet::symbread();
-                &Apache::lonnet::logthis("Error during self-checkin of version $version of Task (symb: $symb) using slot: $slot_name");   
+                &Apache::lonnet::logthis("Error: $1 during self-checkin of version $version of Task (symb: $symb) using slot: $slot_name");   
             }
 	    &add_to_queue('gradingqueue',{'type' => 'Task',
 					  'time' => time,
@@ -765,6 +799,8 @@
 		} elsif ($status eq 'NOT_YET_VIEWED') {
                     my $symb=&Apache::lonnet::symbread();
                     $msg.=&Apache::structuretags::firstaccess_msg($accessmsg,$symb);
+                } elsif ($status eq 'NEED_DIFFERENT_IP') {
+#FIXME
 		} else {
 		    $msg.='<p class="LC_warning">'.&mt('Not open to be viewed').'</p>';
 		}
Index: loncom/homework/lonhomework.pm
diff -u loncom/homework/lonhomework.pm:1.357 loncom/homework/lonhomework.pm:1.358
--- loncom/homework/lonhomework.pm:1.357	Mon Sep 14 13:45:19 2015
+++ loncom/homework/lonhomework.pm	Mon Oct  5 02:35:40 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Homework handler
 #
-# $Id: lonhomework.pm,v 1.357 2015/09/14 13:45:19 raeburn Exp $
+# $Id: lonhomework.pm,v 1.358 2015/10/05 02:35:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -221,8 +221,39 @@
 	return ($status,$datemsg);
     }
 
-    if ($status eq 'SHOW_ANSWER' ||
-	$status eq 'CLOSED' ||
+    my $checkin = 'resource.0.checkedin';
+    my $version;
+    if ($type eq 'Task') {
+        $version=$Apache::lonhomework::history{'resource.version'};
+        $checkin = "resource.$version.0.checkedin";
+    }
+    my $checkedin = $Apache::lonhomework::history{$checkin};
+    my ($returned_slot,$slot_name,$checkinslot,$ipused,$blockip,$now,$ip);
+    $now = time;
+    $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
+
+    if ($checkedin) {
+        $checkinslot = $Apache::lonhomework::history{"$checkin.slot"};
+        my %slot=&Apache::lonnet::get_slot($checkinslot);
+        if ($slot{'iptied'}) {
+            $ipused = $Apache::lonhomework::history{"$checkin.ip"};
+            unless (($ip ne '') && ($ipused eq $ip)) {
+                $blockip = $slot{'iptied'};
+                $slot_name = $checkinslot;
+                $returned_slot = \%slot;
+            }
+        }
+    }
+
+    if ($status eq 'SHOW_ANSWER') {
+        if ($blockip eq 'answer') {
+            return ('NEED_DIFFERENT_IP','',$slot_name,$returned_slot,$ipused);
+        } else {
+            return ($status,$datemsg);
+        }
+    } 
+
+    if ($status eq 'CLOSED' ||
 	$status eq 'INVALID_ACCESS' ||
 	$status eq 'UNAVAILABLE') {
 	return ($status,$datemsg);
@@ -232,11 +263,14 @@
     }
     
     if ($type eq 'Task') {
-	my $version=$Apache::lonhomework::history{'resource.version'};
-	if ($Apache::lonhomework::history{"resource.$version.0.checkedin"} &&
+	if ($checkedin &&
 	    $Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass') {
-	    return ('SHOW_ANSWER');
-	}
+	    if ($blockip eq 'answer') {
+                return ('NEED_DIFFERENT_IP','',$slot_name,$returned_slot,$ipused);
+            } else {
+	        return ('SHOW_ANSWER');
+            }
+        }
     }
 
     my $availablestudent = &Apache::lonnet::EXT("resource.0.availablestudent",$symb);
@@ -246,10 +280,13 @@
 #    if (!@slots) {
 #	return ($status,$datemsg);
 #    }
+    undef($returned_slot);
+    undef($slot_name);
     my $slotstatus='NOT_IN_A_SLOT';
-    my ($returned_slot,$slot_name);
-    my $now = time;
     my $num_usable_slots = 0;
+    if (!$symb) {
+        ($symb) = &Apache::lonnet::whichuser();
+    }
     foreach my $slot (@slots) {
 	$slot =~ s/(^\s*|\s*$)//g;
 	&Apache::lonxml::debug("getting $slot");
@@ -260,12 +297,41 @@
 	if ($slot{'starttime'} < $now &&
 	    $slot{'endtime'} > $now &&
 	    &Apache::loncommon::check_ip_acc($slot{'ip'})) {
-	    &Apache::lonxml::debug("$slot is good");
-	    $slotstatus='NEEDS_CHECKIN';
-	    $returned_slot=\%slot;
-	    $slot_name=$slot;
-	    last;
-        } 
+            if ($slot{'iptied'}) {
+                if ($env{'request.course.id'}) {
+                    my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+                    my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+                    if ($slot eq $checkinslot) {
+                        if ($ip eq $ipused) {
+                            &Apache::lonxml::debug("$slot is good");
+                            $slotstatus ='NEEDS_CHECKIN'; 
+                        } else {
+                            $slotstatus = 'NEED_DIFFERENT_IP';
+                            $slot_name = $slot;
+                            $returned_slot = \%slot;
+                            last;
+                        }
+                    } elsif ($ip) {
+                        my $uniqkey = "$slot\0$symb\0$ip";
+                        my %used_ip = &Apache::lonnet::get('slot_uniqueips',[$uniqkey],$cdom,$cnum);
+                        if ($used_ip{$uniqkey}) {
+                            $slotstatus = 'NEED_DIFFERENT_IP';
+                        } else {
+                            &Apache::lonxml::debug("$slot is good");
+                            $slotstatus ='NEEDS_CHECKIN';
+                        }
+                    }
+                }
+            } else {
+	        &Apache::lonxml::debug("$slot is good");
+	        $slotstatus='NEEDS_CHECKIN';
+            }
+            if ($slotstatus eq 'NEEDS_CHECKIN') {
+	        $returned_slot=\%slot;
+	        $slot_name=$slot;
+	        last;
+            }
+        }
     }
     if ($slotstatus eq 'NEEDS_CHECKIN' &&
 	&proctor_checked_in($slot_name,$returned_slot,$type)) {
@@ -273,7 +339,7 @@
 	$slotstatus=$status;
     }
 
-    my ($is_correct,$got_grade,$checkedin);
+    my ($is_correct,$got_grade);
     if ($type eq 'Task') {
 	my $version=$Apache::lonhomework::history{'resource.0.version'};
 	$got_grade = 
@@ -282,11 +348,8 @@
 	$is_correct =  
 	    ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass'
 	     || $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ );
-	$checkedin =
-	    $Apache::lonhomework::history{"resource.$version.0.checkedin"};
     } elsif ($type eq 'problem') {
 	$got_grade  = 1;
-	$checkedin  = $Apache::lonhomework::history{"resource.0.checkedin"};
 	$is_correct =
 	    ($Apache::lonhomework::history{"resource.0.solved"} =~/^correct_/);
     }
@@ -305,7 +368,7 @@
     # However, the problem is not closed, and potentially, another slot might be
     # used to gain access to it to work on it, until the due date is reached, and the
     # problem then becomes CLOSED.  Therefore return the slotstatus - 
-    # (which will be one of: NOT_IN_A_SLOT, RESERVABLE, RESERVABLE_LATER, or NOTRESERVABLE.
+    # (which will be one of: NOT_IN_A_SLOT, RESERVABLE, RESERVABLE_LATER, or NOTRESERVABLE).
     if (!defined($slot_name) && $type eq 'problem') {
         if ($slotstatus eq 'NOT_IN_A_SLOT') {
             if (!$num_usable_slots) {
@@ -343,14 +406,18 @@
 	&& $checkedin ) {
 
 	if ($got_grade) {
-	    return ('SHOW_ANSWER');
+            if ($blockip eq 'answer') {
+                return ('NEED_DIFFERENT_IP','',$slot_name,$returned_slot,$ipused);
+            } else {
+	        return ('SHOW_ANSWER');
+            }
 	} else {
 	    return ('WAITING_FOR_GRADE');
 	}
 
     }
 
-    if ( $is_correct) {
+    if (($is_correct) && ($blockip ne 'answer')) {
 	if ($type eq 'problem') {
 	    return ($status);
 	}
@@ -358,11 +425,11 @@
     }
 
     if ( $status eq 'CANNOT_ANSWER' && 
-	 ($slotstatus ne 'NEEDS_CHECKIN' && $slotstatus ne 'NOT_IN_A_SLOT')) {
+	 ($slotstatus ne 'NEEDS_CHECKIN' && $slotstatus ne 'NOT_IN_A_SLOT' &&
+          $slotstatus ne 'NEED_DIFFERENT_IP') ) {
 	return ($status,$datemsg);
     }
-
-    return ($slotstatus,$datemsg,$slot_name,$returned_slot);
+    return ($slotstatus,$datemsg,$slot_name,$returned_slot,$ipused);
 }
 
 # JB, 9/24/2002: Any changes in this function may require a change
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.539 loncom/homework/structuretags.pm:1.540
--- loncom/homework/structuretags.pm:1.539	Mon Sep 14 13:45:19 2015
+++ loncom/homework/structuretags.pm	Mon Oct  5 02:35:40 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: structuretags.pm,v 1.539 2015/09/14 13:45:19 raeburn Exp $
+# $Id: structuretags.pm,v 1.540 2015/10/05 02:35:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1510,6 +1510,7 @@
     my $status;
     my $accessmsg;
     my $resource_due;
+    my $ipused;
 
     my $name= &get_resource_name($parstack,$safeeval);
     my ($result,$form_tag_start,$slot_name,$slot,$probpartlist);
@@ -1522,7 +1523,7 @@
             &Apache::lonnet::set_first_access($interval[1],$timelimit);
         }
 
-        ($status,$accessmsg,$slot_name,$slot) =
+        ($status,$accessmsg,$slot_name,$slot,$ipused) =
             &Apache::lonhomework::check_slot_access('0','problem');
         push (@Apache::inputtags::status,$status);
     }
@@ -1613,7 +1614,8 @@
             ( $status eq 'NOTRESERVABLE') ||
             ( $status eq 'RESERVABLE') ||
             ( $status eq 'RESERVABLE_LATER') ||
-	    ( $status eq 'INVALID_ACCESS')) {
+	    ( $status eq 'INVALID_ACCESS') ||
+            ( $status eq 'NEED_DIFFERENT_IP')) {
 	    my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser,
 						       $style);
 	    if ( $target eq "web" ) {
@@ -1646,7 +1648,14 @@
                               &Apache::lonnavmaps::timeToHumanString($accessmsg,'start'));
                 } elsif ($status eq 'NOTRESERVABLE') {
                     $msg.=&mt('Not available to make a reservation.');  
-		}
+		} elsif ($status eq 'NEED_DIFFERENT_IP') {
+                    if ($ipused) {
+                        $msg.=&mt('You must use the same computer ([_1]) you used when you first accessed this resource using your time/place-based reservation.',"IP: $ipused");
+                    } else {
+                        $msg.=&mt('Each student must use a different computer to access this resource at this time and/or place.').'<br />'.
+                              &mt('Somebody else has already used this particular computer for that purpose.');
+                    }
+                }
 		$result.=$msg.'<br />';
 	    } elsif ($target eq 'tex') {
 		my $startminipage = ($env{'form.problem_split'}=~/yes/i)? ''
@@ -1666,8 +1675,11 @@
 		$result .= 
 		    &Apache::bridgetask::proctor_validation_screen($slot);
 	    } elsif ($target eq 'grade') {
-		&Apache::bridgetask::proctor_check_auth($slot_name,$slot,
-							'problem');
+		my $checkinresult = &Apache::bridgetask::proctor_check_auth($slot_name,$slot,
+							                    'problem');
+                if ($checkinresult = /^error:/) {
+                    $result .= 'error';
+                }
 	    }
 	} elsif ($target eq 'web') {
 	    if ($status eq 'CAN_ANSWER') {
@@ -1677,10 +1689,18 @@
                         $Apache::lonhomework::history{'resource.0.checkedin'};
                     if ($checked_in eq '') {
                         # unproctored slot access, self checkin
-                        &Apache::bridgetask::check_in('problem',undef,undef,
-                                                      $slot_name);
-                        $checked_in =
-                            $Apache::lonhomework::results{"resource.0.checkedin"};
+                        my $needsiptied;
+                        if (ref($slot)) {
+                            $needsiptied = $slot->{'iptied'};
+                        }
+                        my $check = &Apache::bridgetask::check_in('problem',undef,undef,
+                                                                  $slot_name,$needsiptied);
+                        if ($check =~ /^error: /) {
+                            &Apache::lonnet::logthis("Error during self-checkin of problem (symb: $env{'request.symb'}) using slot: $slot_name");
+                        } else {
+                            $checked_in =
+                                $Apache::lonhomework::results{"resource.0.checkedin"};
+                        }
                     }
                     if ((ref($slot) eq 'HASH') && ($checked_in ne '')) {
                         if ($slot->{'starttime'} < time()) {
Index: loncom/homework/inputtags.pm
diff -u loncom/homework/inputtags.pm:1.336 loncom/homework/inputtags.pm:1.337
--- loncom/homework/inputtags.pm:1.336	Thu Jun 18 20:18:54 2015
+++ loncom/homework/inputtags.pm	Mon Oct  5 02:35:40 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # input  definitons
 #
-# $Id: inputtags.pm,v 1.336 2015/06/18 20:18:54 musolffc Exp $
+# $Id: inputtags.pm,v 1.337 2015/10/05 02:35:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1700,7 +1700,8 @@
 	 && $status ne 'NOT_IN_A_SLOT'
          && $status ne 'RESERVABLE'
          && $status ne 'RESERVABLE_LATER'
-         && $status ne 'NOTRESERVABLE') {
+         && $status ne 'NOTRESERVABLE'
+         && $status ne 'NEED_DIFFERENT_IP') {
 
 	if ($status eq 'SHOW_ANSWER') {
             $showbutton = 0;
Index: loncom/interface/slotrequest.pm
diff -u loncom/interface/slotrequest.pm:1.130 loncom/interface/slotrequest.pm:1.131
--- loncom/interface/slotrequest.pm:1.130	Sun Sep 27 22:35:39 2015
+++ loncom/interface/slotrequest.pm	Mon Oct  5 02:35:45 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler for requesting to have slots added to a students record
 #
-# $Id: slotrequest.pm,v 1.130 2015/09/27 22:35:39 raeburn Exp $
+# $Id: slotrequest.pm,v 1.131 2015/10/05 02:35:45 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1494,7 +1494,8 @@
 	     'allowedusers'    => 'Users slot is restricted to.',
 	     'uniqueperiod'    => 'Period of time slot is unique',
 	     'scheduled'       => 'Scheduled Students',
-	     'proctor'         => 'List of proctors');
+	     'proctor'         => 'List of proctors',
+	     'iptied'          => 'Unique IP each student',);
     if ($crstype eq 'Community') {
         $show_fields{'startreserve'} = &mt('Time members can start reserving');
         $show_fields{'endreserve'} = &mt('Time members can no longer reserve');
@@ -1502,7 +1503,7 @@
     }
     my @show_order=('name','description','type','starttime','endtime',
 		    'startreserve','endreserve','reservationmsg','secret','space',
-		    'ip','symb','allowedsections','allowedusers','uniqueperiod',
+		    'ip','iptied','symb','allowedsections','allowedusers','uniqueperiod',
 		    'scheduled','proctor');
     my @show = 
 	(exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show')
@@ -1834,6 +1835,16 @@
 	if (exists($show{'ip'})) {
 	    $colspan++;$r->print("<td>$slots{$slot}{'ip'}</td>\n");
 	}
+        if (exists($show{'iptied'})) {
+            $colspan++;
+            if ($slots{$slot}{'iptied'} eq 'yes') {
+                $r->print('<td>'.&mt('Yes')."</td>\n");
+            } elsif ($slots{$slot}{'iptied'} eq 'answer') {
+                $r->print('<td>'.&mt('Yes, including post-answer date')."</td>\n");
+            } else {
+                $r->print('<td>'.&mt('No')."</td>\n");
+            }
+        }
 	if (exists($show{'symb'})) {
 	    $colspan++;$r->print("<td>".join('<br />', at titles)."</td>\n");
 	}
@@ -2952,6 +2963,7 @@
             ['endreserve','Reservation End Time'],
             ['reservationmsg','Message when reservation changed'],
 	    ['ip','IP or DNS restriction'],
+            ['iptied','Unique IP each student'],
 	    ['proctor','List of proctor ids'],
 	    ['description','Slot Description'],
 	    ['maxspace','Maximum number of reservations'],
@@ -3062,6 +3074,11 @@
 		$slot{$key}=$entries{$fields{$key}};
 	    }
 	}
+        if ($entries{$fields{'iptied'}} =~ /^\s*(yes|1)\s*$/i) {
+            $slot{'iptied'}='yes'; 
+        } elsif ($entries{$fields{'iptied'}} =~ /^\s*answer\s*$/i) {
+            $slot{'iptied'}='answer';
+        }
         if ($entries{$fields{'allowedusers'}}) {
             $entries{$fields{'allowedusers'}} =~ s/^\s+//;
             $entries{$fields{'allowedusers'}} =~ s/\s+$//;
@@ -3284,7 +3301,8 @@
 	my ($status) = &Apache::lonhomework::check_slot_access('0',$type);
 	if ($status eq 'CAN_ANSWER' ||
 	    $status eq 'NEEDS_CHECKIN' ||
-	    $status eq 'WAITING_FOR_GRADE') {
+	    $status eq 'WAITING_FOR_GRADE' ||
+            $status eq 'NEED_DIFFERENT_IP') {
 	    &fail($r,'not_allowed');
 	    return OK;
 	}
Index: loncom/html/adm/helper/newslot.helper
diff -u loncom/html/adm/helper/newslot.helper:1.32 loncom/html/adm/helper/newslot.helper:1.33
--- loncom/html/adm/helper/newslot.helper:1.32	Sun Sep 27 22:35:50 2015
+++ loncom/html/adm/helper/newslot.helper	Mon Oct  5 02:35:51 2015
@@ -253,6 +253,21 @@
         return &{$helper->{DATA}{origslot}}('ip');
       </defaultvalue>
     </string>
+
+    <message>
+      </p><p>Does each student need to use a unique IP address to access a resource with this slot?</p>
+    </message>
+    <choices variable="iptied">
+      <choice computer='no'>No. The student's IP address is not tied for later access to the same resource. </choice>
+      <choice computer='yes'>Yes. The IP address on a student's first access to a resource is tied for later access.</choice>
+      <choice computer='answer'>Yes. The IP address on a student's first access to a resource is tied for later access (including post-answer date).</choice>
+      <defaultvalue>
+        my $default=&{$helper->{DATA}{origslot}}('iptied');
+        if ($default eq 'yes') { return 'yes'; }
+        if ($default eq 'answer') { return 'answer'; }
+        return 'no';
+      </defaultvalue>
+    </choices>
     <message>  </p>  </message>
   </state>
 
@@ -403,6 +418,10 @@
 				     $helper->{'VARS'}{'endunique'}];
 	}
 
+        if ( $helper->{'VARS'}{'iptied'} =~ /^(yes|answer)$/ ) {
+            $slot{'iptied'} = lc($helper->{'VARS'}{'iptied'});
+        }
+
         if ( $helper->{'VARS'}{'useproctor'} eq 'yes'
 	     && $helper->{'VARS'}{'proctor'} =~/\S/ ) {
 	    my @names;
@@ -460,6 +479,15 @@
 		    &HTML::Entities::encode($slot{$which}).'</li>';
 	    }
 	}
+        if (exists($slot{'iptied'})) {
+            $result.="\n".'<li> '.$labels{'iptied'}.': ';
+            if ($slot{'iptied'} eq 'yes') {
+                $result.=&Apache::lonlocal::mt('yes');
+            } elsif ($slot{'iptied'} eq 'answer') {
+                $result.=&Apache::lonlocal::mt('yes, including post-answer date');
+            }
+            $result.='</li>';
+        }
         if (exists($slot{'symb'})) {
             $result.="\n".'<li> '.$labels{'symb'}.': ';
             if ($slot{'symb'} =~ /,/) {


More information about the LON-CAPA-cvs mailing list