--- loncom/interface/loncommon.pm 2020/11/12 01:18:26 1.1075.2.149 +++ loncom/interface/loncommon.pm 2023/09/11 13:54:11 1.1075.2.165 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1075.2.149 2020/11/12 01:18:26 raeburn Exp $ +# $Id: loncommon.pm,v 1.1075.2.165 2023/09/11 13:54:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1378,7 +1378,7 @@ sub help_open_menu { } sub top_nav_help { - my ($text) = @_; + my ($text,$linkattr) = @_; $text = &mt($text); my $stay_on_page; unless ($env{'environment.remote'} eq 'on') { @@ -1394,7 +1394,7 @@ sub top_nav_help { if ($link) { return <<"END"; $banner_link -$text +$text END } else { return ' '.$text.' '; @@ -3127,14 +3127,11 @@ sub authform_filesystem { $fsyscheck.' onchange="'.$jscall.'" onclick="'. $jscall.'"'.$disabled.' />'; } - $autharg = ''; $result = &mt ('[_1] Filesystem Authenticated (with initial password [_2])', - ''); + ''.$autharg); return $result; } @@ -4731,8 +4728,91 @@ sub findallcourses { ############################################### sub blockcheck { - my ($setters,$activity,$uname,$udom,$url,$is_course,$symb,$caller) = @_; + my ($setters,$activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller) = @_; + unless ($activity eq 'docs') { + my ($has_evb,$check_ipaccess); + my $dom = $env{'user.domain'}; + if ($env{'request.course.id'}) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $checkrole = "cm./$cdom/$cnum"; + my $sec = $env{'request.course.sec'}; + if ($sec ne '') { + $checkrole .= "/$sec"; + } + if ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) && + ($env{'request.role'} !~ /^st/)) { + $has_evb = 1; + } + unless ($has_evb) { + if (($activity eq 'printout') || ($activity eq 'grades') || ($activity eq 'search') || + ($activity eq 'boards') || ($activity eq 'groups') || ($activity eq 'chat')) { + if ($udom eq $cdom) { + $check_ipaccess = 1; + } + } + } + } elsif (($activity eq 'com') || ($activity eq 'port') || ($activity eq 'blogs') || + ($activity eq 'about') || ($activity eq 'wishlist') || ($activity eq 'passwd')) { + my $checkrole; + if ($env{'request.role.domain'} eq '') { + $checkrole = "cm./$env{'user.domain'}/"; + } else { + $checkrole = "cm./$env{'request.role.domain'}/"; + } + if (($checkrole) && (&Apache::lonnet::allowed('evb',undef,undef,$checkrole))) { + $has_evb = 1; + } + } + unless ($has_evb || $check_ipaccess) { + my @machinedoms = &Apache::lonnet::current_machine_domains(); + if (($dom eq 'public') && ($activity eq 'port')) { + $dom = $udom; + } + if (($dom ne '') && (grep(/^\Q$dom\E$/,@machinedoms))) { + $check_ipaccess = 1; + } else { + my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; + my $internet_names = &Apache::lonnet::get_internet_names($lonhost); + my $prim = &Apache::lonnet::domain($dom,'primary'); + my $intdom = &Apache::lonnet::internet_dom($prim); + if (($intdom ne '') && (ref($internet_names) eq 'ARRAY')) { + if (grep(/^\Q$intdom\E$/,@{$internet_names})) { + $check_ipaccess = 1; + } + } + } + } + if ($check_ipaccess) { + my ($ipaccessref,$cached)=&Apache::lonnet::is_cached_new('ipaccess',$dom); + unless (defined($cached)) { + my %domconfig = + &Apache::lonnet::get_dom('configuration',['ipaccess'],$dom); + $ipaccessref = &Apache::lonnet::do_cache_new('ipaccess',$dom,$domconfig{'ipaccess'},1800); + } + if ((ref($ipaccessref) eq 'HASH') && ($clientip)) { + foreach my $id (keys(%{$ipaccessref})) { + if (ref($ipaccessref->{$id}) eq 'HASH') { + my $range = $ipaccessref->{$id}->{'ip'}; + if ($range) { + if (&Apache::lonnet::ip_match($clientip,$range)) { + if (ref($ipaccessref->{$id}->{'commblocks'}) eq 'HASH') { + if ($ipaccessref->{$id}->{'commblocks'}->{$activity} eq 'on') { + return ('','','',$id,$dom); + last; + } + } + } + } + } + } + } + } + if (($activity eq 'wishlist') || ($activity eq 'annotate')) { + return (); + } + } if (defined($udom) && defined($uname)) { # If uname and udom are for a course, check for blocks in the course. if (($is_course) || (&Apache::lonnet::is_course($udom,$uname))) { @@ -4748,7 +4828,10 @@ sub blockcheck { my $startblock = 0; my $endblock = 0; my $triggerblock = ''; - my %live_courses = &findallcourses(undef,$uname,$udom); + my %live_courses; + unless (($activity eq 'wishlist') || ($activity eq 'annotate')) { + %live_courses = &findallcourses(undef,$uname,$udom); + } # If uname is for a user, and activity is course-specific, i.e., # boards, chat or groups, check for blocking in current course only. @@ -4955,13 +5038,19 @@ sub get_blocks { my $end = $start + $env{'course.'.$cdom.'_'.$cnum.'.timerinterval.'.$timersymb}; if ($start && $end) { if (($start <= time) && ($end >= time)) { - unless (grep(/^\Q$block\E$/,@blockers)) { - push(@blockers,$block); - $triggered{$block} = { - start => $start, - end => $end, - type => $type, - }; + if (ref($commblocks{$block}) eq 'HASH') { + if (ref($commblocks{$block}{'blocks'}) eq 'HASH') { + if ($commblocks{$block}{'blocks'}{$activity} eq 'on') { + unless(grep(/^\Q$block\E$/,@blockers)) { + push(@blockers,$block); + $triggered{$block} = { + start => $start, + end => $end, + type => $type, + }; + } + } + } } } } @@ -5025,14 +5114,17 @@ sub parse_block_record { } sub blocking_status { - my ($activity,$uname,$udom,$url,$is_course,$symb,$caller) = @_; + my ($activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller) = @_; my %setters; # check for active blocking - my ($startblock,$endblock,$triggerblock) = - &blockcheck(\%setters,$activity,$uname,$udom,$url,$is_course,$symb,$caller); + if ($clientip eq '') { + $clientip = &Apache::lonnet::get_requestor_ip(); + } + my ($startblock,$endblock,$triggerblock,$by_ip,$blockdom) = + &blockcheck(\%setters,$activity,$clientip,$uname,$udom,$url,$is_course,$symb,$caller); my $blocked = 0; - if ($startblock && $endblock) { + if (($startblock && $endblock) || ($by_ip)) { $blocked = 1; } @@ -5041,8 +5133,8 @@ sub blocking_status { # build a link to a popup window containing the details my $querystring = "?activity=$activity"; -# $uname and $udom decide whose portfolio the user is trying to look at - if (($activity eq 'port') || ($activity eq 'passwd')) { +# $uname and $udom decide whose portfolio (or information page) the user is trying to look at + if (($activity eq 'port') || ($activity eq 'about') || ($activity eq 'passwd')) { $querystring .= "&udom=$udom" if ($udom =~ /^$match_domain$/); $querystring .= "&uname=$uname" if ($uname =~ /^$match_username$/); } elsif ($activity eq 'docs') { @@ -5076,6 +5168,16 @@ END_MYBLOCK $text = &mt('Printing Blocked'); } elsif ($activity eq 'passwd') { $text = &mt('Password Changing Blocked'); + } elsif ($activity eq 'grades') { + $text = &mt('Gradebook Blocked'); + } elsif ($activity eq 'search') { + $text = &mt('Search Blocked'); + } elsif ($activity eq 'about') { + $text = &mt('Access to User Information Pages Blocked'); + } elsif ($activity eq 'wishlist') { + $text = &mt('Access to Stored Links Blocked'); + } elsif ($activity eq 'annotate') { + $text = &mt('Access to Annotations Blocked'); } $output .= <<"END_BLOCK";
@@ -5105,7 +5207,8 @@ sub check_ip_acc { ($ENV{'REMOTE_ADDR'} eq &Apache::lonnet::get_host_ip($Apache::lonnet::perlvar{'lonHostID'}))) { $ip = $env{'request.host'} || $ENV{'REMOTE_ADDR'} || $clientip; } else { - $ip = $ENV{'REMOTE_ADDR'} || $env{'request.host'} || $clientip; + my $remote_ip = &Apache::lonnet::get_requestor_ip(); + $ip = $remote_ip || $env{'request.host'} || $clientip; } my $name; @@ -5227,6 +5330,17 @@ sub get_domainconf { } } } + } elsif ($key eq 'saml') { + if (ref($domconfig{'login'}{$key}) eq 'HASH') { + foreach my $host (keys(%{$domconfig{'login'}{$key}})) { + if (ref($domconfig{'login'}{$key}{$host}) eq 'HASH') { + $designhash{$udom.'.login.'.$key.'_'.$host} = 1; + foreach my $item ('text','img','alt','url','title','notsso') { + $designhash{$udom.'.login.'.$key.'_'.$item.'_'.$host} = $domconfig{'login'}{$key}{$host}{$item}; + } + } + } + } } else { foreach my $img (keys(%{$domconfig{'login'}{$key}})) { $designhash{$udom.'.login.'.$key.'_'.$img} = @@ -5331,8 +5445,12 @@ sub domainlogo { &Apache::lonnet::repcopy($local_name); } $imgsrc = &lonhttpdurl($imgsrc); - } - return ''.$domain.''; + } + my $alttext = $domain; + if ($designhash{$domain.'.login.alttext_domlogo'} ne '') { + $alttext = $designhash{$domain.'.login.alttext_domlogo'}; + } + return ''; } elsif (defined(&Apache::lonnet::domain($domain,'description'))) { return &Apache::lonnet::domain($domain,'description'); } else { @@ -5596,12 +5714,24 @@ sub bodytag { if ($realm) { $realm = '/'.$realm; } - if ($role eq 'ca') { + if ($role eq 'ca') { my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$}); $realm = &plainname($rname,$rdom); } # realm + my ($cid,$sec); if ($env{'request.course.id'}) { + $cid = $env{'request.course.id'}; + if ($env{'request.course.sec'}) { + $sec = $env{'request.course.sec'}; + } + } elsif ($realm =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$}) { + if (&Apache::lonnet::is_course($1,$2)) { + $cid = $1.'_'.$2; + $sec = $3; + } + } + if ($cid) { if ($env{'request.role'} !~ /^cr/) { $role = &Apache::lonnet::plaintext($role,&course_type()); } elsif ($role =~ m{^cr/($match_domain)/\1-domainconfig/(\w+)$}) { @@ -5613,10 +5743,10 @@ sub bodytag { } else { $role = (split(/\//,$role,4))[-1]; } - if ($env{'request.course.sec'}) { - $role .= (' 'x2).'- '.&mt('section:').' '.$env{'request.course.sec'}; + if ($sec) { + $role .= (' 'x2).'- '.&mt('section:').' '.$sec; } - $realm = $env{'course.'.$env{'request.course.id'}.'.description'}; + $realm = $env{'course.'.$cid.'.description'}; } else { $role = &Apache::lonnet::plaintext($role); } @@ -5638,15 +5768,13 @@ sub bodytag { if ($public) { undef($role); } - + my $titleinfo = '

'.$title.'

'; # # Extra info if you are the DC my $dc_info = ''; - if ($env{'user.adv'} && exists($env{'user.role.dc./'. - $env{'course.'.$env{'request.course.id'}. - '.domain'}.'/'})) { - my $cid = $env{'request.course.id'}; + if (($env{'user.adv'}) && ($env{'request.course.id'}) && + (exists($env{'user.role.dc./'.$env{'course.'.$cid.'.domain'}.'/'}))) { $dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'}; $dc_info =~ s/\s+$//; } @@ -5678,11 +5806,11 @@ sub bodytag { $bodytag .= Apache::lonhtmlcommon::scripttag( Apache::lonmenu::utilityfunctions($httphost), 'start'); - my ($left,$right) = Apache::lonmenu::primary_menu(); + my ($left,$right) = Apache::lonmenu::primary_menu($args->{'links_disabled'}); if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { if ($dc_info) { - $dc_info = qq|$dc_info|; + $dc_info = qq|$dc_info|; } $bodytag .= qq|
$left $role
$realm $dc_info
|; @@ -5706,7 +5834,7 @@ sub bodytag { } #don't show menus for public users if (!$public){ - $bodytag .= Apache::lonmenu::secondary_menu($httphost); + $bodytag .= Apache::lonmenu::secondary_menu($httphost,$args->{'links_disabled'}); $bodytag .= Apache::lonmenu::serverform(); $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); if ($env{'request.state'} eq 'construct') { @@ -5715,8 +5843,8 @@ sub bodytag { } elsif ($forcereg) { $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, $args->{'group'}, - $args->{'hide_buttons', - $hostname}); + $args->{'hide_buttons'}, + $hostname); } else { my $forbodytag; &Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, @@ -5865,6 +5993,9 @@ sub endbodytag { $endbodytag; } } + if ((ref($args) eq 'HASH') && ($args->{'dashjs'})) { + $endbodytag = &Apache::lonhtmlcommon::dash_to_minus_js().$endbodytag; + } return $endbodytag; } @@ -7824,6 +7955,18 @@ ul.LC_funclist li { cursor:pointer; } +.LCisDisabled { + cursor: not-allowed; + opacity: 0.5; +} + +a[aria-disabled="true"] { + color: currentColor; + display: inline-block; /* For IE11/ MS Edge bug */ + pointer-events: none; + text-decoration: none; +} + pre.LC_wordwrap { white-space: pre-wrap; white-space: -moz-pre-wrap; @@ -7992,10 +8135,17 @@ ADDMETA unless (&Apache::lonnet::allowed('mau',$dom_in_use)) { my %domdefs = &Apache::lonnet::get_domain_defaults($dom_in_use); my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; - my $offload; + my ($offload,$offloadoth); if (ref($domdefs{'offloadnow'}) eq 'HASH') { if ($domdefs{'offloadnow'}{$lonhost}) { $offload = 1; + if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne $dom_in_use) && + (!(($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')))) { + unless (&Apache::lonnet::shared_institution($env{'user.domain'})) { + $offloadoth = 1; + $dom_in_use = $env{'user.domain'}; + } + } } } unless ($offload) { @@ -8005,6 +8155,7 @@ ADDMETA (!(($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')))) { unless (&Apache::lonnet::shared_institution($env{'user.domain'})) { $offload = 1; + $offloadoth = 1; $dom_in_use = $env{'user.domain'}; } } @@ -8012,7 +8163,13 @@ ADDMETA } } if ($offload) { - my $newserver = &Apache::lonnet::spareserver(30000,undef,1,$dom_in_use); + my $newserver = &Apache::lonnet::spareserver(undef,30000,undef,1,$dom_in_use); + if (($newserver eq '') && ($offloadoth)) { + my @domains = &Apache::lonnet::current_machine_domains(); + if (($dom_in_use ne '') && (!grep(/^\Q$dom_in_use\E$/,@domains))) { + ($newserver) = &Apache::lonnet::choose_server($dom_in_use); + } + } if (($newserver) && ($newserver ne $lonhost)) { my $numsec = 5; my $timeout = $numsec * 1000; @@ -8026,7 +8183,7 @@ ADDMETA } if ($locknum) { my @lockinfo = sort(values(%locks)); - $msg = &mt('Once the following tasks are complete: ')."\n". + $msg = &mt('Once the following tasks are complete:')." \n". join(", ",sort(values(%locks)))."\n"; if (&show_course()) { $msg .= &mt('your session will be transferred to a different server, after you click "Courses".'); @@ -8188,7 +8345,8 @@ sub print_suppression { } my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $blocked = &blocking_status('printout',$cnum,$cdom,undef,1); + my $clientip = &Apache::lonnet::get_requestor_ip(); + my $blocked = &blocking_status('printout',$clientip,$cnum,$cdom,undef,1); if ($blocked) { my $checkrole = "cm./$cdom/$cnum"; if ($env{'request.course.sec'} ne '') { @@ -8309,6 +8467,9 @@ $args - additional optional args support will contain https:// if server uses https (as per hosts.tab), but request is for http hostname -> hostname, originally from $r->hostname(), (optional). + links_disabled -> Links in primary and secondary menus are disabled + (Can enable them once page has loaded - see lonroles.pm + for an example). =back @@ -8515,7 +8676,15 @@ ENDLINK } sub modal_adhoc_script { - my ($funcname,$width,$height,$content)=@_; + my ($funcname,$width,$height,$content,$possmathjax)=@_; + my $mathjax; + if ($possmathjax) { + $mathjax = <<'ENDJAX'; + if (typeof MathJax == 'object') { + MathJax.Hub.Queue(["Typeset",MathJax.Hub]); + } +ENDJAX + } return (< // @@ -8533,7 +8703,7 @@ ENDADHOC } sub modal_adhoc_inner { - my ($funcname,$width,$height,$content)=@_; + my ($funcname,$width,$height,$content,$possmathjax)=@_; my $innerwidth=$width-20; $content=&js_ready( &start_page('Dialog',undef,{'only_body'=>1,'bgcolor'=>'#FFFFFF'}). @@ -8542,12 +8712,12 @@ sub modal_adhoc_inner { &end_scrollbox(). &end_page() ); - return &modal_adhoc_script($funcname,$width,$height,$content); + return &modal_adhoc_script($funcname,$width,$height,$content,$possmathjax); } sub modal_adhoc_window { - my ($funcname,$width,$height,$content,$linktext)=@_; - return &modal_adhoc_inner($funcname,$width,$height,$content). + my ($funcname,$width,$height,$content,$linktext,$possmathjax)=@_; + return &modal_adhoc_inner($funcname,$width,$height,$content,$possmathjax). "".$linktext.""; } @@ -10403,11 +10573,15 @@ sub sorted_inst_types { } sub get_institutional_codes { - my ($settings,$allcourses,$LC_code) = @_; + my ($cdom,$crs,$settings,$allcourses,$LC_code) = @_; # Get complete list of course sections to update my @currsections = (); my @currxlists = (); + my (%unclutteredsec,%unclutteredlcsec); my $coursecode = $$settings{'internal.coursecode'}; + my $crskey = $crs.':'.$coursecode; + @{$unclutteredsec{$crskey}} = (); + @{$unclutteredlcsec{$crskey}} = (); if ($$settings{'internal.sectionnums'} ne '') { @currsections = split(/,/,$$settings{'internal.sectionnums'}); @@ -10418,8 +10592,8 @@ sub get_institutional_codes { } if (@currxlists > 0) { - foreach (@currxlists) { - if (m/^([^:]+):(\w*)$/) { + foreach my $xl (@currxlists) { + if ($xl =~ /^([^:]+):(\w*)$/) { unless (grep/^$1$/,@{$allcourses}) { push(@{$allcourses},$1); $$LC_code{$1} = $2; @@ -10427,15 +10601,28 @@ sub get_institutional_codes { } } } - + if (@currsections > 0) { - foreach (@currsections) { - if (m/^(\w+):(\w*)$/) { - my $sec = $coursecode.$1; + foreach my $sec (@currsections) { + if ($sec =~ m/^(\w+):(\w*)$/ ) { + my $instsec = $1; my $lc_sec = $2; - unless (grep/^$sec$/,@{$allcourses}) { + unless (grep/^\Q$instsec\E$/,@{$unclutteredsec{$crskey}}) { + push(@{$unclutteredsec{$crskey}},$instsec); + push(@{$unclutteredlcsec{$crskey}},$lc_sec); + } + } + } + } + + if (@{$unclutteredsec{$crskey}} > 0) { + my %formattedsec = &Apache::lonnet::auto_instsec_reformat($cdom,'clutter',\%unclutteredsec); + if ((ref($formattedsec{$crskey}) eq 'ARRAY') && (ref($unclutteredlcsec{$crskey}) eq 'ARRAY')) { + for (my $i=0; $i<@{$formattedsec{$crskey}}; $i++) { + my $sec = $coursecode.$formattedsec{$crskey}[$i]; + unless (grep/^\Q$sec\E$/,@{$allcourses}) { push(@{$allcourses},$sec); - $$LC_code{$sec} = $lc_sec; + $$LC_code{$sec} = $unclutteredlcsec{$crskey}[$i]; } } } @@ -14727,7 +14914,7 @@ sub recurse_categories { for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) { my $name = $cats->[$depth]{$category}[$k]; my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower; - my $trailstr = join(' -> ',(@{$parents},$category)); + my $trailstr = join(' » ',(@{$parents},$category)); if ($allitems->{$item} eq '') { push(@{$trails},$trailstr); $allitems->{$item} = scalar(@{$trails})-1; @@ -15332,8 +15519,7 @@ sub construct_course { 'plc.users.denied', 'hidefromcat', 'checkforpriv', - 'categories', - 'internal.uniquecode'], + 'categories'], $$crsudom,$$crsunum); if ($args->{'textbook'}) { $cenv{'internal.textbook'} = $args->{'textbook'}; @@ -15783,6 +15969,24 @@ sub compare_arrays { return @difference; } +sub lon_status_items { + my %defaults = ( + E => 100, + W => 4, + N => 1, + U => 5, + threshold => 200, + sysmail => 2500, + ); + my %names = ( + E => 'Errors', + W => 'Warnings', + N => 'Notices', + U => 'Unsent', + ); + return (\%defaults,\%names); +} + # -------------------------------------------------------- Initialize user login sub init_user_environment { my ($r, $username, $domain, $authhost, $form, $args) = @_; @@ -15885,6 +16089,7 @@ sub init_user_environment { # --------------------------------------------------------- Write first profile { + my $ip = &Apache::lonnet::get_requestor_ip(); my %initial_env = ("user.name" => $username, "user.domain" => $domain, @@ -15903,7 +16108,7 @@ sub init_user_environment { "request.course.sec" => '', "request.role" => 'cm', "request.role.adv" => $env{'user.adv'}, - "request.host" => $ENV{'REMOTE_ADDR'},); + "request.host" => $ip,); if ($form->{'localpath'}) { $initial_env{"browser.localpath"} = $form->{'localpath'}; @@ -17086,13 +17291,17 @@ sub create_captcha { if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') { $output = ''."\n". + ''. &mt('Type in the letters/numbers shown below').' '. ''. - '
'. + '

'. 'captcha'; last; } } + if ($output eq '') { + &Apache::lonnet::logthis("Failed to create Captcha code after $tries attempts."); + } return $output; } @@ -17131,7 +17340,8 @@ sub check_captcha { sub create_recaptcha { my ($pubkey,$version) = @_; if ($version >= 2) { - return '
'; + return '
'. + '
'; } else { my $use_ssl; if ($ENV{'SERVER_PORT'} == 443) { @@ -17149,13 +17359,14 @@ sub create_recaptcha { sub check_recaptcha { my ($privkey,$version) = @_; my $captcha_chk; + my $ip = &Apache::lonnet::get_requestor_ip(); if ($version >= 2) { my $ua = LWP::UserAgent->new; $ua->timeout(10); my %info = ( secret => $privkey, response => $env{'form.g-recaptcha-response'}, - remoteip => $ENV{'REMOTE_ADDR'}, + remoteip => $ip, ); my $response = $ua->post('https://www.google.com/recaptcha/api/siteverify',\%info); if ($response->is_success) { @@ -17171,7 +17382,7 @@ sub check_recaptcha { my $captcha_result = $captcha->check_answer( $privkey, - $ENV{'REMOTE_ADDR'}, + $ip, $env{'form.recaptcha_challenge_field'}, $env{'form.recaptcha_response_field'}, ); @@ -17222,13 +17433,16 @@ sub cleanup_html { # $interval indicates how often to check for messages. sub critical_redirect { my ($interval) = @_; + unless (($env{'user.domain'} ne '') && ($env{'user.name'} ne '')) { + return (); + } if ((time-$env{'user.criticalcheck.time'})>$interval) { my @what=&Apache::lonnet::dump('critical', $env{'user.domain'}, $env{'user.name'}); &Apache::lonnet::appenv({'user.criticalcheck.time'=>time}); my $redirecturl; if ($what[0]) { - if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) { + if (($what[0] ne 'con_lost') && ($what[0] ne 'no_such_host') && ($what[0]!~/^error\:/)) { $redirecturl='/adm/email?critical=display'; my $url=&Apache::lonnet::absolute_url().$redirecturl; return (1, $url);