--- loncom/interface/domainprefs.pm 2017/01/30 19:18:33 1.160.6.79 +++ loncom/interface/domainprefs.pm 2018/09/02 15:22:28 1.160.6.87 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.160.6.79 2017/01/30 19:18:33 raeburn Exp $ +# $Id: domainprefs.pm,v 1.160.6.87 2018/09/02 15:22:28 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -262,6 +262,8 @@ sub handler { help => 'Domain_Configuration_LangTZAuth', header => [{col1 => 'Setting', col2 => 'Value'}, + {col1 => 'Internal Authentication', + col2 => 'Value'}, {col1 => 'Institutional user types', col2 => 'Assignable to e-mail usernames'}], print => \&print_defaults, @@ -618,7 +620,7 @@ sub process_changes { } elsif ($action eq 'autocreate') { $output = &modify_autocreate($dom,%domconfig); } elsif ($action eq 'directorysrch') { - $output = &modify_directorysrch($dom,%domconfig); + $output = &modify_directorysrch($dom,$lastactref,%domconfig); } elsif ($action eq 'usercreation') { $output = &modify_usercreation($dom,%domconfig); } elsif ($action eq 'selfcreation') { @@ -744,7 +746,7 @@ sub print_config_box { if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'coursecategories') || - ($action eq 'contacts')) { + ($action eq 'contacts') || ($action eq 'defaults')) { if ($action eq 'coursecategories') { $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); $colspan = ' colspan="2"'; @@ -1276,7 +1278,7 @@ sub print_login { } else { $datatable .= ''; } - $datatable .= ''; + $datatable .= ''; } $datatable .= ''; } @@ -1436,7 +1438,7 @@ sub display_color_options { my $datatable = ''. ''.$choices->{'font'}.''; if (!$is_custom->{'font'}) { - $datatable .= ''.&mt('Default in use:').' '.$defaults->{'font'}.''; + $datatable .= ''.&mt('Default in use:').' '.$defaults->{'font'}.''; } else { $datatable .= ' '; } @@ -1445,12 +1447,12 @@ sub display_color_options { $datatable .= ''. ' '. - ' '; + ' '; unless ($role eq 'login') { $datatable .= ''. ''.$choices->{'fontmenu'}.''; if (!$is_custom->{'fontmenu'}) { - $datatable .= ''.&mt('Default in use:').' '.$defaults->{'fontmenu'}.''; + $datatable .= ''.&mt('Default in use:').' '.$defaults->{'fontmenu'}.''; } else { $datatable .= ' '; } @@ -1460,7 +1462,7 @@ sub display_color_options { ' '. - ' '; + ' '; } my $switchserver = &check_switchserver($dom,$confname); foreach my $img (@{$images}) { @@ -1577,7 +1579,7 @@ sub display_color_options { my $bgs_def; foreach my $item (@{$bgs}) { if (!$is_custom->{$item}) { - $bgs_def .= ''.$choices->{$item}.'    
'.$defaults->{'bgs'}{$item}.''; + $bgs_def .= ''.$choices->{$item}.'    
'.$defaults->{'bgs'}{$item}.''; } } if ($bgs_def) { @@ -1605,7 +1607,7 @@ sub display_color_options { my $links_def; foreach my $item (@{$links}) { if (!$is_custom->{$item}) { - $links_def .= ''.$choices->{$item}.'
'.$defaults->{'links'}{$item}.''; + $links_def .= ''.$choices->{$item}.'
'.$defaults->{'links'}{$item}.''; } } if ($links_def) { @@ -1691,17 +1693,15 @@ sub image_changes { my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_; my $output; if ($img eq 'login') { - # suppress image for Log-in header + $output = ''.$logincolors; # suppress image for Log-in header } elsif (!$is_custom) { if ($img ne 'domlogo') { - $output .= &mt('Default image:').'
'; + $output = &mt('Default image:').'
'; } else { - $output .= &mt('Default in use:').'
'; + $output = &mt('Default in use:').'
'; } } - if ($img eq 'login') { # suppress image for Log-in header - $output .= ''.$logincolors; - } else { + if ($img ne 'login') { if ($img_import) { $output .= ''; } @@ -2312,7 +2312,7 @@ sub print_textbookcourses { $datatable .= ''; } $datatable .= ' '."\n". - ''.&mt('Add').''."\n". + ''.&mt('Add').''."\n". ''. ''.&mt('Subject:').' '."\n". (' 'x2). @@ -2329,13 +2329,13 @@ sub print_textbookcourses { } else { $datatable .= ''; } + $datatable .= ''."\n"; } - $datatable .= ''."\n". - ''.&mt('LON-CAPA course:').' '. + $datatable .= ''.&mt('LON-CAPA course:').' '. &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom'). ''. &Apache::loncommon::selectcourse_link - ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course'); + ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course'). ''."\n". ''."\n"; $itemcount ++; @@ -2514,7 +2514,7 @@ sub print_autoenroll { ''.&mt('Failsafe for no drops when institutional data missing').''. ''. ''; + ' value="'.$failsafe.'" size="4" />'; $$rowtotal += 4; return $datatable; } @@ -2941,7 +2941,7 @@ sub print_contacts { 'value="'.$bccemails{$type}.'" />'. '
'.&mt('Optional added text').''. &mt('Text automatically added to e-mail:').' '. - '
'. + '
'. ''.&mt('Location:').' '. ''. (' 'x2). @@ -3002,7 +3002,7 @@ sub print_contacts { if ($currfield{$field} eq 'no') { $display = ' style="display:none"'; } - $datatable .= ''. + $datatable .= ''. ''.&mt('Maximum size for upload (MB)').''. ''; } @@ -3060,8 +3060,10 @@ sub print_helpsettings { my $css_class; my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_'); my (%customroles,%ordered,%current); - if (ref($settings->{'adhoc'}) eq 'HASH') { - %current = %{$settings->{'adhoc'}}; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'adhoc'}) eq 'HASH') { + %current = %{$settings->{'adhoc'}}; + } } my $count = 0; foreach my $key (sort(keys(%existing))) { @@ -3097,7 +3099,7 @@ sub print_helpsettings { @jsarray = ('bystatus'); } } - my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh'.'da']); + my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']); if (keys(%domhelpdesk)) { push(@accesstypes,('inc','exc')); push(@jsarray,('notinc','notexc')); @@ -3206,7 +3208,9 @@ sub print_helpsettings { \@templateroles,$newcust). &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels, \%levelscurrent,$newcust). - '
'; + ''. + &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname). + ''; $count ++; $$rowtotal += $count; } @@ -3725,7 +3729,7 @@ sub print_coursedefaults { foreach my $type (@types) { $datatable .= ''.&mt($type).'
'. ''; + ' value="'.$currmysql{$type}.'" size="8" />'; } $datatable .= ''."\n"; $itemcount ++; @@ -3923,7 +3927,7 @@ sub print_validation_rows { '
'; } } elsif ($item eq 'markup') { - $datatable .= ''; } @@ -3945,7 +3949,7 @@ sub print_validation_rows { my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio', 'validationdc',%currhash); my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - $datatable .= ''; + $datatable .= ''; if ($numdc > 1) { $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)'); } else { @@ -5038,7 +5042,7 @@ sub print_selfcreation { $datatable .= ''. ''.&mt('Mapping of Shibboleth environment variable names to user data fields (SSO auth)').''. ''."\n". - '
'."\n"; + ''."\n"; for (my $i=0; $i<@fields; $i++) { $rem = $i%($numperrow); if ($rem == 0) { @@ -5402,7 +5406,10 @@ sub print_usermodification { sub print_defaults { my ($position,$dom,$settings,$rowtotal) = @_; my $rownum = 0; - my ($datatable,$css_class); + my ($datatable,$css_class,$titles); + unless ($position eq 'bottom') { + $titles = &defaults_titles($dom); + } if ($position eq 'top') { my @items = ('auth_def','auth_arg_def','lang_def','timezone_def', 'datelocale_def','portal_def'); @@ -5415,7 +5422,6 @@ sub print_defaults { $defaults{$item} = $domdefaults{$item}; } } - my $titles = &defaults_titles($dom); foreach my $item (@items) { if ($rownum%2) { $css_class = ''; @@ -5463,8 +5469,87 @@ sub print_defaults { $datatable .= ''; $rownum ++; } + } elsif ($position eq 'middle') { + my @items = ('intauth_cost','intauth_check','intauth_switch'); + my %defaults; + if (ref($settings) eq 'HASH') { + %defaults = %{$settings}; + if ($defaults{'intauth_cost'} !~ /^\d+$/) { + $defaults{'intauth_cost'} = 10; + } + if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) { + $defaults{'intauth_check'} = 0; + } + if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) { + $defaults{'intauth_switch'} = 0; + } + } else { + %defaults = ( + 'intauth_cost' => 10, + 'intauth_check' => 0, + 'intauth_switch' => 0, + ); + } + foreach my $item (@items) { + if ($rownum%2) { + $css_class = ''; + } else { + $css_class = ' class="LC_odd_row" '; + } + $datatable .= ''. + ''; + $rownum ++; + } } else { - my (%defaults); + my %defaults; if (ref($settings) eq 'HASH') { if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') && (ref($settings->{'inststatusguest'}) eq 'ARRAY')) { @@ -5559,6 +5644,9 @@ sub defaults_titles { 'timezone_def' => 'Default timezone', 'datelocale_def' => 'Default locale for dates', 'portal_def' => 'Portal/Default URL', + 'intauth_cost' => 'Encryption cost for bcrypt (positive integer)', + 'intauth_check' => 'Check bcrypt cost if authenticated', + 'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication', ); if ($dom) { my $uprimary_id = &Apache::lonnet::domain($dom,'primary'); @@ -5788,7 +5876,7 @@ sub print_coursecategories { ''.$lt{$type}.' '; } - $datatable .= ''; + $datatable .= ''; $itemcount ++; } $$rowtotal += $itemcount; @@ -5999,7 +6087,7 @@ sub print_coursecategories { $datatable .= &initialize_categories($itemcount); } } else { - $datatable .= '' + $datatable .= '' .&initialize_categories($itemcount); } $$rowtotal += $itemcount; @@ -6047,7 +6135,7 @@ sub print_serverstatuses { ''. ''. - ''."\n"; + ''."\n"; } $$rowtotal += $rownum; return $datatable; @@ -6062,7 +6150,35 @@ sub serverstatus_pages { sub defaults_javascript { my ($settings) = @_; - return unless (ref($settings) eq 'HASH'); + my $intauthcheck = &mt('Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.'); + my $intauthcost = &mt('Warning: bcrypt encryption cost for internal authentication must be an integer.'); + &js_escape(\$intauthcheck); + &js_escape(\$intauthcost); + my $intauthjs = <<"ENDSCRIPT"; + +function warnIntAuth(field) { + if (field.name == 'intauth_check') { + if (field.value == '2') { + alert('$intauthcheck'); + } + } + if (field.name == 'intauth_cost') { + field.value.replace(/\s/g,''); + if (field.value != '') { + var regexdigit=/^\\d+\$/; + if (!regexdigit.test(field.value)) { + alert('$intauthcost'); + } + } + } + return; +} + +ENDSCRIPT + + if (ref($settings) ne 'HASH') { + return &Apache::lonhtmlcommon::scripttag($intauthjs); + } if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) { my $maxnum = scalar(@{$settings->{'inststatusorder'}}); if ($maxnum eq '') { @@ -6116,10 +6232,14 @@ $jstext return; } +$intauthjs + // ]]> ENDSCRIPT + } else { + return &Apache::lonhtmlcommon::scripttag($intauthjs); } } @@ -6240,7 +6360,7 @@ sub initialize_categories { my $select1 = ''; foreach my $default ('instcode','communities') { $css_class = $itemcount%2?' class="LC_odd_row"':''; - $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"'; + $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','0'".');"'; if ($default eq 'communities') { $select1 = $select0; $select0 = ''; @@ -6265,8 +6385,9 @@ sub initialize_categories { .'' .'' .' ' - .&mt('Add category').''; + .&mt('Add category').'>'.&mt('Name:') + .' ' + .''; return $datatable; } @@ -6321,7 +6442,7 @@ sub build_category_rows { pop(@{$path}); } } else { - $text .= &mt('Add subcategory:').' '.&mt('Add subcategory:').''; + $text .= ''; } } } @@ -6539,7 +6660,7 @@ sub insttypes_row { $rem = @{$types}%($numinrow); } my $colsleft = $numinrow - $rem; - if (($rem == 0) && (@{$types} > 0)) { + if ($rem == 0) { $output .= ''; } if ($colsleft > 1) { @@ -8644,9 +8765,9 @@ sub modify_autoenroll { } if ($changes{'autofailsafe'}) { if ($failsafe ne '') { - $resulttext .= '
  • '.&mt("$title{'failsafe'} set to [_1]",$failsafe).'
  • '; + $resulttext .= '
  • '.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'
  • '; } else { - $resulttext .= '
  • '.&mt("$title{'failsafe'} deleted"); + $resulttext .= '
  • '.&mt('Failsafe for no drops if institutional data missing for a section: deleted'); } &Apache::lonnet::get_domain_defaults($dom,1); if (ref($lastactref) eq 'HASH') { @@ -8925,7 +9046,7 @@ sub modify_autocreate { } sub modify_directorysrch { - my ($dom,%domconfig) = @_; + my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,%changes); my %currdirsrch; if (ref($domconfig{'directorysrch'}) eq 'HASH') { @@ -9119,6 +9240,10 @@ sub modify_directorysrch { $resulttext .= '
  • '.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'
  • '; } $resulttext .= ''; + &Apache::lonnet::do_cache_new('directorysrch',$dom,$dirsrch_hash{'directorysrch'},3600); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'directorysrch'} = 1; + } } else { $resulttext = &mt('No changes made to directory search settings'); } @@ -10008,7 +10133,7 @@ sub modify_selfcreation { $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'}; } $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'}; - $save_usercreate{'emailrule'} = \@email_rule; + $save_usercreate{'email_rule'} = \@email_rule; my %userconfig_hash = ( usercreation => \%save_usercreate, @@ -10444,7 +10569,8 @@ sub modify_defaults { my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors); my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); - my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def','portal_def'); + my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def', + 'portal_def','intauth_cost','intauth_check','intauth_switch'); my @authtypes = ('internal','krb4','krb5','localauth'); foreach my $item (@items) { $newvalues{$item} = $env{'form.'.$item}; @@ -10486,6 +10612,24 @@ sub modify_defaults { push(@errors,$item); } } + } elsif ($item eq 'intauth_cost') { + if ($newvalues{$item} ne '') { + if ($newvalues{$item} =~ /\D/) { + push(@errors,$item); + } + } + } elsif ($item eq 'intauth_check') { + if ($newvalues{$item} ne '') { + unless ($newvalues{$item} =~ /^(0|1|2)$/) { + push(@errors,$item); + } + } + } elsif ($item eq 'intauth_switch') { + if ($newvalues{$item} ne '') { + unless ($newvalues{$item} =~ /^(0|1|2)$/) { + push(@errors,$item); + } + } } if (grep(/^\Q$item\E$/,@errors)) { $newvalues{$item} = $domdefaults{$item}; @@ -10640,6 +10784,28 @@ sub modify_defaults { localauth => 'loc', ); $value = $authnames{$shortauth{$value}}; + } elsif ($item eq 'intauth_switch') { + my %optiondesc = &Apache::lonlocal::texthash ( + 0 => 'No', + 1 => 'Yes', + 2 => 'Yes, and copy existing passwd file to passwd.bak file', + ); + if ($value =~ /^(0|1|2)$/) { + $value = $optiondesc{$value}; + } else { + $value = &mt('none -- defaults to No'); + } + } elsif ($item eq 'intauth_check') { + my %optiondesc = &Apache::lonlocal::texthash ( + 0 => 'No', + 1 => 'Yes, allow login then update passwd file using default cost (if higher)', + 2 => 'Yes, disallow login if stored cost is less than domain default', + ); + if ($value =~ /^(0|1|2)$/) { + $value = $optiondesc{$value}; + } else { + $value = &mt('none -- defaults to No'); + } } $resulttext .= '
  • '.&mt('[_1] set to "[_2]"',$title->{$item},$value).'
  • '; $mailmsgtext .= "$title->{$item} set to $value\n"; @@ -11400,7 +11566,7 @@ sub modify_helpsettings { order => 'Order', desc => 'Role description', access => 'Role usage', - status => 'Allowed instituional types', + status => 'Allowed institutional types', exc => 'Allowed personnel', inc => 'Disallowed personnel', ); @@ -12316,8 +12482,10 @@ sub modify_usersessions { } my $cachetime = 24*60*60; &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600); if (ref($lastactref) eq 'HASH') { $lastactref->{'domdefaults'} = 1; + $lastactref->{'usersessions'} = 1; } if (keys(%changes) > 0) { my %lt = &usersession_titles(); @@ -13401,7 +13569,7 @@ sub devalidate_remote_domconfs { my %servers = &Apache::lonnet::internet_dom_servers($dom); my %thismachine; map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); - my @posscached = ('domainconfig','domdefaults'); + my @posscached = ('domainconfig','domdefaults','usersessions','directorysrch'); if (keys(%servers)) { foreach my $server (keys(%servers)) { next if ($thismachine{$server});
    '.$titles->{$item}. + ''; + if ($item eq 'intauth_switch') { + my @options = (0,1,2); + my %optiondesc = &Apache::lonlocal::texthash ( + 0 => 'No', + 1 => 'Yes', + 2 => 'Yes, and copy existing passwd file to passwd.bak file', + ); + $datatable .= ''; + foreach my $option (@options) { + my $checked = ' '; + if ($defaults{$item} eq $option) { + $checked = ' checked="checked"'; + } + $datatable .= ''; + } + $datatable .= '
    '. + '
    '; + } elsif ($item eq 'intauth_check') { + my @options = (0,1,2); + my %optiondesc = &Apache::lonlocal::texthash ( + 0 => 'No', + 1 => 'Yes, allow login then update passwd file using default cost (if higher)', + 2 => 'Yes, disallow login if stored cost is less than domain default', + ); + $datatable .= ''; + foreach my $option (@options) { + my $checked = ' '; + my $onclick; + if ($defaults{$item} eq $option) { + $checked = ' checked="checked"'; + } + if ($option == 2) { + $onclick = ' onclick="javascript:warnIntAuth(this);"'; + } + $datatable .= ''; + } + $datatable .= '
    '. + '
    '; + } else { + $datatable .= ''; + } + $datatable .= '
    '.$hdritem->{'header'}->[1]->{'col2'}.'
    '.$hdritem->{'header'}->[1]->{'col2'}.'
    '.&mt('Name:') - .' 
    '.&mt('Add subcategory:').'