--- rat/lonuserstate.pm 2022/10/05 22:54:00 1.149.2.5.2.3 +++ 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.149.2.5.2.3 2022/10/05 22:54:00 raeburn Exp $ +# $Id: lonuserstate.pm,v 1.171 2025/05/26 19:55:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -42,7 +42,7 @@ use Safe::Hole; use Opcode; use Apache::lonenc; use Fcntl qw(:flock); -use LONCAPA qw(:DEFAULT :match); +use LONCAPA qw(:DEFAULT :match); use File::Basename; @@ -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 @@ -260,9 +261,9 @@ sub loadmap { push(@map_ids, $resource_id); if ($hash{'src_'.$lpc.'.'.$resource_id}) { $rescount{$lpc} ++; - if (($hash{'src_'.$lpc.'.'.$resource_id}=~/\.sequence$/) || + if (($hash{'src_'.$lpc.'.'.$resource_id}=~/\.sequence$/) || ($hash{'src_'.$lpc.'.'.$resource_id}=~/\.page$/)) { - $mapcount{$lpc} ++; + $mapcount{$lpc} ++; } } unless ($codechecked) { @@ -405,6 +406,12 @@ sub error_detail { if (($parent_pc eq '0') && ($hash{'map_id_1'} =~ m{^/res/($match_domain)/($match_username)/.+\.(sequence|page)$})) { ($audomfile,$aunamefile) = ($1,$2); ($editfile,$filerole,$fileswitch) = &canedit_published($audomfile,$aunamefile); + if ($fileswitch) { + unless ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audomfile)) && + (&Apache::lonnet::will_trust('coaurem',$audomfile,$env{'user.domain'}))) { + undef($editfile); + } + } $errinfo = &mt('Top level published sequence file is missing.'); } else { if ($parent_pc eq '1') { @@ -478,6 +485,12 @@ sub error_detail { if ($uri =~ m{^/res/($match_domain)/($match_username)/.+\.(sequence|page)$}) { ($audomfile,$aunamefile) = ($1,$2); ($editfile,$filerole,$fileswitch) = &canedit_published($audomfile,$aunamefile); + if ($fileswitch) { + unless ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audomfile)) && + (&Apache::lonnet::will_trust('coaurem',$audomfile,$env{'user.domain'}))) { + undef($editfile); + } + } } } if ($errinfo) { @@ -530,10 +543,15 @@ sub error_detail { my $mapurl = $hash{'map_id_'.$parent_pc}; $mapurl =~s{^/res/}{/priv/}; if ($switchserver) { - $errinfo .= '.
'. - &mt('You will need to [_1]switch server[_2].', - '',''); + $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 { &js_escape(\$mapurl); $errinfo .= ': '.&mt('Edit the map').''; @@ -1169,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.')'); @@ -1504,6 +1528,7 @@ sub readmap { undef %hiddenurl; undef %encurl; undef %deeplinkout; + undef %deeplinkonlyprot; undef %rescount; undef %mapcount; $retfrid=''; @@ -1653,6 +1678,7 @@ sub readmap { undef %hiddenurl; undef %encurl; undef %deeplinkout; + undef %deeplinkonlyprot; undef %rescount; undef %mapcount; $errtext=''; @@ -1713,7 +1739,7 @@ sub readmap { if ($redirect) { $retfurl = $url; } - } + } return ($retfurl,$errtext); } @@ -1777,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)) { @@ -1817,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) { @@ -2030,6 +2091,10 @@ sub get_mapparam { last; } } + my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; + if (defined($$useropt{$recursechk})) { + return $$useropt{$recursechk}; + } } } @@ -2051,6 +2116,10 @@ sub get_mapparam { last; } } + my $recursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(rec).'.$what; + if (defined($$courseopt{$recursechk})) { + return $$courseopt{$recursechk}; + } } } @@ -2072,6 +2141,10 @@ sub get_mapparam { last; } } + my $recursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what; + if (defined($$courseopt{$recursechk})) { + return $$courseopt{$recursechk}; + } } } @@ -2115,6 +2188,10 @@ sub get_mapparam { last; } } + my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; + if (defined($$courseopt{$recursechk})) { + return $$courseopt{$recursechk}; + } } } }