[LON-CAPA-cvs] cvs: loncom(version_2_11_X) /auth lonlogin.pm
raeburn
raeburn at source.lon-capa.org
Sun Dec 12 06:47:03 EST 2021
raeburn Sun Dec 12 11:47:03 2021 EDT
Modified files: (Branch: version_2_11_X)
/loncom/auth lonlogin.pm
Log:
- For 2.11
Backport 1.183, 1.184, 1.185, 1.186, 1.187 (part), 1.188, 1.189, 1.190,
1.191, 1.192 (part), 1.193
-------------- next part --------------
Index: loncom/auth/lonlogin.pm
diff -u loncom/auth/lonlogin.pm:1.158.2.12 loncom/auth/lonlogin.pm:1.158.2.13
--- loncom/auth/lonlogin.pm:1.158.2.12 Mon Jan 4 03:49:10 2021
+++ loncom/auth/lonlogin.pm Sun Dec 12 11:47:03 2021
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Login Screen
#
-# $Id: lonlogin.pm,v 1.158.2.12 2021/01/04 03:49:10 raeburn Exp $
+# $Id: lonlogin.pm,v 1.158.2.13 2021/12/12 11:47:03 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -38,6 +38,8 @@
use Apache::migrateuser();
use lib '/home/httpd/lib/perl/';
use LONCAPA qw(:DEFAULT :match);
+use URI::Escape;
+use HTML::Entities();
use CGI::Cookie();
sub handler {
@@ -47,16 +49,39 @@
(join('&',$ENV{'QUERY_STRING'},$env{'request.querystring'},
$ENV{'REDIRECT_QUERY_STRING'}),
['interface','username','domain','firsturl','localpath','localres',
- 'token','role','symb','iptoken','btoken']);
- if (!defined($env{'form.firsturl'})) {
- &Apache::lonacc::get_posted_cgi($r,['firsturl']);
- }
+ 'token','role','symb','iptoken','btoken','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');
+ if (($env{'form.sso'}) || ($env{'form.retry'})) {
+ my $infotoken;
+ if ($env{'form.sso'}) {
+ $infotoken = $env{'form.sso'};
+ } else {
+ $infotoken = $env{'form.retry'};
+ }
+ my $data = &Apache::lonnet::reply('tmpget:'.$infotoken,$lonhost);
+ unless (($data=~/^error/) || ($data eq 'con_lost') ||
+ ($data eq 'no_such_host')) {
+ my %info = &decode_token($data);
+ foreach my $item (keys(%info)) {
+ $env{'form.'.$item} = $info{$item};
+ }
+ &Apache::lonnet::tmpdel($infotoken);
+ }
+ } else {
+ if (!defined($env{'form.firsturl'})) {
+ &Apache::lonacc::get_posted_cgi($r,['firsturl']);
+ }
+ if ($env{'form.firsturl'} eq '/adm/logout') {
+ delete($env{'form.firsturl'});
+ }
+ }
+
# 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');
@@ -101,9 +126,6 @@
return OK;
}
- my $lonhost = $r->dir_config('lonHostID');
- $env{'form.firsturl'} =~ s/(`)/'/g;
-
# Check if browser sent a LON-CAPA load balancer cookie (and this is a balancer)
my ($found_server,$balancer_cookie) = &Apache::lonnet::check_for_balancer_cookie($r,1);
@@ -114,14 +136,25 @@
$protocol = 'http' if ($protocol ne 'https');
my $dest = '/adm/roles';
if ($env{'form.firsturl'} ne '') {
- $dest = $env{'form.firsturl'};
+ $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
}
my %info = (
balcookie => $lonhost.':'.$balancer_cookie,
);
+ 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) {
- $dest .= (($dest=~/\?/)?'&;':'?') . 'btoken='.$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;
+ }
+ unless ($found_server eq $lonhost) {
+ my $alias = &Apache::lonnet::use_proxy_alias($r,$found_server);
+ $hostname = $alias if ($alias ne '');
}
my $url = $protocol.'://'.$hostname.$dest;
my $start_page =
@@ -163,8 +196,6 @@
}
}
- $env{'form.firsturl'} =~ s/(`)/'/g;
-
# -------------------------------- Prevent users from attempting to login twice
if ($handle ne '') {
&Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);
@@ -174,7 +205,7 @@
&Apache::loncommon::end_page();
my $dest = '/adm/roles';
if ($env{'form.firsturl'} ne '') {
- $dest = $env{'form.firsturl'};
+ $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
}
$r->print(
$start_page
@@ -207,7 +238,7 @@
$env{'form.interface'}=~s/\W//g;
(undef,undef,undef,undef,undef,undef,my $clientmobile) =
- &Apache::loncommon::decode_user_agent();
+ &Apache::loncommon::decode_user_agent($r);
my $iconpath=
&Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));
@@ -301,23 +332,14 @@
# -------------------------------------------------------- Store away log token
my $tokenextras;
- if ($env{'form.role'}) {
- $tokenextras = '&role='.&escape($env{'form.role'});
- }
- if ($env{'form.symb'}) {
- if (!$tokenextras) {
- $tokenextras = '&';
- }
- $tokenextras .= '&symb='.&escape($env{'form.symb'});
- }
- if ($env{'form.iptoken'}) {
- if (!$tokenextras) {
- $tokenextras = '&&';
+ my @names = ('role','symb','iptoken');
+ foreach my $name (@names) {
+ if ($env{'form.'.$name} ne '') {
+ $tokenextras .= '&'.$name.'='.&escape($env{'form.'.$name});
}
- $tokenextras .= '&iptoken='.&escape($env{'form.iptoken'});
}
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
@@ -475,17 +497,9 @@
ENDSCRIPT
-# --------------------------------------------------- Print login screen header
-
- my %add_entries = (
- bgcolor => "$mainbg",
- text => "$font",
- link => "$link",
- vlink => "$vlink",
- alink => "$alink",
- onload => 'javascript:enableInput();',);
-
- my ($lonhost_in_use,$headextra,$headextra_exempt, at hosts,%defaultdomconf);
+ my ($lonhost_in_use, at hosts,%defaultdomconf,$saml_prefix,$saml_landing,
+ $samlssotext,$samlnonsso,$samlssoimg,$samlssoalt,$samlssourl,$samltooltip);
+ %defaultdomconf = &Apache::loncommon::get_domainconf($defdom);
@hosts = &Apache::lonnet::current_machine_ids();
$lonhost_in_use = $lonhost;
if (@hosts > 1) {
@@ -496,7 +510,67 @@
}
}
}
- %defaultdomconf = &Apache::loncommon::get_domainconf($defdom);
+ $saml_prefix = $defdom.'.login.saml_';
+ if ($defaultdomconf{$saml_prefix.$lonhost_in_use}) {
+ $saml_landing = 1;
+ $samlssotext = $defaultdomconf{$saml_prefix.'text_'.$lonhost_in_use};
+ $samlnonsso = $defaultdomconf{$saml_prefix.'notsso_'.$lonhost_in_use};
+ $samlssoimg = $defaultdomconf{$saml_prefix.'img_'.$lonhost_in_use};
+ $samlssoalt = $defaultdomconf{$saml_prefix.'alt_'.$lonhost_in_use};
+ $samlssourl = $defaultdomconf{$saml_prefix.'url_'.$lonhost_in_use};
+ $samltooltip = $defaultdomconf{$saml_prefix.'title_'.$lonhost_in_use};
+ }
+ if ($saml_landing) {
+ if ($samlssotext eq '') {
+ $samlssotext = 'SSO Login';
+ }
+ if ($samlnonsso eq '') {
+ $samlnonsso = 'Non-SSO Login';
+ }
+ $js .= <<"ENDSAMLJS";
+
+<script type="text/javascript">
+// <![CDATA[
+function toggleLClogin() {
+ if (document.getElementById('LC_standard_login')) {
+ if (document.getElementById('LC_standard_login').style.display == 'none') {
+ document.getElementById('LC_standard_login').style.display = 'inline-block';
+ if (document.getElementById('LC_login_text')) {
+ document.getElementById('LC_login_text').innerHTML = '$samlnonsso';
+ }
+ if (document.getElementById('LC_SSO_login')) {
+ document.getElementById('LC_SSO_login').style.display = 'none';
+ }
+ } else {
+ document.getElementById('LC_standard_login').style.display = 'none';
+ if (document.getElementById('LC_login_text')) {
+ document.getElementById('LC_login_text').innerHTML = '$samlssotext';
+ }
+ if (document.getElementById('LC_SSO_login')) {
+ document.getElementById('LC_SSO_login').style.display = 'inline-block';
+ }
+ }
+ }
+ return;
+}
+
+// ]]>
+</script>
+
+ENDSAMLJS
+ }
+
+# --------------------------------------------------- Print login screen header
+
+ my %add_entries = (
+ bgcolor => "$mainbg",
+ text => "$font",
+ link => "$link",
+ vlink => "$vlink",
+ alink => "$alink",
+ onload => 'javascript:enableInput();',);
+
+ my ($headextra,$headextra_exempt);
$headextra = $defaultdomconf{$defdom.'.login.headtag_'.$lonhost_in_use};
$headextra_exempt = $defaultdomconf{$domain.'.login.headtag_exempt_'.$lonhost_in_use};
if ($headextra) {
@@ -541,6 +615,7 @@
'helpdesk' => 'Contact Helpdesk',
'forgotpw' => 'Forgot password?',
'newuser' => 'New User?',
+ 'change' => 'Change?',
);
# -------------------------------------------------- Change password field name
@@ -602,7 +677,7 @@
$mobileargs = 'autocapitalize="off" autocorrect="off"';
}
my $loginform=(<<LFORM);
-<form name="client" action="" onsubmit="return(send())">
+<form name="client" action="" onsubmit="return(send())" id="lclogin">
<input type="hidden" name="lextkey" value="$lextkey" />
<input type="hidden" name="uextkey" value="$uextkey" />
<b><label for="uname">$lt{'un'}</label>:</b><br />
@@ -623,8 +698,70 @@
</div>
HEADER
}
- $r->print(<<ENDTOP);
-<div style="float:left;margin-top:0;">
+
+ my $stdauthformstyle = 'inline-block';
+ my $ssoauthstyle = 'none';
+ my $logintype;
+ $r->print('<div style="float:left;margin-top:0;">');
+ if ($saml_landing) {
+ $ssoauthstyle = 'inline-block';
+ $stdauthformstyle = 'none';
+ $logintype = $samlssotext;
+ my $ssologin = '/adm/sso';
+ if ($samlssourl ne '') {
+ $ssologin = $samlssourl;
+ }
+ if (($logtoken eq 'con_lost') || ($logtoken eq 'no_such_host')) {
+ my $querystring;
+ if ($env{'form.firsturl'} ne '') {
+ $querystring = 'origurl=';
+ if ($env{'form.firsturl'} =~ /[^\x00-\xFF]/) {
+ $querystring .= &uri_escape_utf8($env{'form.firsturl'});
+ } else {
+ $querystring .= &uri_escape($env{'form.firsturl'});
+ }
+ $querystring = &HTML::Entities::encode($querystring,"'");
+ }
+ if ($querystring ne '') {
+ $ssologin .= (($ssologin=~/\?/)?'&':'?') . $querystring;
+ }
+ } elsif ($logtoken ne '') {
+ $ssologin .= (($ssologin=~/\?/)?'&':'?') . 'logtoken='.$logtoken;
+ }
+ my $ssohref;
+ if ($samlssoimg ne '') {
+ $ssohref = '<a href="'.$ssologin.'" title="'.$samltooltip.'"><img src="'.$samlssoimg.'" alt="'.$samlssoalt.'" /></a>';
+ } else {
+ $ssohref = '<a href="'.$ssologin.'">'.$samlssotext.'</a>';
+ }
+ if (($env{'form.saml'} eq 'no') ||
+ (($env{'form.username'} ne '') && ($env{'form.domain'} ne ''))) {
+ $ssoauthstyle = 'none';
+ $stdauthformstyle = 'inline-block';
+ $logintype = $samlnonsso;
+ }
+ $r->print(<<ENDSAML);
+<p>
+Log-in type:
+<span style="font-weight:bold" id="LC_login_text">$logintype</span><br />
+<span><a href="javascript:toggleLClogin();" style="color:#000000">$lt{'change'}</a></span>
+</p>
+<div style="display:$ssoauthstyle" id="LC_SSO_login">
+<div class="LC_Box" style="padding-top: 10px;">
+$ssohref
+$noscript_warning
+</div>
+<div class="LC_Box" style="padding-top: 10px;">
+$loginhelp
+$contactblock
+$coursecatalog
+</div>
+</div>
+ENDSAML
+ }
+
+ $r->print(<<ENDLOGIN);
+<div style="display:$stdauthformstyle;" id="LC_standard_login">
<div class="LC_Box" style="background:$loginbox_bg;">
$logintitle
$loginform
@@ -640,8 +777,8 @@
</div>
</div>
-<div>
-ENDTOP
+ENDLOGIN
+ $r->print('</div><div>'."\n");
if ($showmainlogo) {
$r->print(' <img src="'.$logo.'" alt="" class="LC_maxwidth" />'."\n");
}
@@ -814,7 +951,14 @@
}
my $url = $protocol.'://'.$hostname.$path;
if ($env{'form.firsturl'} ne '') {
- $url .='?firsturl='.$env{'form.firsturl'};
+ my $querystring;
+ if ($env{'form.firsturl'} =~ /[^\x00-\xFF]/) {
+ $querystring = &uri_escape_utf8($env{'form.firsturl'});
+ } else {
+ $querystring = &uri_escape($env{'form.firsturl'});
+ }
+ $querystring = &HTML::Entities::encode($querystring,"'");
+ $url .='?firsturl='.$querystring;
}
my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,
{'redirect' => [0,$url],});
@@ -890,5 +1034,19 @@
return '<a href="/adm/createaccount">'.$linkname.'</a>';
}
+sub decode_token {
+ my ($info) = @_;
+ my ($firsturl, at rest)=split(/\&/,$info);
+ my %form;
+ if ($firsturl ne '') {
+ $form{'firsturl'} = &unescape($firsturl);
+ }
+ foreach my $item (@rest) {
+ my ($key,$value) = split(/=/,$item);
+ $form{$key} = &unescape($value);
+ }
+ return %form;
+}
+
1;
__END__
More information about the LON-CAPA-cvs
mailing list