--- 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};
+ }
}
}
}