--- loncom/homework/bridgetask.pm 2020/01/13 14:31:19 1.264.6.1 +++ loncom/homework/bridgetask.pm 2025/03/31 13:55:08 1.274 @@ -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.1 2020/01/13 14:31:19 raeburn Exp $ +# $Id: bridgetask.pm,v 1.274 2025/03/31 13:55:08 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -32,12 +32,14 @@ package Apache::bridgetask; use strict; use Apache::lonnet; +use Apache::loncommon; use Apache::File(); use Apache::lonmenu; use Apache::lonlocal; use Apache::lonxml; use Apache::slotrequest(); use Apache::structuretags(); +use HTML::Entities(); use Time::HiRes qw( gettimeofday tv_interval ); use LONCAPA; @@ -65,6 +67,7 @@ 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'}); @@ -83,7 +86,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; } @@ -95,47 +98,82 @@ 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); my @resources = - $navmap->retrieveResources($map, sub { $_[0]->is_problem() },0,0); + $navmap->retrieveResources($map, sub { $_[0]->is_problem() || $_[0]->is_tool() },0,0); 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') { @@ -159,7 +197,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)) { @@ -169,11 +207,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 { @@ -710,10 +750,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, @@ -766,6 +810,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.='

'.&mt('Not open to be viewed').'

'; } @@ -3234,14 +3280,8 @@ sub proctor_validation_screen { my ($slot) = @_; my (undef,undef,$domain,$user) = &Apache::lonnet::whichuser(); my $url=&Apache::lonnet::studentphoto($domain,$user,'jpg'); - if ($url ne '/adm/lonKaputt/lonlogo_broken.gif') { - $url = ""; - } else { - undef($url); - } - my $name=&Apache::loncommon::plainname($user,$domain); - + my $msg; if ($env{'form.proctorpassword'}) { $msg.='

' @@ -3269,43 +3309,77 @@ sub proctor_validation_screen { my %lt = &Apache::lonlocal::texthash( 'prva' => "Proctor Validation", 'yoro' => "Your room's proctor needs to validate your access to this resource.", - 'prus' => "Proctor's Username:", - 'pasw' => "Password:", - 'prdo' => "Proctor's Domain:", + 'prus' => "Proctor's Username", + 'pasw' => "Password", + 'prdo' => "Proctor's Domain", 'vali' => 'Validate', 'stui' => "Student who should be logged in is:", - 'name' => "Name:", + 'name' => "Name", 'sid' => "Student/Employee ID", - 'unam' => "Username:", + 'unam' => "Username", + 'phot' => "Photo", ); - my $result= (<$lt{'prva'} -

$lt{'yoro'}

- $msg + my $proctortable = + &Apache::lonhtmlcommon::start_pick_box()."\n". + &Apache::lonhtmlcommon::row_title(''). + ''. + &Apache::lonhtmlcommon::row_closure()."\n". + &Apache::lonhtmlcommon::row_title(''). + ''. + &Apache::lonhtmlcommon::row_closure()."\n". + &Apache::lonhtmlcommon::row_title(''). + ''. + &Apache::lonhtmlcommon::row_closure(1)."\n". + &Apache::lonhtmlcommon::end_pick_box()."\n"; + + my $studenttable = + &Apache::loncommon::start_data_table('LC_manage_reservations'). + &Apache::loncommon::start_data_table_row(). + ''.$lt{'name'}.':'.$name.''. + &Apache::loncommon::end_data_table_row()."\n". + &Apache::loncommon::start_data_table_row(). + ''.$lt{'sid'}.':'.$env{'environment.id'}.''. + &Apache::loncommon::end_data_table_row()."\n". + &Apache::loncommon::start_data_table_row(). + ''.$lt{'unam'}.':'.$user.':'.$domain.''. + &Apache::loncommon::end_data_table_row(); + if ($url ne '/adm/lonKaputt/lonlogo_broken.gif') { + $studenttable .= &Apache::loncommon::start_data_table_row(). + ''.$lt{'phot'}.''. + ''. + &Apache::loncommon::end_data_table_row()."\n"; + } + $studenttable .= &Apache::loncommon::end_data_table()."\n"; + if ($msg ne '') { + $msg = "

$msg

"; + } else { + $msg = '

'; + } + return (< +

$lt{'prva'}


+
+$lt{'yoro'} +$msg
- - - - -
$lt{'prus'}
$lt{'pasw'}
$lt{'prdo'}
-
- - -
- - - - - - $url -
$lt{'stui'}
$lt{'name'}$name
$lt{'sid'}$env{'environment.id'}
$lt{'unam'}$user:$domain
-
+$proctortable +
+
+
+
+$lt{'stui'} +

+$studenttable +
+ ENDCHECKOUT - - return $result; } 1;