[LON-CAPA-cvs] cvs: loncom / lontrans.pm /auth lonacc.pm lonauth.pm lonlogin.pm lonroles.pm lonshibauth.pm migrateuser.pm /interface lontiny.pm /lti ltiauth.pm
raeburn
raeburn at source.lon-capa.org
Tue Nov 2 21:04:04 EDT 2021
raeburn Wed Nov 3 01:04:04 2021 EDT
Modified files:
/loncom/auth lonacc.pm lonauth.pm lonlogin.pm lonroles.pm
lonshibauth.pm migrateuser.pm
/loncom/interface lontiny.pm
/loncom lontrans.pm
/loncom/lti ltiauth.pm
Log:
- Bug 6907
- Use of token to store linkprot or linkkey compatible with use of
btoken and iptoken (for load balancing and IP change respectively).
- Launching access from a deeplink, with its own ltoken and/or linkkey,
for a user session originally launched from a different deeplink will
update required session information.
-------------- next part --------------
Index: loncom/auth/lonacc.pm
diff -u loncom/auth/lonacc.pm:1.199 loncom/auth/lonacc.pm:1.200
--- loncom/auth/lonacc.pm:1.199 Tue Oct 26 15:52:54 2021
+++ loncom/auth/lonacc.pm Wed Nov 3 01:04:02 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Cookie Based Access Handler
#
-# $Id: lonacc.pm,v 1.199 2021/10/26 15:52:54 raeburn Exp $
+# $Id: lonacc.pm,v 1.200 2021/11/03 01:04:02 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -305,7 +305,8 @@
my $query = $r->args;
my %form;
if ($query) {
- my @items = ('role','symb','iptoken','origurl','ltoken','linkkey','logtoken');
+ my @items = ('role','symb','iptoken','origurl','ttoken',
+ 'ltoken','linkkey','logtoken','sso');
&Apache::loncommon::get_unprocessed_cgi($query,\@items);
foreach my $item (@items) {
if (defined($env{'form.'.$item})) {
@@ -324,26 +325,97 @@
}
my ($linkprot,$linkkey);
- if ($form{'logtoken'}) {
+
+#
+# If Shibboleth auth is in use, and a dual SSO and non-SSO login page
+# is in use, then the query string will contain the logtoken item with
+# a value set to the name of a .tmp file in /home/httpd/perl/tmp
+# containing the url to display after authentication, and also,
+# optionally, role and symb, or linkprot or linkkey (deep-link access).
+#
+# If Shibboleth auth is in use, but a dual log-in page is not in use,
+# and the originally requested URL was /tiny/$domain/$id (i.e.,
+# for deeplinking), then the query string will contain the sso item
+# with a value set to the name of a .tmp file in /home/httpd/perl/tmp
+# containing the url to display after authentication, and also,
+# optionally, linkprot or linkkey (deep-link access).
+#
+# Otherwise the query string may contain role and symb, or if the
+# originally requested URL was /tiny/$domain/$id (i.e. for deeplinking)
+# then the query string may contain a ttoken item with a value set
+# to the name of a .tmp file in /home/httpd/perl/tmp containing either
+# linkprot or linkkey (deep-link access).
+#
+# If deep-linked, i.e., the originally requested URL was /tiny/$domain/$id
+# the linkkey may have originally been sent in POSTed data, which will
+# have been processed in lontrans.pm
+#
+
+ if ($form{'ttoken'}) {
+ my %info = &Apache::lonnet::tmpget($form{'ttoken'});
+ &Apache::lonnet::tmpdel($form{'ttoken'});
+ if ($info{'origurl'}) {
+ $form{'origurl'} = $info{'origurl'};
+ }
+ if ($info{'linkprot'}) {
+ $linkprot = $info{'linkprot'};
+ } elsif ($info{'linkkey'} ne '') {
+ $linkkey = $info{'linkkey'};
+ }
+ } elsif ($form{'logtoken'}) {
my ($firsturl, at rest);
my $lonhost = $r->dir_config('lonHostID');
my $tmpinfo = &Apache::lonnet::reply('tmpget:'.$form{'logtoken'},$lonhost);
my $delete = &Apache::lonnet::tmpdel($form{'logtoken'});
- (undef,$firsturl, at rest) = split(/&/,$tmpinfo);
- foreach my $item (@rest) {
- my ($key,$value) = split(/=/,$item);
- $form{$key} = &unescape($value);
+ unless (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost') ||
+ ($tmpinfo eq 'no_such_host')) {
+ (undef,$firsturl, at rest) = split(/&/,$tmpinfo);
+ if ($firsturl ne '') {
+ $firsturl = &unescape($firsturl);
+ }
+ foreach my $item (@rest) {
+ my ($key,$value) = split(/=/,$item);
+ $form{$key} = &unescape($value);
+ }
+ if ($firsturl =~ m{^/tiny/$match_domain/\w+$}) {
+ $form{'origurl'} = $firsturl;
+ }
+ if ($form{'linkprot'}) {
+ $linkprot = $form{'linkprot'};
+ } elsif ($form{'linkkey'} ne '') {
+ $linkkey = $form{'linkkey'};
+ }
+ if ($form{'iptoken'}) {
+ %sessiondata = &Apache::lonnet::tmpget($form{'iptoken'});
+ my $delete = &Apache::lonnet::tmpdel($form{'iptoken'});
+ }
}
- if ($firsturl =~ m{^/tiny/$match_domain/\w+$}) {
- $form{'origurl'} = $firsturl;
+ } elsif ($form{'sso'}) {
+ my $lonhost = $r->dir_config('lonHostID');
+ my $info = &Apache::lonnet::reply('tmpget:'.$form{'sso'},$lonhost);
+ &Apache::lonnet::tmpdel($form{'sso'});
+ unless (($info=~/^error/) || ($info eq 'con_lost') ||
+ ($info eq 'no_such_host')) {
+ my ($firsturl, at rest)=split(/\&/,$info);
+ if ($firsturl ne '') {
+ $form{'origurl'} = &unescape($firsturl);
+ }
+ foreach my $item (@rest) {
+ my ($key,$value) = split(/=/,$item);
+ $form{$key} = &unescape($value);
+ }
+ if ($form{'linkprot'}) {
+ $linkprot = $form{'linkprot'};
+ } elsif ($form{'linkkey'} ne '') {
+ $linkkey = $form{'linkkey'};
+ }
}
- }
- if ($form{'ltoken'}) {
+ } elsif ($form{'ltoken'}) {
my %link_info = &Apache::lonnet::tmpget($form{'ltoken'});
$linkprot = $link_info{'linkprot'};
my $delete = &Apache::lonnet::tmpdel($form{'ltoken'});
- }
- if ($form{'linkkey'} ne '') {
+ delete($form{'ltoken'});
+ } elsif ($form{'linkkey'} ne '') {
$linkkey = $form{'linkkey'};
}
@@ -432,6 +504,8 @@
foreach my $item ('role','symb','iptoken','origurl') {
if (exists($form{$item})) {
$info{$item} = $form{$item};
+ } elsif ($sessiondata{$item} ne '') {
+ $info{$item} = $sessiondata{$item};
}
}
unless (($info{'symb'}) || ($info{'origurl'})) {
@@ -488,6 +562,8 @@
$r->subprocess_env->set('SSOUserUnknown' => $user);
$r->subprocess_env->set('SSOUserDomain' => $domain);
if (grep(/^sso$/, at cancreate)) {
+#FIXME - need to preserve origurl, role and symb, or linkprot or linkkey for use after account
+# creation
$r->set_handlers('PerlHandler'=> [\&Apache::createaccount::handler]);
$r->handler('perl-script');
} else {
Index: loncom/auth/lonauth.pm
diff -u loncom/auth/lonauth.pm:1.168 loncom/auth/lonauth.pm:1.169
--- loncom/auth/lonauth.pm:1.168 Tue Oct 26 15:52:54 2021
+++ loncom/auth/lonauth.pm Wed Nov 3 01:04:02 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# User Authentication Module
#
-# $Id: lonauth.pm,v 1.168 2021/10/26 15:52:54 raeburn Exp $
+# $Id: lonauth.pm,v 1.169 2021/11/03 01:04:02 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -178,6 +178,22 @@
$destination .= 'source=login';
}
+ if (($env{'request.deeplink.login'} eq $lowerurl) &&
+ (($env{'request.linkprot'}) || ($env{'request.linkkey'} ne ''))) {
+ my %info;
+ if ($env{'request.linkprot'}) {
+ $info{'linkprot'} = $env{'request.linkprot'};
+ } elsif ($env{'request.linkkey'} ne '') {
+ $info{'linkkey'} = $env{'request.linkkey'};
+ }
+ $info{'origurl'} = $lowerurl;
+ my $token = &Apache::lonnet::tmpput(\%info,$r->dir_config('lonHostID'),'link');
+ unless (($token eq 'con_lost') || ($token eq 'refused') ||
+ ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
+ $destination .= (($destination =~ /\?/) ? '&' : '?') . 'ttoken='.$token;
+ }
+ }
+
my $windowname = 'loncapaclient';
if ($env{'request.lti.login'}) {
$windowname .= 'lti';
@@ -329,7 +345,7 @@
}
if (exists($form->{linkprot})) {
my $ltoken = &Apache::lonnet::tmpput({linkprot => $form->{'linkprot'}},
- $r->dir_config('lonHostID'));
+ $r->dir_config('lonHostID'),'retry');
if ($ltoken) {
$retry .= (($retry =~ /\?/) ? '&' : '?').'ltoken='.$ltoken;
}
@@ -398,44 +414,71 @@
my $end_page =
&Apache::loncommon::end_page();
my $dest = '/adm/roles';
- if ($env{'form.firsturl'} ne '') {
- $dest = $env{'form.firsturl'};
- if (($dest =~ m{^/tiny/$match_domain/\w+$}) && ($env{'request.course.id'})) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- my $symb = &Apache::loncommon::symb_from_tinyurl($dest,$cnum,$cdom);
- if ($symb) {
- my $buffer;
- if ($r->header_in('Content-length') > 0) {
- $r->read($buffer,$r->header_in('Content-length'),0);
- }
- my %form;
- foreach my $pair (split(/&/,$buffer)) {
- my ($name,$value) = split(/=/,$pair);
- $value =~ tr/+/ /;
- $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
- $form{$name}=$value;
+ my %form = &get_form_items($r);
+ if ($form{'logtoken'}) {
+ my $tmpinfo = &Apache::lonnet::reply('tmpget:'.$form{'logtoken'},
+ $form{'serverid'});
+ unless (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost') ||
+ ($tmpinfo eq 'no_such_host')) {
+ my ($des_key,$firsturl, at rest)=split(/&/,$tmpinfo);
+ $firsturl = &unescape($firsturl);
+ my %info;
+ foreach my $item (@rest) {
+ my ($key,$value) = split(/=/,$item);
+ $info{$key} = &unescape($value);
+ }
+ if ($firsturl ne '') {
+ $info{'firsturl'} = $firsturl;
+ $dest = $firsturl;
+ my $relogin;
+ if ($dest =~ m{^/tiny/$match_domain/\w+$}) {
+ if ($env{'request.course.id'}) {
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $symb = &Apache::loncommon::symb_from_tinyurl($dest,$cnum,$cdom);
+ if ($symb) {
+ unless (&set_deeplink_login(%info) eq 'ok') {
+ $relogin = 1;
+ }
+ }
+ }
+ if ($relogin) {
+ $r->print(
+ $start_page
+ .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
+ .'<p>'.&mt('Please [_1]log out[_2] first, and then try your access again',
+ '<a href="/adm/logout">','</a>')
+ .'</p>'
+ .$end_page);
+ } else {
+ if (($info{'linkprot'}) || ($info{'linkkey'} ne '')) {
+ my $token = &Apache::lonnet::tmpput(\%info,$r->dir_config('lonHostID'),'link');
+ unless (($token eq 'con_lost') || ($token eq 'refused') ||
+ ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
+ $dest .= (($dest =~ /\?/) ? '&' : '?') . 'ttoken='.$token;
+ }
+ }
+ $r->print(
+ $start_page
+ .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
+ .'<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4] first, and then try your access again',
+ '<a href="'.$dest.'">','</a>',
+ '<a href="/adm/logout">','</a>')
+ .'</p>'
+ .$end_page);
+ }
+ return OK;
}
- &set_deeplink_login(%form);
- } else {
- $r->print(
- $start_page
- .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
- .'<p>'.&mt('Please [_1]log out[_2] first, and then try your access again',
- '<a href="/adm/logout">','</a>')
- .'</p>'
- .$end_page);
- return OK;
}
}
}
$r->print(
- $start_page
- .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
- .'<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].'
- ,'<a href="'.$dest.'">','</a>','<a href="/adm/logout">','</a>')
- .'</p>'
- .$end_page
+ $start_page
+ .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
+ .'<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].'
+ ,'<a href="'.$dest.'">','</a>','<a href="/adm/logout">','</a>')
+ .'</p>'
+ .$end_page
);
return OK;
}
@@ -443,19 +486,7 @@
# ---------------------------------------------------- No valid token, continue
-
- my $buffer;
- if ($r->header_in('Content-length') > 0) {
- $r->read($buffer,$r->header_in('Content-length'),0);
- }
- my %form;
- foreach my $pair (split(/&/,$buffer)) {
- my ($name,$value) = split(/=/,$pair);
- $value =~ tr/+/ /;
- $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
- $form{$name}=$value;
- }
-
+ my %form = &get_form_items($r);
if ((!$form{'uname'}) || (!$form{'upass0'}) || (!$form{'udom'})) {
&failed($r,'Username, password and domain need to be specified.',
\%form);
@@ -499,7 +530,8 @@
return OK;
}
- my ($key,$firsturl, at rest)=split(/&/,$tmpinfo);
+ my ($des_key,$firsturl, at rest)=split(/&/,$tmpinfo);
+ $firsturl = &unescape($firsturl);
foreach my $item (@rest) {
my ($key,$value) = split(/=/,$item);
$form{$key} = &unescape($value);
@@ -508,7 +540,7 @@
$form{'firsturl'} = $firsturl;
}
my $upass = $ENV{HTTPS} ? $form{'upass0'}
- : &Apache::loncommon::des_decrypt($key,$form{'upass0'});
+ : &Apache::loncommon::des_decrypt($des_key,$form{'upass0'});
# ---------------------------------------------------------------- Authenticate
@@ -570,9 +602,9 @@
$firsturl='/adm/roles';
}
- my $hosthere;
+ my ($hosthere,%sessiondata);
if ($form{'iptoken'}) {
- my %sessiondata = &Apache::lonnet::tmpget($form{'iptoken'});
+ %sessiondata = &Apache::lonnet::tmpget($form{'iptoken'});
my $delete = &Apache::lonnet::tmpdel($form{'iptoken'});
if (($sessiondata{'domain'} eq $form{'udom'}) &&
($sessiondata{'username'} eq $form{'uname'})) {
@@ -616,7 +648,7 @@
unless ($suprim eq $uprim) {
unless ($suintdom eq $uintdom) {
&Apache::lonnet::logthis('Attempted switch user '
- .'to user with different "internet domain".');
+ .'to user with different "internet domain".');
$noprivswitch = 1;
}
}
@@ -778,6 +810,18 @@
$form{'noloadbalance'} = $hosthere;
}
my $extra_env;
+ if (($hosthere) && ($sessiondata{'sessionserver'} ne '')) {
+ if ($sessiondata{'origurl'} ne '') {
+ $firsturl = $sessiondata{'origurl'};
+ $form{'firsturl'} = $sessiondata{'origurl'};
+ my @names = ('role','symb','linkprot','linkkey');
+ foreach my $item (@names) {
+ if ($sessiondata{$item} ne '') {
+ $form{$item} = $sessiondata{$item};
+ }
+ }
+ }
+ }
if ($form{'linkprot'}) {
my ($linkprotector,$uri) = split(/:/,$form{'linkprot'},2);
if ($linkprotector) {
@@ -817,14 +861,31 @@
}
}
+sub get_form_items {
+ my ($r) = @_;
+ my $buffer;
+ if ($r->header_in('Content-length') > 0) {
+ $r->read($buffer,$r->header_in('Content-length'),0);
+ }
+ my %form;
+ foreach my $pair (split(/&/,$buffer)) {
+ my ($name,$value) = split(/=/,$pair);
+ $value =~ tr/+/ /;
+ $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
+ $form{$name}=$value;
+ }
+ return %form;
+}
+
sub set_deeplink_login {
my (%form) = @_;
+ my $disallow;
if ($form{'firsturl'} =~ m{^/tiny/($match_domain)/\w+$}) {
my $cdom = $1;
my ($cnum,$symb) = &Apache::loncommon::symb_from_tinyurl($form{'firsturl'},'',$cdom);
if ($symb) {
if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
- my ($disallow,$deeplink);
+ my $deeplink;
if ($symb =~ /\.(page|sequence)$/) {
my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($symb))[2]);
my $navmap = Apache::lonnavmaps::navmap->new();
@@ -857,14 +918,17 @@
}
}
}
- return;
+ if ($disallow) {
+ return;
+ }
+ return 'ok';
}
sub set_retry_token {
my ($form,$lonhost,$querystr) = @_;
if (ref($form) eq 'HASH') {
my ($firsturl,$token,$extras, at names);
- @names = ('role','symb','linkprot','linkkey');
+ @names = ('role','symb','linkprot','linkkey','iptoken');
foreach my $name (@names) {
if ($form->{$name} ne '') {
$extras .= '&'.$name.'='.&escape($form->{$name});
Index: loncom/auth/lonlogin.pm
diff -u loncom/auth/lonlogin.pm:1.192 loncom/auth/lonlogin.pm:1.193
--- loncom/auth/lonlogin.pm:1.192 Tue Oct 26 15:52:54 2021
+++ loncom/auth/lonlogin.pm Wed Nov 3 01:04:02 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Login Screen
#
-# $Id: lonlogin.pm,v 1.192 2021/10/26 15:52:54 raeburn Exp $
+# $Id: lonlogin.pm,v 1.193 2021/11/03 01:04:02 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -49,11 +49,29 @@
(join('&',$ENV{'QUERY_STRING'},$env{'request.querystring'},
$ENV{'REDIRECT_QUERY_STRING'}),
['interface','username','domain','firsturl','localpath','localres',
- 'token','role','symb','iptoken','btoken','ltoken','linkkey','saml',
- 'sso','retry']);
+ 'token','role','symb','iptoken','btoken','ltoken','ttoken','linkkey',
+ 'saml','sso','retry']);
+
+# -- check if they are a migrating user
+ if (defined($env{'form.token'})) {
+ return &Apache::migrateuser::handler($r);
+ }
+
my $lonhost = $r->dir_config('lonHostID');
- my $linkkey;
- if (($env{'form.sso'}) || ($env{'form.retry'})) {
+ if ($env{'form.ttoken'}) {
+ my %info = &Apache::lonnet::tmpget($env{'form.ttoken'});
+ &Apache::lonnet::tmpdel($env{'form.ttoken'});
+ if ($info{'origurl'}) {
+ $env{'form.firsturl'} = $info{'origurl'};
+ }
+ if ($info{'ltoken'}) {
+ $env{'form.ltoken'} = $info{'ltoken'};
+ } elsif ($info{'linkprot'}) {
+ $env{'form.linkprot'} = $info{'linkprot'};
+ } elsif ($info{'linkkey'} ne '') {
+ $env{'form.linkkey'} = $info{'linkkey'};
+ }
+ } elsif (($env{'form.sso'}) || ($env{'form.retry'})) {
my $infotoken;
if ($env{'form.sso'}) {
$infotoken = $env{'form.sso'};
@@ -70,9 +88,6 @@
&Apache::lonnet::tmpdel($infotoken);
}
} else {
- if ($env{'form.linkkey'}) {
- $linkkey = $env{'form.linkkey'};
- }
if (!defined($env{'form.firsturl'})) {
&Apache::lonacc::get_posted_cgi($r,['firsturl']);
}
@@ -82,7 +97,7 @@
}
}
if (($env{'form.firsturl'} =~ m{^/+tiny/+$LONCAPA::match_domain/+\w+$}) &&
- (!$env{'form.ltoken'}) && (!$env{'form.linkkey'})) {
+ (!$env{'form.ltoken'}) && (!$env{'form.linkprot'}) && (!$env{'form.linkkey'})) {
&Apache::lonacc::get_posted_cgi($r,['linkkey']);
}
if ($env{'form.firsturl'} eq '/adm/logout') {
@@ -90,11 +105,6 @@
}
}
-# -- check if they are a migrating user
- if (defined($env{'form.token'})) {
- return &Apache::migrateuser::handler($r);
- }
-
# For "public user" - remove any exising "public" cookie, as user really wants to log-in
my ($handle,$lonidsdir,$expirepub,$userdom);
$lonidsdir=$r->dir_config('lonIDsDir');
@@ -149,31 +159,40 @@
$protocol = 'http' if ($protocol ne 'https');
my $dest = '/adm/roles';
if ($env{'form.firsturl'} ne '') {
- if ($env{'form.firsturl'} =~ /[^\x00-\xFF]/) {
- $dest = &uri_escape_utf8($env{'form.firsturl'});
- } else {
- $dest = &uri_escape($env{'form.firsturl'});
- }
- $dest = &HTML::Entities::encode($dest,"'");
+ $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
}
my %info = (
balcookie => $lonhost.':'.$balancer_cookie,
);
- if ($env{'form.ltoken'}) {
- my %link_info = &Apache::lonnet::tmpget($env{'form.ltoken'});
- if ($link_info{'linkprot'}) {
- $info{'linkprot'} = $link_info{'linkprot'};
- }
- &Apache::lonnet::tmpdel($env{'form.ltoken'});
- delete($env{'form.ltoken'});
- } elsif ($env{'form.linkkey'}) {
- $info{'linkkey'} = $env{'form.linkkey'};
- delete($env{'form.linkkey'});
+ if ($env{'form.role'}) {
+ $info{'role'} = $env{'form.role'};
+ }
+ if ($env{'form.symb'}) {
+ $info{'symb'} = $env{'form.symb'};
}
my $balancer_token = &Apache::lonnet::tmpput(\%info,$found_server);
- if ($balancer_token) {
+ unless (($balancer_token eq 'con_lost') || ($balancer_token eq 'refused') ||
+ ($balancer_token eq 'unknown_cmd') || ($balancer_token eq 'no_such_host')) {
$dest .= (($dest=~/\?/)?'&':'?') . 'btoken='.$balancer_token;
}
+ if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
+ my %link_info;
+ if ($env{'form.ltoken'}) {
+ $link_info{'ltoken'} = $env{'form.ltoken'};
+ } elsif ($env{'form.linkprot'}) {
+ $link_info{'linkprot'} = $env{'form.linkprot'};
+ } elsif ($env{'form.linkkey'} ne '') {
+ $link_info{'linkkey'} = $env{'form.linkkey'};
+ }
+ if (keys(%link_info)) {
+ $link_info{'origurl'} = $env{'form.firsturl'};
+ my $token = &Apache::lonnet::tmpput(\%link_info,$found_server,'link');
+ unless (($token eq 'con_lost') || ($token eq 'refused') ||
+ ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
+ $dest .= (($dest=~/\?/)?'&':'?') . 'ttoken='.$token;
+ }
+ }
+ }
unless ($found_server eq $lonhost) {
my $alias = &Apache::lonnet::use_proxy_alias($r,$found_server);
$hostname = $alias if ($alias ne '');
@@ -193,17 +212,10 @@
# it a balancer cookie for an active session on this server.
#
- my ($balcookie,$linkprot,$linkkey);
+ my $balcookie;
if ($env{'form.btoken'}) {
my %info = &Apache::lonnet::tmpget($env{'form.btoken'});
$balcookie = $info{'balcookie'};
- if ($balcookie) {
- if ($info{'linkprot'}) {
- $linkprot = $info{'linkprot'};
- } elsif ($info{'linkkey'}) {
- $linkkey = $info{'linkkey'};
- }
- }
&Apache::lonnet::tmpdel($env{'form.btoken'});
delete($env{'form.btoken'});
}
@@ -234,19 +246,16 @@
&Apache::loncommon::end_page();
my $dest = '/adm/roles';
if ($env{'form.firsturl'} ne '') {
- if ($env{'form.firsturl'} =~ /[^\x00-\xFF]/) {
- $dest = &uri_escape_utf8($env{'form.firsturl'});
- } else {
- $dest = &uri_escape($env{'form.firsturl'});
- }
- $dest = &HTML::Entities::encode($dest,"'");
+ $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
}
- if (($env{'form.ltoken'}) || ($linkprot)) {
- unless ($linkprot) {
+ if (($env{'form.ltoken'}) || ($env{'form.linkprot'})) {
+ my $linkprot;
+ if ($env{'form.ltoken'}) {
my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
$linkprot = $info{'linkprot'};
my $delete = &Apache::lonnet::tmpdel($env{'form.ltoken'});
- delete($env{'form.ltoken'});
+ } else {
+ $linkprot = $env{'form.linkprot'};
}
if ($linkprot) {
my ($linkprotector,$deeplink) = split(/:/,$linkprot,2);
@@ -271,16 +280,14 @@
&Apache::lonnet::appenv({'user.linkproturi' => $deeplink});
}
}
- } elsif (($env{'form.linkkey'}) || ($linkkey)) {
+ } elsif ($env{'form.linkkey'} ne '') {
if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
- if ($linkkey eq '') {
- $linkkey = $env{'form.linkkey'};
- }
+ my $linkkey = $env{'form.linkkey'};
if ($env{'user.deeplinkkey'}) {
my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
unless (grep(/^\Q$linkkey\E$/, at linkkeys)) {
push(@linkkeys,$linkkey);
- &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
+ &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
}
} else {
&Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
@@ -337,8 +344,7 @@
my $defdom = $domain;
if ($lonhost ne '') {
unless ($sessiondata{'sessionserver'}) {
- my $redirect = &check_loginvia($domain,$lonhost,$lonidsdir,$balcookie,
- $linkprot,$linkkey);
+ my $redirect = &check_loginvia($domain,$lonhost,$lonidsdir,$balcookie);
if ($redirect) {
$r->print($redirect);
return OK;
@@ -423,11 +429,11 @@
# -------------------------------------------------------- Store away log token
my ($tokenextras,$tokentype);
- my @names = ('role','symb','iptoken','ltoken','linkkey');
+ my @names = ('role','symb','iptoken','ltoken','linkprot','linkkey');
foreach my $name (@names) {
if ($env{'form.'.$name} ne '') {
if ($name eq 'ltoken') {
- my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
+ my %info = &Apache::lonnet::tmpget($env{'form.'.$name});
if ($info{'linkprot'}) {
$tokenextras .= '&linkprot='.&escape($info{'linkprot'});
$tokentype = 'link';
@@ -435,7 +441,7 @@
}
} else {
$tokenextras .= '&'.$name.'='.&escape($env{'form.'.$name});
- if ($name eq 'linkkey') {
+ if (($name eq 'linkkey') || ($name eq 'linkprot')) {
$tokentype = 'link';
}
}
@@ -445,7 +451,7 @@
$tokenextras .= ":$tokentype";
}
my $logtoken=Apache::lonnet::reply(
- 'tmpput:'.$ukey.$lkey.'&'.$firsturl.$tokenextras,
+ 'tmpput:'.$ukey.$lkey.'&'.&escape($firsturl).$tokenextras,
$lonhost);
# -- If we cannot talk to ourselves, or hostID does not map to a hostname
@@ -1000,7 +1006,7 @@
}
sub check_loginvia {
- my ($domain,$lonhost,$lonidsdir,$balcookie,$linkprot,$linkkey) = @_;
+ my ($domain,$lonhost,$lonidsdir,$balcookie) = @_;
if ($domain eq '' || $lonhost eq '' || $lonidsdir eq '') {
return;
}
@@ -1060,7 +1066,7 @@
}
}
}
- $output = &redirect_page($newhost,$path,$linkprot,$linkkey);
+ $output = &redirect_page($newhost,$path);
}
}
}
@@ -1069,7 +1075,7 @@
}
sub redirect_page {
- my ($desthost,$path,$linkprot,$linkkey) = @_;
+ my ($desthost,$path) = @_;
my $hostname = &Apache::lonnet::hostname($desthost);
my $protocol = $Apache::lonnet::protocol{$desthost};
$protocol = 'http' if ($protocol ne 'https');
@@ -1087,13 +1093,18 @@
$querystring = &HTML::Entities::encode($querystring,"'");
$url .='?firsturl='.$querystring;
}
- if ($linkprot) {
- my $ltoken = &Apache::lonnet::tmpput({linkprot => $linkprot},$desthost);
- if ($ltoken) {
- $url .= (($url =~ /\?/) ? '&' : '?').'ltoken='.$ltoken;
+ if (($env{'form.ltoken'}) || ($env{'form.linkkey'} ne '')) {
+ my %link_info;
+ if ($env{'form.ltoken'}) {
+ $link_info{'ltoken'} = $env{'form.ltoken'};
+ } elsif ($env{'form.linkkey'} ne '') {
+ $link_info{'linkkey'} = $env{'form.linkkey'};
+ }
+ my $token = &Apache::lonnet::tmpput(\%link_info,$desthost,'link');
+ unless (($token eq 'con_lost') || ($token eq 'refused') ||
+ ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
+ $url .= (($url=~/\?/)?'&':'?') . 'ttoken='.$token;
}
- } elsif ($linkkey) {
- $url .= (($url =~ /\?/) ? '&' : '?').'linkkey='.&uri_escape($linkkey);
}
my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,
{'redirect' => [0,$url],});
Index: loncom/auth/lonroles.pm
diff -u loncom/auth/lonroles.pm:1.352 loncom/auth/lonroles.pm:1.353
--- loncom/auth/lonroles.pm:1.352 Tue Oct 26 14:25:09 2021
+++ loncom/auth/lonroles.pm Wed Nov 3 01:04:02 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# User Roles Screen
#
-# $Id: lonroles.pm,v 1.352 2021/10/26 14:25:09 raeburn Exp $
+# $Id: lonroles.pm,v 1.353 2021/11/03 01:04:02 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -912,6 +912,9 @@
$dest .= (($dest =~/\?/)? '&':'?').'symb='.$esc_symb;
}
}
+ if ($env{'form.ttoken'}) {
+ $dest .= (($dest =~/\?/)? '&':'?').'ttoken='.$env{'form.ttoken'};
+ }
unless ($env{'request.lti.login'}) {
$msg = '<p>'.&mt('Entering [_1] ...',
$env{'course.'.$cdom.'_'.$cnum.'.description'}).
Index: loncom/auth/lonshibauth.pm
diff -u loncom/auth/lonshibauth.pm:1.11 loncom/auth/lonshibauth.pm:1.12
--- loncom/auth/lonshibauth.pm:1.11 Tue Oct 26 15:52:54 2021
+++ loncom/auth/lonshibauth.pm Wed Nov 3 01:04:02 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Redirect Shibboleth authentication to designated URL (/adm/sso).
#
-# $Id: lonshibauth.pm,v 1.11 2021/10/26 15:52:54 raeburn Exp $
+# $Id: lonshibauth.pm,v 1.12 2021/11/03 01:04:02 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -98,19 +98,18 @@
}
} else {
my $uri = $r->uri;
- if ($r->args ne '') {
- $dest .= (($dest=~/\?/)?'&':'?').$r->args;
- }
- unless (($uri eq '/adm/roles') || ($uri eq '/adm/logout')) {
- unless ($r->args =~ /origurl=/) {
- $dest.=(($dest=~/\?/)?'&':'?').'origurl='.$uri;
- }
- }
if ($uri =~ m{^/tiny/$match_domain/\w+$}) {
- unless (($r->args =~ /ltoken=/) || ($r->args =~ /linkkey=/)) {
- &Apache::lonacc::get_posted_cgi($r,['linkkey']);
- if ($env{'form.linkkey'} ne '') {
- $dest.=(($dest=~/\?/)?'&':'?').'linkkey='.$env{'form.linkkey'};
+ my $querystring = &set_token($r,$lonhost);
+ if ($querystring ne '') {
+ $dest .= '?'.$querystring;
+ }
+ } else {
+ if ($r->args ne '') {
+ $dest .= (($dest=~/\?/)?'&':'?').$r->args;
+ }
+ unless (($uri eq '/adm/roles') || ($uri eq '/adm/logout')) {
+ unless ($r->args =~ /origurl=/) {
+ $dest.=(($dest=~/\?/)?'&':'?').'origurl='.$uri;
}
}
}
@@ -134,8 +133,18 @@
&Apache::loncommon::get_unprocessed_cgi($r->args);
}
if ($r->uri =~ m{^/tiny/$match_domain/\w+$}) {
- unless (($env{'form.ltoken'}) || ($env{'form.linkkey'})) {
- &Apache::lonacc::get_posted_cgi($r,['linkkey']);
+ if ($env{'form.ttoken'}) {
+ my %info = &Apache::lonnet::tmpget($env{'form.ttoken'});
+ &Apache::lonnet::tmpdel($env{'form.ttoken'});
+ if ($info{'ltoken'}) {
+ $env{'form.ltoken'} = $info{'ltoken'};
+ } elsif ($info{'linkkey'} ne '') {
+ $env{'form.linkkey'} = $info{'linkkey'};
+ }
+ } else {
+ unless (($env{'form.ltoken'}) || ($env{'form.linkkey'})) {
+ &Apache::lonacc::get_posted_cgi($r,['linkkey']);
+ }
}
}
my $extras;
@@ -143,6 +152,7 @@
if ($env{'form.'.$name} ne '') {
if ($name eq 'ltoken') {
my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
+ &Apache::lonnet::tmpdel($env{'form.ltoken'});
if ($info{'linkprot'}) {
$extras .= '&linkprot='.&escape($info{'linkprot'});
last;
@@ -162,7 +172,7 @@
foreach my $key (sort(keys(%env))) {
if ($key =~ /^form\.(.+)$/) {
my $name = $1;
- next if ($token{$name});
+ next if (($token{$name}) || ($name eq 'ttoken'));
$querystring .= '&'.$name.'='.$env{$key};
}
}
Index: loncom/auth/migrateuser.pm
diff -u loncom/auth/migrateuser.pm:1.53 loncom/auth/migrateuser.pm:1.54
--- loncom/auth/migrateuser.pm:1.53 Tue Oct 26 14:20:40 2021
+++ loncom/auth/migrateuser.pm Wed Nov 3 01:04:02 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Starts a user off based of an existing token.
#
-# $Id: migrateuser.pm,v 1.53 2021/10/26 14:20:40 raeburn Exp $
+# $Id: migrateuser.pm,v 1.54 2021/11/03 01:04:02 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -283,19 +283,17 @@
my %info= (
'domain' => $udom,
'username' => $dataref->{'username'},
- 'role' => $dataref->{'role'},
'sessionserver' => $lonhost,
);
- if ($dataref->{'origurl'}) {
- $info{'origurl'} = $dataref->{'origurl'};
- }
- if ($dataref->{'symb'}) {
- $info{'symb'} = $dataref->{'symb'};
+ my @names = ('origurl','symb','role','linkprot','linkkey');
+ foreach my $name (@names) {
+ if ($dataref->{$name} ne '') {
+ $info{$name} = $dataref->{$name};
+ }
}
- my $iptoken = &Apache::lonnet::tmpput(\%info,$switchto);
+ my $iptoken = &Apache::lonnet::tmpput(\%info,$switchto,'link');
unless ($iptoken eq 'conlost') {
- $url .= ($url =~ /\?/) ? '&' : '?';
- $url .= 'iptoken='.$iptoken;
+ $url .= (($url =~ /\?/) ? '&' : '?') . 'iptoken='.$iptoken;
}
$r->print(&Apache::loncommon::start_page($title,undef,
{'redirect' =>
@@ -709,8 +707,29 @@
if ($handle) {
&Apache::lonnet::transfer_profile_to_env($r->dir_config('lonIDsDir'),
$handle);
+ my $checklaunch;
+ if ($data{'origurl'} =~ m{^/tiny/$match_domain/\w+$}) {
+ if ($env{'request.linkprot'} ne '') {
+ unless ($env{'request.linkprot'} eq $data{'linkprot'}) {
+ $checklaunch = 1;
+ }
+ }
+ if ($env{'request.linkkey'} ne '') {
+ unless ($env{'request.linkkey'} eq $data{'linkkey'}) {
+ $checklaunch = 1;
+ }
+ }
+ if ($env{'request.deeplink.login'}) {
+ unless ($env{'request.deeplink.login'} eq $data{'deeplink.login'}) {
+ $checklaunch = 1;
+ }
+ }
+ }
if ($data{'linkprot'} ne '') {
&Apache::lonnet::appenv({'request.linkprot' => $data{'linkprot'}});
+ if ($env{'request.linkkey'}) {
+ &Apache::lonnet::delenv('request.linkkey');
+ }
my ($linkprotector,$deeplink) = split(/:/,$data{'linkprot'},2);
if ($env{'user.linkprotector'}) {
my @protectors = split(/,/,$env{'user.linkprotector'});
@@ -734,6 +753,9 @@
}
} elsif ($data{'linkkey'} ne '') {
&Apache::lonnet::appenv({'request.linkkey' => $data{'linkkey'}});
+ if ($env{'request.linkprot'}) {
+ &Apache::lonnet::delenv('request.linkprot');
+ }
my $deeplink = $data{'deeplink.login'};
my $linkkey = $data{'linkkey'};
if ($env{'user.deeplinkkey'} ne '') {
@@ -837,7 +859,26 @@
}
}
} elsif ($data{'origurl'} ne '') {
- $r->internal_redirect($data{'origurl'});
+ my $dest = $data{'origurl'};
+ if (($env{'request.deeplink.login'} eq $data{'origurl'}) &&
+ (($env{'request.linkprot'}) || ($env{'request.linkkey'} ne ''))) {
+ my %info;
+ if ($env{'request.linkprot'}) {
+ $info{'linkprot'} = $env{'request.linkprot'};
+ } elsif ($env{'request.linkkey'} ne '') {
+ $info{'linkkey'} = $env{'request.linkkey'};
+ }
+ $info{'origurl'} = $data{'origurl'};
+ if ($checklaunch) {
+ $info{'checklaunch'} = 1;
+ }
+ my $token = &Apache::lonnet::tmpput(\%info,$r->dir_config('lonHostID'),'link');
+ unless (($token eq 'con_lost') || ($token eq 'refused') ||
+ ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
+ $dest .= (($dest =~ /\?/) ? '&' : '?') . 'ttoken='.$token;
+ }
+ }
+ $r->internal_redirect($dest);
} elsif ($env{'request.course.id'}) {
$r->internal_redirect('/adm/navmaps');
} else {
@@ -889,7 +930,7 @@
}
if ($data{'deeplink.login'}) {
if (ref($extra_env) eq 'HASH') {
- $extra_env->{'request.deeplink.login' => $data{'deeplink.login'}};
+ $extra_env->{'request.deeplink.login'} = $data{'deeplink.login'};
} else {
$extra_env = {'request.deeplink.login' => $data{'deeplink.login'}};
}
@@ -939,15 +980,15 @@
} elsif ($data{'origurl'} =~ m{^/tiny/$match_domain/\w+$}) {
$next_url=$data{'origurl'};
} else {
- $next_url='/adm/roles?selectrole=1&'.&escape($data{'role'}).'=1';
+ $next_url='/adm/roles?selectrole=1&'.&escape($data{'role'}).'=1';
if ($data{'origurl'} ne '') {
- $next_url .= '&orgurl='.&escape($data{'origurl'});
+ $next_url .= '&orgurl='.&escape($data{'origurl'});
}
}
if ($data{'lti.login'}) {
if (($data{'origurl'} =~ m{/default_\d+\.sequence$}) ||
($data{'origurl'} =~ m{^/res/.+\.sequence$})) {
- $next_url .= '&navmap=1';
+ $next_url .= '&navmap=1';
}
}
if ($reuse_session) {
Index: loncom/interface/lontiny.pm
diff -u loncom/interface/lontiny.pm:1.7 loncom/interface/lontiny.pm:1.8
--- loncom/interface/lontiny.pm:1.7 Tue Aug 10 15:28:14 2021
+++ loncom/interface/lontiny.pm Wed Nov 3 01:04:03 2021
@@ -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.7 2021/08/10 15:28:14 raeburn Exp $
+# $Id: lontiny.pm,v 1.8 2021/11/03 01:04:03 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -67,9 +67,10 @@
if ($cnum =~ /^$match_courseid$/) {
my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
if ($chome ne 'no_host') {
- # Check for ltoken or linkkey
- my $newlauncher = &launch_check($r->uri,$symb,$cnum,$cdom);
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['ttoken']);
if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
+ # Check for ttoken
+ my $newlauncher = &launch_check($r->uri,$symb);
my ($map,$resid,$url) = &Apache::lonnet::decode_symb($symb);
if (&Apache::lonnet::is_on_map($url)) {
my $realuri;
@@ -207,6 +208,9 @@
}
my $destination .= '/adm/roles?selectrole=1&'.$newrole.'=1'.
'&destinationurl='.&HTML::Entities::encode($r->uri);
+ if ($env{'form.ttoken'}) {
+ $destination .= '&ttoken='.$env{'form.ttoken'};
+ }
&do_redirect($r,$destination);
} elsif (keys(%possroles) > 1) {
if (grep(/^(cc|co)$/, at allposs)) {
@@ -219,6 +223,9 @@
$newrole .= "./$cdom/$cnum";
my $destination .= '/adm/roles?selectrole=1&'.$newrole.'=1'.
'&destinationurl='.&HTML::Entities::encode($r->uri);
+ if ($env{'form.ttoken'}) {
+ $destination .= '&ttoken='.$env{'form.ttoken'};
+ }
&do_redirect($r,$destination);
} else {
my $hascustom;
@@ -243,13 +250,12 @@
}
sub launch_check {
- my ($linkuri,$symb,$cnum,$cdom) = @_;
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['ltoken','linkkey']);
+ my ($linkuri,$symb) = @_;
my ($linkprotector,$linkproturi,$linkkey,$newlauncher);
- if ($env{'form.ltoken'}) {
- my %link_info = &Apache::lonnet::tmpget($env{'form.ltoken'});
- &Apache::lonnet::tmpdel($env{'form.ltoken'});
- delete($env{'form.ltoken'});
+ if ($env{'form.ttoken'}) {
+ my %link_info = &Apache::lonnet::tmpget($env{'form.ttoken'});
+ &Apache::lonnet::tmpdel($env{'form.ttoken'});
+ delete($env{'form.ttoken'});
if ($link_info{'linkprot'}) {
($linkprotector,$linkproturi) = split(/:/,$link_info{'linkprot'},2);
if ($env{'user.linkprotector'}) {
@@ -272,84 +278,101 @@
} else {
&Apache::lonnet::appenv({'user.linkproturi' => $linkproturi});
}
- }
- } elsif ($env{'form.linkkey'}) {
- $linkkey = $env{'form.linkkey'};
- my $keyedlinkuri = $linkuri;
- if ($env{'user.deeplinkkey'}) {
- my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
- unless (grep(/^\Q$linkkey\E$/, at linkkeys)) {
- push(@linkkeys,$linkkey);
- &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
- }
- } else {
- &Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
- }
- if ($env{'user.keyedlinkuri'}) {
- my @keyeduris = split(/,/,$env{'user.keyedlinkuri'});
- unless (grep(/^\Q$keyedlinkuri\E$/, at keyeduris)) {
- push(@keyeduris,$keyedlinkuri);
- &Apache::lonnet::appenv({'user.keyedlinkuri' => join(',',sort(@keyeduris))});
+ } elsif ($link_info{'linkkey'} ne '') {
+ $linkkey = $link_info{'linkkey'};
+ my $keyedlinkuri = $linkuri;
+ if ($env{'user.deeplinkkey'} ne '') {
+ my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
+ unless (grep(/^\Q$linkkey\E$/, at linkkeys)) {
+ push(@linkkeys,$linkkey);
+ &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
+ }
+ } else {
+ &Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
}
- } else {
- &Apache::lonnet::appenv({'user.keyedlinkuri' => $keyedlinkuri});
- }
- delete($env{'form.linkkey'});
- }
- if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
- my $currdeeplinklogin = $env{'request.deeplink.login'};
- if ($linkprotector || $linkkey) {
- my $deeplink;
- if ($symb =~ /\.(page|sequence)$/) {
- my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($symb))[2]);
- my $navmap = Apache::lonnavmaps::navmap->new();
- if (ref($navmap)) {
- $deeplink = $navmap->get_mapparam(undef,$mapname,'0.deeplink');
+ if ($env{'user.keyedlinkuri'}) {
+ my @keyeduris = split(/,/,$env{'user.keyedlinkuri'});
+ unless (grep(/^\Q$keyedlinkuri\E$/, at keyeduris)) {
+ push(@keyeduris,$keyedlinkuri);
+ &Apache::lonnet::appenv({'user.keyedlinkuri' => join(',',sort(@keyeduris))});
}
} else {
- $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$symb);
+ &Apache::lonnet::appenv({'user.keyedlinkuri' => $keyedlinkuri});
}
- if ($deeplink ne '') {
- my $disallow;
- my ($state,$others,$listed,$scope,$protect) = split(/,/,$deeplink);
- if (($protect ne 'none') && ($protect ne '')) {
- my ($acctype,$item) = split(/:/,$protect);
- if ($acctype =~ /lti(c|d)$/) {
- unless ($linkprotector.':'.$linkproturi eq $item.$1.':'.$linkuri) {
- $disallow = 1;
- }
- } elsif ($acctype eq 'key') {
- unless ($linkkey eq $item) {
- $disallow = 1;
- }
+ }
+ if ($link_info{'checklaunch'}) {
+ $newlauncher = 1;
+ }
+ }
+ my $currdeeplinklogin = $env{'request.deeplink.login'};
+ my $deeplink;
+ if ($symb =~ /\.(page|sequence)$/) {
+ my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($symb))[2]);
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (ref($navmap)) {
+ $deeplink = $navmap->get_mapparam(undef,$mapname,'0.deeplink');
+ }
+ } else {
+ $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$symb);
+ }
+ if ($deeplink ne '') {
+ my $disallow;
+ my ($state,$others,$listed,$scope,$protect) = split(/,/,$deeplink);
+ if (($protect ne 'none') && ($protect ne '')) {
+ my ($acctype,$item) = split(/:/,$protect);
+ if ($acctype =~ /lti(c|d)$/) {
+ my $ltitype = $1;
+ if ($linkprotector) {
+ unless ($linkprotector.':'.$linkproturi eq $item.$ltitype.':'.$linkuri) {
+ $disallow = 1;
}
+ } else {
+ $disallow = 1;
}
- if ($disallow) {
- if ($currdeeplinklogin eq $linkuri) {
- &Apache::lonnet::delenv('request.deeplink.login');
+ } elsif ($acctype eq 'key') {
+ if ($linkkey ne '') {
+ unless ($linkkey eq $item) {
+ $disallow = 1;
}
} else {
- unless ($currdeeplinklogin eq $linkuri) {
- if ($linkprotector) {
- &Apache::lonnet::appenv({'request.linkprot' => $linkprotector.':'.$linkproturi});
- } elsif ($linkkey) {
- &Apache::lonnet::appenv({'request.linkkey' => $linkkey});
- }
- $newlauncher = 1;
- }
- &Apache::lonnet::appenv({'request.deeplink.login' => $linkuri});
+ $disallow = 1;
}
}
+ }
+ if ($disallow) {
+ if ($currdeeplinklogin eq $linkuri) {
+ &Apache::lonnet::delenv('request.deeplink.login');
+ }
} else {
+ unless ($currdeeplinklogin eq $linkuri) {
+ if (($linkprotector) || ($linkkey ne '')) {
+ if ($linkprotector) {
+ &Apache::lonnet::appenv({'request.linkprot' => $linkprotector.':'.$linkproturi});
+ } elsif ($env{'request.linkprot'}) {
+ &Apache::lonnet::delenv({'request.linkprot'});
+ }
+ if ($linkkey ne '') {
+ &Apache::lonnet::appenv({'request.linkkey' => $linkkey});
+ } elsif ($env{'request.linkkey'} ne '') {
+ &Apache::lonnet::delenv({'request.linkkey'});
+ }
+ $newlauncher = 1;
+ }
+ }
&Apache::lonnet::appenv({'request.deeplink.login' => $linkuri});
}
} else {
- &Apache::lonnet::appenv({'request.deeplink.login' => $linkuri});
if ($linkprotector) {
&Apache::lonnet::appenv({'request.linkprot' => $linkprotector.':'.$linkproturi});
- } elsif ($linkkey) {
+ } elsif ($env{'request.linkprot'}) {
+ &Apache::lonnet::delenv({'request.linkprot'});
+ }
+ if ($linkkey ne '') {
&Apache::lonnet::appenv({'request.linkkey' => $linkkey});
+ } else {
+ &Apache::lonnet::delenv({'request.linkkey'});
}
+ &Apache::lonnet::appenv({'request.deeplink.login' => $linkuri});
}
return $newlauncher;
}
@@ -402,12 +425,15 @@
$preamble = &mt('You have the following active roles in this course:');
}
$datatable = '<form name="" action="/adm/roles">'.
- '<input type="hidden" name="newrole" value="" />'.
- '<input type="hidden" name="selectrole" value="1" />'.
- '<input type="hidden" name="destinationurl" value="'.$r->uri.'" />'.
- &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row().
- '<th></th><th>'.&mt('User role').'</th>';
+ '<input type="hidden" name="newrole" value="" />'."\n".
+ '<input type="hidden" name="selectrole" value="1" />'."\n".
+ '<input type="hidden" name="destinationurl" value="'.$r->uri.'" />'."\n";
+ if ($env{'form.ttoken'}) {
+ $datatable .= '<input type="hidden" name="ttoken" value="'.$env{'form.ttoken'}.'" />'."\n";
+ }
+ $datatable .= &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ '<th></th><th>'.&mt('User role').'</th>';
if ($hassection) {
$datatable .= '<th>'.&mt('Section').'</th>';
}
Index: loncom/lontrans.pm
diff -u loncom/lontrans.pm:1.36 loncom/lontrans.pm:1.37
--- loncom/lontrans.pm:1.36 Fri Oct 8 14:36:51 2021
+++ loncom/lontrans.pm Wed Nov 3 01:04:03 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# URL translation for User Files
#
-# $Id: lontrans.pm,v 1.36 2021/10/08 14:36:51 raeburn Exp $
+# $Id: lontrans.pm,v 1.37 2021/11/03 01:04:03 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -105,14 +105,15 @@
if (($uri eq '/adm/switchserver') || ($uri =~ m{^/Shibboleth.sso/})) {
return DECLINED;
}
- unless ($uri eq '/adm/migrateuser') {
+ unless (($uri eq '/adm/migrateuser') || ($uri eq '/adm/sso')) {
my %user;
my $handle = &Apache::lonnet::check_for_valid_session($r,undef,\%user);
if (($handle) && ($user{'name'} ne '') && ($user{'domain'} ne '')) {
unless (($user{'name'} eq 'public') && ($user{'domain'} eq 'public')) {
- my $token = &get_token($r,$remote_ip,\%user);
+ my $dest = '/adm/migrateuser';
+ my $token = &set_token($r,$dest,$remote_ip,\%user);
unless ($token eq '') {
- $r->internal_redirect("/adm/migrateuser?token=$token");
+ $r->internal_redirect("$dest?token=$token");
$r->set_handlers('PerlHandler'=> undef);
return DECLINED;
}
@@ -124,19 +125,29 @@
if ($port eq '443') {
$protocol = 'https';
}
- my $querystring = $r->args;
if ($uri =~ m{^(/adm/css/)(.+)(.css)$}) {
$uri = $1.&escape($2).$3;
}
my $location = $protocol.'://'.$redirect.$uri;
- if ($querystring) {
- $location .= "?$querystring";
+ if ($r->uri =~ m{^/tiny/$match_domain/\w+$}) {
+ my $token = &set_token($r,$r->uri);
+ unless ($token eq '') {
+ $location .= '?ttoken='.$token;
+ }
+ } elsif ($r->args) {
+ $location .= '?'.$r->args;
}
$r->header_out(Location => $location);
return REDIRECT;
}
}
}
+ if ($r->uri =~ m{^/tiny/$match_domain/\w+$}) {
+ my $token = &set_token($r,$r->uri);
+ unless ($token eq '') {
+ $r->args('ttoken='.$token);
+ }
+ }
if ($r->uri=~m|^(/raw)?/uploaded/|) {
my $fn = $r->uri();
$fn=~s/^\/raw//;
@@ -208,40 +219,83 @@
return $redirect;
}
-sub get_token {
- my ($r,$remote_ip,$userref) = @_;
- return unless (ref($userref) eq 'HASH');
- my %user = %{$userref};
- my %info = ('ip' => $remote_ip,
- 'domain' => $user{'domain'},
- 'username' => $user{'name'},
- 'server' => $r->dir_config('lonHostID'),
- );
- my $query = $r->args;
- if ($query) {
- foreach my $pair (split(/&/,$query)) {
+sub set_token {
+ my ($r,$dest,$remote_ip,$userref) = @_;
+ my (%info,%user);
+ if ($dest eq '/adm/migrateuser') {
+ return unless (ref($userref) eq 'HASH');
+ %user = %{$userref};
+ %info = ('ip' => $remote_ip,
+ 'domain' => $user{'domain'},
+ 'username' => $user{'name'},
+ 'server' => $r->dir_config('lonHostID'),
+ );
+ }
+ if ($r->args) {
+ foreach my $pair (split(/&/,$r->args)) {
my ($name,$value) = split(/=/,$pair);
$name = &LONCAPA::unescape($name);
- next unless (($name eq 'role') || ($name eq 'symb'));
+ next unless (($name eq 'role') || ($name eq 'symb') ||
+ ($name eq 'ltoken') || ($name eq 'linkkey') ||
+ ($name eq 'ttoken'));
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$info{$name} = $value;
}
+ if ($info{'ttoken'}) {
+ my %current = &Apache::lonnet::tmpget($info{'ttoken'});
+ delete($info{'ttoken'});
+ if ($current{'origurl'} eq $r->uri) {
+ return if (keys(%current));
+ }
+ }
}
- unless ($info{'role'}) {
- if ($user{'role'} ne '') {
- $info{'role'} = $user{'role'};
+#
+# To be able to support deep-linking for a shortened URL, i.e.,
+# /tiny/$dom/$id with (a) linkkey included in POSTed data and
+# data and (b) non-Shibboleth SSO in use, ltoken (or linkprot
+# if sending to /adm/migrateuser), or linkkey are written to a
+# .tmp file in /home/httpd/perl/tmp and the query string is
+# replaced with ttoken=tokenid. This does mean other POSTed
+# data will be discarded.
+#
+ if ($r->uri =~ m{^/tiny/$match_domain/\w+$}) {
+ unless (($info{'ltoken'}) || ($info{'linkkey'} ne '')) {
+ &Apache::lonacc::get_posted_cgi($r,['linkkey']);
+ if ($env{'form.linkkey'} ne '') {
+ $info{'linkkey'} = $env{'form.linkkey'};
+ }
}
}
- unless ($info{'symb'}) {
- unless ($r->uri eq '/adm/roles') {
- $info{'origurl'} = $r->uri;
+ if ($dest eq '/adm/migrateuser') {
+ if ($info{'ltoken'}) {
+ my %link_info = &Apache::lonnet::tmpget($info{'ltoken'});
+ if ($link_info{'linkprot'}) {
+ $info{'linkprot'} = $link_info{'linkprot'};
+ }
+ &Apache::lonnet::tmpdel($info{'ltoken'});;
+ delete($info{'ltoken'});
+ }
+ unless ($info{'role'}) {
+ if ($user{'role'} ne '') {
+ $info{'role'} = $user{'role'};
+ }
+ }
+ unless ($info{'symb'}) {
+ unless ($r->uri eq '/adm/roles') {
+ $info{'origurl'} = $r->uri;
+ }
}
}
- my $token = &Apache::lonnet::tmpput(\%info,$r->dir_config('lonHostID'));
- unless (($token eq 'con_lost') || ($token eq 'refused') ||
- ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
- return $token;
+ if (($dest eq '/adm/migrateuser') || (keys(%info) > 0)) {
+ unless ($dest eq '/adm/migrateuser') {
+ $info{'origurl'} = $r->uri;
+ }
+ my $token = &Apache::lonnet::tmpput(\%info,$r->dir_config('lonHostID'),'link');
+ unless (($token eq 'con_lost') || ($token eq 'refused') ||
+ ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
+ return $token;
+ }
}
return;
}
Index: loncom/lti/ltiauth.pm
diff -u loncom/lti/ltiauth.pm:1.23 loncom/lti/ltiauth.pm:1.24
--- loncom/lti/ltiauth.pm:1.23 Thu Aug 12 00:05:27 2021
+++ loncom/lti/ltiauth.pm Wed Nov 3 01:04:04 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Basic LTI Authentication Module
#
-# $Id: ltiauth.pm,v 1.23 2021/08/12 00:05:27 raeburn Exp $
+# $Id: ltiauth.pm,v 1.24 2021/11/03 01:04:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -197,7 +197,7 @@
delete($env{'form.'.$key});
}
my $ltoken = &Apache::lonnet::tmpput({'linkprot' => $itemid.$ltitype.':'.$tail},
- $lonhost);
+ $lonhost,'link');
if ($ltoken) {
$r->internal_redirect($tail.'?ltoken='.$ltoken);
$r->set_handlers('PerlHandler'=> undef);
More information about the LON-CAPA-cvs
mailing list