--- loncom/homework/bridgetask.pm	2020/09/01 17:48:33	1.264.6.2
+++ loncom/homework/bridgetask.pm	2017/12/22 02:00:39	1.268
@@ -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.6.2 2020/09/01 17:48:33 raeburn Exp $
+# $Id: bridgetask.pm,v 1.268 2017/12/22 02:00:39 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -65,9 +65,8 @@ sub initialize_bridgetask {
 sub proctor_check_auth {
     my ($slot_name,$slot,$type)=@_;
     my $user=$env{'form.proctorname'};
-    $user =~ s/^\s+|\s+$//g;
     my $domain=$env{'form.proctordomain'};
-
+    
     my @allowed=split(",",$slot->{'proctor'});
     foreach my $possible (@allowed) {
 	my ($puser,$pdom)=(split(':',$possible));
@@ -84,7 +83,7 @@ sub proctor_check_auth {
 		}
 	    }
 	    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;
                 }
@@ -96,25 +95,30 @@ sub proctor_check_auth {
 }
 
 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{'REMOTE_ADDR'} || $env{'request.host'};
     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);
@@ -123,20 +127,50 @@ sub check_in_sequence {
     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 $type;
+        if ($res->is_task()) {
+            $type = 'Task';
+        } elsif ($res->is_tool) {
+            $type = 'tool';
+        } else {
+            $type = 'problem';
+        }
+	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') {
@@ -160,7 +194,7 @@ sub create_new_version {
 	    $domain = $env{'user.domain'};
 	}
 	
-    } elsif ($type eq 'problem') {
+    } elsif (($type eq 'problem') || ($type eq 'tool')) {
 	&Apache::lonxml::debug("authed $slot_name");
     }
     if (!defined($user) || !defined($domain)) {
@@ -170,11 +204,13 @@ sub create_new_version {
 
     $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 {
@@ -711,10 +747,14 @@ sub start_Task {
 	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,
@@ -767,6 +807,8 @@ sub start_Task {
 		} 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>';
 		}
@@ -3287,9 +3329,9 @@ sub proctor_validation_screen {
 <input type="hidden" name="validate" value="yes" />
 <input type="hidden" name="submitted" value="yes" />
 <table>
-  <tr><td>$lt{'prus'}</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" autocomplete="off" /></td></tr>
-  <tr><td>$lt{'pasw'}</td><td><input type="password" name="proctorpassword" value="" autocomplete="off" /></td></tr>
-  <tr><td>$lt{'prdo'}</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" autocomplete="off" /></td></tr>
+  <tr><td>$lt{'prus'}</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
+  <tr><td>$lt{'pasw'}</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
+  <tr><td>$lt{'prdo'}</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
 </table>
 <input type="submit" name="checkoutbutton" value="$lt{'vali'}"  /><br />
 <table border="1">