--- rat/lonuserstate.pm 2022/10/04 20:39:57 1.169 +++ rat/lonuserstate.pm 2025/05/26 19:55:11 1.171 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Construct and maintain state and binary representation of course for user # -# $Id: lonuserstate.pm,v 1.169 2022/10/04 20:39:57 raeburn Exp $ +# $Id: lonuserstate.pm,v 1.171 2025/05/26 19:55:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -63,6 +63,7 @@ my %randomizationcode; # code used to gr my %encurl; # URLs in this folder are supposed to be encrypted my %hiddenurl; # this URL (or complete folder) is supposed to be hidden my %deeplinkout; # this URL (or complete folder) unavailable in deep-link session +my %deeplinkonlyprot; # Link protection items used for deep-link only resources. my %rescount; # count of unhidden items in each map my %mapcount; # count of unhidden maps in each map @@ -504,6 +505,8 @@ sub error_detail { } else { $errinfo .= &mt('To rectify this problem, create and publish the missing file'); } + my $fileurl = $uri; + $fileurl =~s{^/res/}{/priv/}; if ($fileswitch) { my $rolename = &Apache::lonnet::plaintext($filerole); my $rolecode; @@ -513,10 +516,10 @@ sub error_detail { $rolecode = $filerole.'./'.$audomfile.'/'.$aunamefile; } $errinfo .= '.
'.&mt('You will need to [_1]switch server[_2].', - '',''); + '',''); } else { - my $fileurl = $uri; - $fileurl =~s{^/res/}{/priv/}; + &js_escape(\$fileurl); $errinfo .= ': '.&mt('Create the missing file').''; } } @@ -537,18 +540,20 @@ sub error_detail { } else { $errinfo .= &mt('To rectify this problem edit the parent map to remove the reference to the missing file'); } + my $mapurl = $hash{'map_id_'.$parent_pc}; + $mapurl =~s{^/res/}{/priv/}; if ($switchserver) { $errinfo .= '.
'; if ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audom)) && (&Apache::lonnet::will_trust('coaurem',$audom,$env{'user.domain'}))) { $errinfo .= &mt('You will need to [_1]switch server[_2].', - '',''); + '',''); } else { $errinfo .= &mt('Session switch required but prohibited.'); } } else { - my $mapurl = $hash{'map_id_'.$parent_pc}; - $mapurl =~s{^/res/}{/priv/}; + &js_escape(\$mapurl); $errinfo .= ': '.&mt('Edit the map').''; } } elsif ($uploaded && $courseid) { @@ -1182,8 +1187,14 @@ sub traceroute { } unless (@deeplink < 2) { $hash{'deeplinkonly_'.$rid}=join(':',map { &escape($_); } @deeplink); + my ($state,$others,$listed,$scope,$protect) = split(/,/,$deeplink[0]); + if (($state eq 'only') && ($protect ne 'none') && ($protect ne '')) { + my ($acctype,$item) = split(/:/,$protect); + if ($acctype =~ /lti(c|d)$/) { + $deeplinkonlyprot{$1}{$item} = 1; + } + } } - if (defined($hash{'conditions_'.$rid})) { $hash{'conditions_'.$rid}=simplify( '('.$hash{'conditions_'.$rid}.')|('.$sofar.')'); @@ -1517,6 +1528,7 @@ sub readmap { undef %hiddenurl; undef %encurl; undef %deeplinkout; + undef %deeplinkonlyprot; undef %rescount; undef %mapcount; $retfrid=''; @@ -1666,6 +1678,7 @@ sub readmap { undef %hiddenurl; undef %encurl; undef %deeplinkout; + undef %deeplinkonlyprot; undef %rescount; undef %mapcount; $errtext=''; @@ -1790,6 +1803,42 @@ sub build_tmp_hashes { &accinit($uri,$short,$fn); &hiddenurls(); } + my ($cdom,$cnum) = split(/_/,$short); + if (keys(%deeplinkonlyprot)) { + my %launchers; + if (ref($deeplinkonlyprot{'c'}) eq 'HASH') { + if (($cdom ne '') && ($cnum ne '')) { + my %crs_linkprot = &Apache::lonnet::get_course_lti($cnum,$cdom,'provider'); + foreach my $num (keys(%{$deeplinkonlyprot{'c'}})) { + if ((ref($crs_linkprot{$num}) eq 'HASH') && + ($crs_linkprot{$num}{'name'} ne '')) { + push(@{$launchers{$crs_linkprot{$num}{'name'}}},'c'.$num); + } + } + } + } + if (ref($deeplinkonlyprot{'d'}) eq 'HASH') { + if ($cdom ne '') { + my %dom_linkprot = &Apache::lonnet::get_domain_lti($cdom,'linkprot'); + foreach my $num (keys(%{$deeplinkonlyprot{'d'}})) { + if ((ref($dom_linkprot{$num}) eq 'HASH') && + ($dom_linkprot{$num}{'name'} ne '')) { + push(@{$launchers{$dom_linkprot{$num}{'name'}}},'d'.$num); + } + } + } + } + if (keys(%launchers)) { + my $value = ''; + foreach my $key (sort(keys(%launchers))) { + if (ref($launchers{$key}) eq 'ARRAY') { + $value .= &escape($key).':'.join(',',@{$launchers{$key}}).'&'; + } + } + $value =~ s/&$//; + &Apache::lonnet::appenv({'request.course.deeponlyprot' => $value}); + } + } $errtext .= &get_mapalias_errors(); # ------------------------------------------------------- Put versions into src foreach my $key (keys(%hash)) { @@ -1830,7 +1879,6 @@ sub build_tmp_hashes { } # Was initial access via a deep-link? - my ($cdom,$cnum) = split(/_/,$short); if (($cdom ne '') && ($env{'request.deeplink.login'} ne '')) { my $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom); if ($deeplink_symb) {