--- loncom/interface/domainprefs.pm 2021/04/18 02:08:46 1.381 +++ loncom/interface/domainprefs.pm 2021/09/01 00:21:52 1.385 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.381 2021/04/18 02:08:46 raeburn Exp $ +# $Id: domainprefs.pm,v 1.385 2021/09/01 00:21:52 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -223,7 +223,7 @@ sub handler { 'ltitools','ssl','trust','lti','privacy','passwords', 'proctoring','wafproxy'],$dom); my %encconfig = - &Apache::lonnet::get_dom('encconfig',['ltitools','lti','proctoring'],$dom); + &Apache::lonnet::get_dom('encconfig',['ltitools','lti','proctoring'],$dom,undef,1); if (ref($domconfig{'ltitools'}) eq 'HASH') { if (ref($encconfig{'ltitools'}) eq 'HASH') { foreach my $id (keys(%{$domconfig{'ltitools'}})) { @@ -857,6 +857,8 @@ sub print_config_box { $output .= &proctoring_javascript($settings); } elsif ($action eq 'wafproxy') { $output .= &wafproxy_javascript($dom); + } elsif ($action eq 'autoupdate') { + $output .= &autoupdate_javascript(); } $output .= ' @@ -3311,6 +3313,41 @@ function toggleLTI(form,setting,item) { ENDSCRIPT } +sub autoupdate_javascript { + return <<"ENDSCRIPT"; + + +ENDSCRIPT +} + sub print_autoenroll { my ($dom,$settings,$rowtotal) = @_; my $autorun = &Apache::lonnet::auto_run(undef,$dom), @@ -3397,42 +3434,69 @@ sub print_autoenroll { sub print_autoupdate { my ($position,$dom,$settings,$rowtotal) = @_; - my $datatable; + my ($enable,$datatable); if ($position eq 'top') { + my %choices = &Apache::lonlocal::texthash ( + run => 'Auto-update active?', + classlists => 'Update information in classlists?', + unexpired => 'Skip updates for users without active or future roles?', + lastactive => 'Skip updates for inactive users?', + ); + my $itemcount = 0; my $updateon = ' '; my $updateoff = ' checked="checked" '; - my $classlistson = ' '; - my $classlistsoff = ' checked="checked" '; if (ref($settings) eq 'HASH') { if ($settings->{'run'} eq '1') { $updateon = $updateoff; $updateoff = ' '; } - if ($settings->{'classlists'} eq '1') { - $classlistson = $classlistsoff; - $classlistsoff = ' '; - } } - my %title = ( - run => 'Auto-update active?', - classlists => 'Update information in classlists?', - ); - $datatable = ''. - ''. - ''. + ''. + ''. - ''. - ''. - ''. + $updateon.'value="1" />'.&mt('Yes').''. ''; - $$rowtotal += 2; + my @toggles = ('classlists','unexpired'); + my %defaultchecked = ('classlists' => 'off', + 'unexpired' => 'off' + ); + $$rowtotal ++; + ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, + \%choices,$itemcount,'','','left','no'); + $datatable = $enable.$datatable; + $$rowtotal += $itemcount; + my $lastactiveon = ' '; + my $lastactiveoff = ' checked="checked" '; + my $lastactivestyle = 'none'; + my $lastactivedays; + my $onclick = ' onclick="javascript:toggleLastActiveDays(this.form);"'; + if (ref($settings) eq 'HASH') { + if ($settings->{'lastactive'} =~ /^\d+$/) { + $lastactiveon = $lastactiveoff; + $lastactiveoff = ' '; + $lastactivestyle = 'inline-block'; + $lastactivedays = $settings->{'lastactive'}; + } + } + my $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''. + ''. + ''; + $$rowtotal ++; } elsif ($position eq 'middle') { my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); my $numinrow = 3; @@ -4561,7 +4625,7 @@ sub helpdeskroles_access { sub radiobutton_prefs { my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick, - $additional,$align) = @_; + $additional,$align,$firstval) = @_; return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') && (ref($choices) eq 'HASH')); @@ -4601,15 +4665,21 @@ sub radiobutton_prefs { } else { $datatable .= ''. - ''; + $datatable .= ''; + if ($firstval eq 'no') { + $datatable .= + ' '; + } else { + $datatable .= + ' '; + } + $datatable .= ''.$additional.''; $itemcount ++; } return ($datatable,$itemcount); @@ -7337,12 +7407,10 @@ sub print_wafproxy { foreach my $domain (keys(%otherdoms)) { %{$values{$domain}} = (); my %config = &Apache::lonnet::get_dom('configuration',['wafproxy'],$domain); - if (ref($config{$domain}) eq 'HASH') { - if (ref($config{$domain}{'wafproxy'}) eq 'HASH') { - $aliases{$domain} = $config{$domain}{'wafproxy'}{'alias'}; - foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext') { - $values{$domain}{$item} = $config{$domain}{'wafproxy'}{$item}; - } + if (ref($config{'wafproxy'}) eq 'HASH') { + $aliases{$domain} = $config{'wafproxy'}{'alias'}; + foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext') { + $values{$domain}{$item} = $config{'wafproxy'}{$item}; } } } @@ -7354,22 +7422,25 @@ sub print_wafproxy { $itemcount ++; my $dom_in_effect; my $aliasrows = ''. - ''; + ''; if ($othercontrol{$server}) { $dom_in_effect = $othercontrol{$server}; my $current; - if (ref($aliases{$othercontrol{$server}}) eq 'HASH') { - $current = $aliases{$othercontrol{$server}{$server}}; + if (ref($aliases{$dom_in_effect}) eq 'HASH') { + $current = $aliases{$dom_in_effect}{$server}; } + $aliasrows .= ''; + $aliasrows .= ' ('. + &mt('controlled by domain: [_1]', + ''.$dom_in_effect.'').')'; } else { $dom_in_effect = $dom; my $current; @@ -7378,7 +7449,8 @@ sub print_wafproxy { $current = $aliases{$dom}{$server}; } } - $aliasrows .= ''; } @@ -7408,27 +7480,29 @@ sub print_wafproxy { '
'.&mt($title{'run'}).'
'.$choices{'run'}.' '. + $updateoff.' value="0" />'.&mt('No').' '. '
'.&mt($title{'classlists'}).''. - ' '. - '
'.$choices{'lastactive'}.''. + ' '. + '
'. + ': '.&mt('inactive = no activity in last [_1] days', + ''). + '
'; } - $datatable .= - ''. - ' '. - ''.$additional. - '
'.&mt('Hostname').': '. - &Apache::lonnet::hostname($server).''. + &mt('Hostname').': '. + ''.&Apache::lonnet::hostname($server).' '. + &mt('Alias').': '; if ($current) { $aliasrows .= $current; } else { - $aliasrows .= &mt('None in effect'); + $aliasrows .= &mt('None'); } - $aliasrows .= '('. - &mt('WAF/Reverse Proxy controlled by domain: [_1]', - ''.$othercontrol{$server}.'').''.&mt('WAF/Reverse Proxy Alias').': '. + $aliasrows .= ''. + &mt('Alias').': '. '
'; $itemcount++; } - if (keys(%othercontrol)) { - foreach my $key (sort(keys(%othercontrol))) { + if (keys(%otherdoms)) { + foreach my $key (sort(keys(%otherdoms))) { $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - $datatable = ''. - ''.&mt('Domain: [_1]',''.$key.'').''. - ''.$aliasinfo{$key}. - '
'; + $datatable .= ''. + ''.&mt('Domain: [_1]',''.$key.'').''. + ''.$aliasinfo{$key}. + '
'; $itemcount++; } } } else { + my %ip_methods = &remoteip_methods(); if ($setdom) { $itemcount ++; $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; my ($nowafstyle,$wafstyle,$curr_remotip,$currwafdisplay,$vpndircheck,$vpnaliascheck, - $currwafvpn,$wafrangestyle); + $currwafvpn,$wafrangestyle,$alltossl,$ssltossl); $wafstyle = ' style="display:none;"'; $nowafstyle = ' style="display:table-row;"'; $currwafdisplay = ' style="display: none"'; $wafrangestyle = ' style="display: none"'; $curr_remotip = 'n'; + $ssltossl = ' checked="checked"'; if ($showdom) { $wafstyle = ' style="display:table-row;"'; $nowafstyle = ' style="display:none;"'; @@ -7440,6 +7514,10 @@ sub print_wafproxy { $currwafdisplay = ' style="display:table-row"'; $wafrangestyle = ' style="display:inline-block;"'; } + if ($values{$dom}{'sslopt'}) { + $alltossl = ' checked="checked"'; + $ssltossl = ''; + } } if (($values{$dom}{'vpnint'} ne '') || ($values{$dom}{'vpnext'} ne '')) { $vpndircheck = ' checked="checked"'; @@ -7462,7 +7540,6 @@ sub print_wafproxy { ''. ''.$lt{'remoteip'}.': '. ''. ''."\n". @@ -7491,24 +7568,39 @@ sub print_wafproxy { $lt{'vpnaliased'}.''; foreach my $item ('vpnint','vpnext') { $datatable .= ''. - ''.$lt{$item}.': '. + ''.$lt{$item}.':
'. ''. ''."\n"; } - $datatable .= ''; + $datatable .= '
'."\n". + ''. + ''.$lt{'sslopt'}.':
'. + ''.(' 'x2). + ''."\n". + ''; } if (keys(%otherdoms)) { foreach my $domain (sort(keys(%otherdoms))) { $itemcount ++; $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; $datatable .= ''. - ''.&mt('Domain: [_1]',$domain).''. + ''.&mt('Domain: [_1]',''.$domain.'').''. ''; - foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext') { + foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext','sslopt') { my $showval = &mt('None'); + if ($item eq 'ssl') { + $showval = $lt{'ssltossl'}; + } if ($values{$domain}{$item}) { $showval = $values{$domain}{$item}; + if ($item eq 'ssl') { + $showval = $lt{'alltossl'}; + } elsif ($item eq 'remoteip') { + $showval = $ip_methods{$values{$domain}{$item}}; + } } $datatable .= ''. ''; @@ -7531,7 +7623,7 @@ sub wafproxy_titles { vpnaliased => 'via aliased hostname (WAF)', vpnint => 'Internal IP Range(s) for VPN sessions', vpnext => 'IP Range(s) for backend WAF connections', - ssloptions => 'Forwarding http/https', + sslopt => 'Forwarding http/https', alltossl => 'WAF forwards both http and https requests to https', ssltossl => 'WAF forwards http requests to http and https to https', ); @@ -13505,7 +13597,7 @@ sub modify_ltitools { my %ltienchash = ( $action => { %encconfig } ); - &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom); + &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom,undef,1); if (keys(%changes) > 0) { my $cachetime = 24*60*60; my %ltiall = %confhash; @@ -14079,7 +14171,7 @@ sub modify_proctoring { my %proc_enchash = ( $action => { %encconfhash } ); - &Apache::lonnet::put_dom('encconfig',\%proc_enchash,$dom); + &Apache::lonnet::put_dom('encconfig',\%proc_enchash,$dom,undef,1); if (keys(%changes) > 0) { my $cachetime = 24*60*60; my %procall = %confhash; @@ -14571,7 +14663,7 @@ sub modify_lti { my %ltienchash = ( $action => { %encconfig } ); - &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom); + &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom,undef,1); if (keys(%changes) > 0) { my $cachetime = 24*60*60; my %ltiall = %confhash; @@ -14913,8 +15005,10 @@ sub modify_autoupdate { } my @offon = ('off','on'); my %title = &Apache::lonlocal::texthash ( - run => 'Auto-update:', - classlists => 'Updates to user information in classlists?' + run => 'Auto-update:', + classlists => 'Updates to user information in classlists?', + unexpired => 'Skip updates for users without active or future roles?', + lastactive => 'Skip updates for inactive users?', ); my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); my %fieldtitles = &Apache::lonlocal::texthash ( @@ -14958,12 +15052,23 @@ sub modify_autoupdate { my %updatehash = ( autoupdate => { run => $env{'form.autoupdate_run'}, classlists => $env{'form.classlists'}, + unexpired => $env{'form.unexpired'}, fields => {%fields}, lockablenames => \@lockablenames, } ); + my $lastactivedays; + if ($env{'form.lastactive'}) { + $lastactivedays = $env{'form.lastactivedays'}; + $lastactivedays =~ s/^\s+|\s+$//g; + unless ($lastactivedays =~ /^\d+$/) { + undef($lastactivedays); + $env{'form.lastactive'} = 0; + } + } + $updatehash{'autoupdate'}{'lastactive'} = $lastactivedays; foreach my $key (keys(%currautoupdate)) { - if (($key eq 'run') || ($key eq 'classlists')) { + if (($key eq 'run') || ($key eq 'classlists') || ($key eq 'unexpired') || ($key eq 'lastactive')) { if (exists($updatehash{autoupdate}{$key})) { if ($currautoupdate{$key} ne $updatehash{autoupdate}{$key}) { $changes{$key} = 1; @@ -15009,6 +15114,16 @@ sub modify_autoupdate { $changes{'lockablenames'} = 1; } } + unless (grep(/^unexpired$/,keys(%currautoupdate))) { + if ($updatehash{'autoupdate'}{'unexpired'}) { + $changes{'unexpired'} = 1; + } + } + unless (grep(/^lastactive$/,keys(%currautoupdate))) { + if ($updatehash{'autoupdate'}{'lastactive'} ne '') { + $changes{'lastactive'} = 1; + } + } foreach my $item (@{$types},'default') { if (defined($fields{$item})) { if (ref($currautoupdate{'fields'}) eq 'HASH') { @@ -15071,6 +15186,11 @@ sub modify_autoupdate { my $newvalue; if ($key eq 'run') { $newvalue = $offon[$env{'form.autoupdate_run'}]; + } elsif ($key eq 'lastactive') { + $newvalue = $offon[$env{'form.lastactive'}]; + unless ($lastactivedays eq '') { + $newvalue .= '; '.&mt('inactive = no activity in last [quant,_1,day]',$lastactivedays); + } } else { $newvalue = $offon[$env{'form.'.$key}]; } @@ -19826,7 +19946,7 @@ sub modify_wafproxy { if (ref($domconfig{'wafproxy'}{'alias'}) eq 'HASH') { %curralias = %{$domconfig{'wafproxy'}{'alias'}}; } - foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext') { + foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext','sslopt') { $currvalue{$item} = $domconfig{'wafproxy'}{$item}; } } @@ -19862,7 +19982,7 @@ sub modify_wafproxy { vpnint => 'internal IP range(s) for VPN sessions(s)', vpnext => 'IP range(s) for backend WAF connections', ); - foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext') { + foreach my $item ('remoteip','ipheader','trusted','vpnint','vpnext','sslopt') { my $possible = $env{'form.wafproxy_'.$item}; $possible =~ s/^\s+|\s+$//g; if ($possible ne '') { @@ -19874,6 +19994,10 @@ sub modify_wafproxy { if ($wafproxy{'remoteip'} eq 'h') { $wafproxy{$item} = $possible; } + } elsif ($item eq 'sslopt') { + if ($possible =~ /^0|1$/) { + $wafproxy{$item} = $possible; + } } else { my (@ok,$count); if (($item eq 'vpnint') || ($item eq 'vpnext')) { @@ -19936,7 +20060,7 @@ sub modify_wafproxy { if ($putresult eq 'ok') { my $cachetime = 24*60*60; my (%domdefaults,$updatedomdefs); - foreach my $item ('ipheader','trusted','vpnint','vpnext') { + foreach my $item ('ipheader','trusted','vpnint','vpnext','sslopt') { if ($changes{$item}) { unless ($updatedomdefs) { %domdefaults = &Apache::lonnet::get_domain_defaults($dom); @@ -19973,7 +20097,7 @@ sub modify_wafproxy { } } $output = &mt('Changes were made to Web Application Firewall/Reverse Proxy').'
    '; - foreach my $item ('alias','remoteip','ipheader','trusted','vpnint','vpnext') { + foreach my $item ('alias','remoteip','ipheader','trusted','vpnint','vpnext','sslopt') { if ($changes{$item}) { if ($item eq 'alias') { my $numaliased = 0; @@ -20037,6 +20161,12 @@ sub modify_wafproxy { } else { $output .= '
  • '.&mt('IP Range(s) for backend WAF connections deleted').'
  • '; } + } elsif ($item eq 'sslopt') { + if ($wafproxy{$item}) { + $output .= '
  • '.&mt('WAF/Reverse Proxy expected to forward requests to https on LON-CAPA node, regardless of original protocol in web browser (http or https).').'
  • '; + } else { + $output .= '
  • '.&mt('WAF/Reverse Proxy expected to preserve original protocol in web browser (either http or https) when forwarding to LON-CAPA node.').'
  • '; + } } } }
'.$lt{$item}.': '.$showval.'