--- loncom/interface/lontiny.pm 2024/02/10 14:24:46 1.8.2.6 +++ loncom/interface/lontiny.pm 2024/11/17 04:48:15 1.23 @@ -2,7 +2,7 @@ # Extract domain, courseID, and symb from a shortened URL, # and switch role to a role in designated course. # -# $Id: lontiny.pm,v 1.8.2.6 2024/02/10 14:24:46 raeburn Exp $ +# $Id: lontiny.pm,v 1.23 2024/11/17 04:48:15 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -99,7 +99,7 @@ sub handler { } if ($env{'request.course.id'} eq $cdom.'_'.$cnum) { # Check for ttoken - my $newlauncher = &launch_check($r->uri,$symb); + my $newlauncher = &launch_check($r->uri,$symb,$cdom,$cnum); my ($map,$resid,$url) = &Apache::lonnet::decode_symb($symb); if (&Apache::lonnet::is_on_map($url)) { my $realuri; @@ -307,7 +307,7 @@ sub handler { } sub launch_check { - my ($linkuri,$symb) = @_; + my ($linkuri,$symb,$cdom,$cnum) = @_; my ($linkprotector,$linkproturi,$linkprotexit,$linkprotpbid,$linkprotpburl, $linkkey,$newlauncher,$prevlaunch); if ($env{'form.ttoken'}) { @@ -447,6 +447,11 @@ sub launch_check { } if ($linkprotector) { &Apache::lonnet::appenv({'request.linkprot' => $linkprotector.':'.$linkproturi}); + if ($linkprotpburl && $linkprotpbid) { + my ($res,$error) = &store_passback_info($cdom,$cnum,$linkuri,$linkprotector, + $scope,$symb,$linkprotpbid,$linkprotpburl, + $currdeeplinklogin); + } } elsif ($env{'request.linkprot'}) { &Apache::lonnet::delenv('request.linkprot'); } @@ -525,6 +530,68 @@ sub launch_check { return $newlauncher; } +# +# Store linkprotpburl and linkprotpbid in user's nohist_$cid_linkprot_pb.db +# $linkuri\0$linkprotector\0$scope = [$linkprotpbid,$linkprotpburl] +# Separately store $symb in course's nohist_linkprot_passback.db +# which should trigger passback: +# $symb => {$linkuri\0$linkprotector\0$scope => 1}; +# + +sub store_passback_info { + my ($cdom,$cnum,$linkuri,$linkprotector,$scope,$symb, + $linkprotpbid,$linkprotpburl,$currdeeplinklogin) = @_; + my $key = join("\0",($linkuri,$linkprotector,$scope)); + my $namespace = 'nohist_'.$cdom.'_'.$cnum.'_linkprot_pb'; + if ($linkuri eq $currdeeplinklogin) { + my %pbinfo = &Apache::lonnet::get($namespace,[$key]); + if (ref($pbinfo{$key}) eq 'ARRAY') { + if (($pbinfo{$key}[0] eq $linkprotpbid) && + ($pbinfo{$key}[1] eq $linkprotpburl)) { + return ('ok'); + } + } + } + my $now = time; + my $result = &Apache::lonnet::cput($namespace,{$key => [$linkprotpbid,$linkprotpburl]}); + my $error; + if (($result eq 'ok') || ($result eq 'con_delayed')) { + $namespace = 'nohist_linkprot_passback'; + my %triggers = &Apache::lonnet::get($namespace,[$symb],$cdom,$cnum); + my $newtrigger; + if ((exists($triggers{$symb})) && (ref($triggers{$symb}) eq 'HASH')) { + unless (exists($triggers{$symb}{$key})) { + $newtrigger = 1; + } + } else { + $newtrigger = 1; + } + if ($newtrigger) { + my ($lockhash,$tries,$gotlock); + $lockhash = { + lock => $env{'user.name'}. + ':'.$env{'user.domain'}, + }; + $tries = 0; + $gotlock = &Apache::lonnet::newput($namespace,$lockhash,$cdom,$cnum); + while (($gotlock ne 'ok') && ($tries<10)) { + $tries ++; + sleep (0.1); + $gotlock = &Apache::lonnet::newput($namespace,$lockhash,$cdom,$cnum); + } + if ($gotlock eq 'ok') { + %triggers = &Apache::lonnet::get($namespace,[$symb],$cdom,$cnum); + $triggers{$symb}{$key} = 1; + $result = &Apache::lonnet::cput($namespace,{$symb => $triggers{$symb}},$cdom,$cnum); + my $dellockoutcome = &Apache::lonnet::del($namespace,['lock'],$cdom,$cnum); + } else { + $error = 'nolock'; + } + } + } + return ($result,$error); +} + sub do_redirect { my ($r,$destination,$linkprot) = @_; my $windowname = 'loncapaclient';