--- loncom/interface/domainprefs.pm 2019/07/23 01:30:35 1.364
+++ loncom/interface/domainprefs.pm 2020/02/05 23:46:01 1.369
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set domain-wide configuration settings
#
-# $Id: domainprefs.pm,v 1.364 2019/07/23 01:30:35 raeburn Exp $
+# $Id: domainprefs.pm,v 1.369 2020/02/05 23:46:01 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -831,6 +831,7 @@ sub print_config_box {
if ($numheaders > 1) {
my $colspan = '';
my $rightcolspan = '';
+ my $leftnobr = '';
if (($action eq 'rolecolors') || ($action eq 'defaults') ||
($action eq 'directorysrch') ||
(($action eq 'login') && ($numheaders < 4))) {
@@ -839,12 +840,15 @@ sub print_config_box {
if ($action eq 'usersessions') {
$rightcolspan = ' colspan="3"';
}
+ if ($action eq 'passwords') {
+ $leftnobr = ' LC_nobreak';
+ }
$output .= '
- '.&mt($item->{'header'}->[0]->{'col1'}).'
+ '.&mt($item->{'header'}->[0]->{'col1'}).'
'.&mt($item->{'header'}->[0]->{'col2'}).'
';
$rowtotal ++;
@@ -889,6 +893,7 @@ sub print_config_box {
($action eq 'usersessions') || ($action eq 'coursecategories') ||
($action eq 'trust') || ($action eq 'contacts') ||
($action eq 'privacy') || ($action eq 'passwords')) {
+ my $leftnobr = ' LC_nobreak';
if ($action eq 'coursecategories') {
$output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
$colspan = ' colspan="2"';
@@ -956,7 +961,7 @@ sub print_config_box {
- '.&mt($item->{'header'}->[3]->{'col1'}).'
+ '.&mt($item->{'header'}->[3]->{'col1'}).'
'.&mt($item->{'header'}->[3]->{'col2'}).' '."\n";
if ($action eq 'passwords') {
$output .= $item->{'print'}->('bottom',$dom,$confname,$settings,\$rowtotal);
@@ -6056,7 +6061,7 @@ sub print_passwords {
$datatable .= ''.
' '.$usertypes->{$item}.' '.
- ' ';
+ ' ';
}
}
my $checkedcase;
@@ -6160,7 +6165,7 @@ sub print_passwords {
&mt('(If you use the same account ... reset a password from this page.)').' '.
&mt('Include custom text:');
if ($customurl) {
- my $link = &Apache::loncommon::modal_link($customurl,&mt('Custom text file'),600,500,
+ my $link = &Apache::loncommon::modal_link($customurl,&mt('custom text'),600,500,
undef,undef,undef,undef,'background-color:#ffffff');
$datatable .= ' '.$link.
' {min}) {
$min = $settings->{min};
@@ -6272,8 +6278,6 @@ sub print_passwords {
if ($settings->{numsaved}) {
$numsaved = $settings->{numsaved};
}
- } else {
- $min = '7';
}
my %rulenames = &Apache::lonlocal::texthash(
uc => 'At least one upper case letter',
@@ -6284,14 +6288,16 @@ sub print_passwords {
$css_class = $itemcount%2?' class="LC_odd_row"':'';
$datatable .= ''.$titles{'min'}.' '.
''.
- ' '.
- ' '.&mt('(Leave blank for no minimum)').' '.
+ ' '.
+ ' '.&mt('(Enter an integer: 7 or larger)').' '.
' ';
$itemcount ++;
$css_class = $itemcount%2?' class="LC_odd_row"':'';
$datatable .= ''.$titles{'max'}.' '.
''.
- ' '.
+ ' '.
' '.&mt('(Leave blank for no maximum)').' '.
' ';
$itemcount ++;
@@ -6331,14 +6337,16 @@ sub print_passwords {
$css_class = $itemcount%2?' class="LC_odd_row"':'';
$datatable .= ''.$titles{'expire'}.' '.
''.
- ' '.
+ ' '.
' '.&mt('(Leave blank for no expiration)').' '.
' ';
$itemcount ++;
$css_class = $itemcount%2?' class="LC_odd_row"':'';
$datatable .= ''.$titles{'numsaved'}.' '.
''.
- ' '.
+ ' '.
' '.&mt('(Leave blank to not save previous passwords)').' '.
' ';
} else {
@@ -6384,7 +6392,7 @@ sub print_passwords {
$datatable .= ''.
' '.$usertypes->{$type}.' '.
- ' ';
+ ' ';
}
}
my $checked;
@@ -9295,16 +9303,22 @@ ENDSCRIPT
}
sub passwords_javascript {
- 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 %intalert = &Apache::lonlocal::texthash (
+ authcheck => '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.',
+ authcost => 'Warning: bcrypt encryption cost for internal authentication must be an integer.',
+ passmin => 'Warning: minimum password length must be a positive integer greater than 6.',
+ passmax => 'Warning: maximum password length must be a positive integer (or blank).',
+ passexp => 'Warning: days before password expiration must be a positive integer (or blank).',
+ passnum => 'Warning: number of previous passwords to save must be a positive integer (or blank).',
+ );
+ &js_escape(\%intalert);
+ my $defmin = $Apache::lonnet::passwdmin;
my $intauthjs = <<"ENDSCRIPT";
function warnIntAuth(field) {
if (field.name == 'intauth_check') {
if (field.value == '2') {
- alert('$intauthcheck');
+ alert('$intalert{authcheck}');
}
}
if (field.name == 'intauth_cost') {
@@ -9312,7 +9326,60 @@ function warnIntAuth(field) {
if (field.value != '') {
var regexdigit=/^\\d+\$/;
if (!regexdigit.test(field.value)) {
- alert('$intauthcost');
+ alert('$intalert{authcost}');
+ }
+ }
+ }
+ return;
+}
+
+function warnIntPass(field) {
+ field.value.replace(/^\s+/,'');
+ field.value.replace(/\s+\$/,'');
+ var regexdigit=/^\\d+\$/;
+ if (field.name == 'passwords_min') {
+ if (field.value == '') {
+ alert('$intalert{passmin}');
+ field.value = '$defmin';
+ } else {
+ if (!regexdigit.test(field.value)) {
+ alert('$intalert{passmin}');
+ field.value = '$defmin';
+ }
+ var minval = parseInt(field.value,10);
+ if (minval < $defmin) {
+ alert('$intalert{passmin}');
+ field.value = '$defmin';
+ }
+ }
+ } else {
+ if (field.value == '0') {
+ field.value = '';
+ }
+ if (field.value != '') {
+ if (field.name == 'passwords_expire') {
+ var regexpposnum=/^\\d+(|\\.\\d*)\$/;
+ if (!regexpposnum.test(field.value)) {
+ alert('$intalert{passexp}');
+ field.value = '';
+ } else {
+ var expval = parseFloat(field.value);
+ if (expval == 0) {
+ alert('$intalert{passexp}');
+ field.value = '';
+ }
+ }
+ } else {
+ if (!regexdigit.test(field.value)) {
+ if (field.name == 'passwords_max') {
+ alert('$intalert{passmax}');
+ } else {
+ if (field.name == 'passwords_numsaved') {
+ alert('$intalert{passnum}');
+ }
+ }
+ }
+ field.value = '';
}
}
}
@@ -14490,8 +14557,8 @@ sub modify_passwords {
'intauth_cost' => 10,
'intauth_check' => 0,
'intauth_switch' => 0,
- 'min' => 7,
);
+ $staticdefaults{'min'} = $Apache::lonnet::passwdmin;
foreach my $type (@oktypes) {
$staticdefaults{'resetpostlink'}{$type} = ['email','username'];
}
@@ -14503,7 +14570,7 @@ sub modify_passwords {
if ($current{'resetlink'} ne $linklife) {
$changes{'reset'} = 1;
}
- } elsif (!exists($domconfig{passwords})) {
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
if ($staticdefaults{'resetlink'} ne $linklife) {
$changes{'reset'} = 1;
}
@@ -14524,7 +14591,7 @@ sub modify_passwords {
if (@diffs > 0) {
$changes{'reset'} = 1;
}
- } elsif (!exists($domconfig{passwords})) {
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetcase'},\@casesens);
if (@diffs > 0) {
$changes{'reset'} = 1;
@@ -14536,7 +14603,7 @@ sub modify_passwords {
if ($current{'resetprelink'} ne $newvalues{'resetprelink'}) {
$changes{'reset'} = 1;
}
- } elsif (!exists($domconfig{passwords})) {
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
if ($staticdefaults{'resetprelink'} ne $newvalues{'resetprelink'}) {
$changes{'reset'} = 1;
}
@@ -14563,7 +14630,7 @@ sub modify_passwords {
} else {
$changes{'reset'} = 1;
}
- } elsif (!exists($domconfig{passwords})) {
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetpostlink'}{$type},\@postlink);
if (@diffs > 0) {
$changes{'reset'} = 1;
@@ -14585,7 +14652,7 @@ sub modify_passwords {
if (@diffs > 0) {
$changes{'reset'} = 1;
}
- } elsif (!exists($domconfig{passwords})) {
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetemail'},\@resetemail);
if (@diffs > 0) {
$changes{'reset'} = 1;
@@ -14672,10 +14739,18 @@ sub modify_passwords {
$env{'form.passwords_'.$rule} =~ s/^\s+|\s+$//g;
my $ruleok;
if ($rule eq 'expire') {
- if ($env{'form.passwords_'.$rule} =~ /^\d+(|\.\d*)$/) {
+ if (($env{'form.passwords_'.$rule} =~ /^\d+(|\.\d*)$/) &&
+ ($env{'form.passwords_'.$rule} ne '0')) {
$ruleok = 1;
}
- } elsif ($env{'form.passwords_'.$rule} =~ /^\d+$/) {
+ } elsif ($rule eq 'min') {
+ if ($env{'form.passwords_'.$rule} =~ /^\d+$/) {
+ if ($env{'form.passwords_'.$rule} >= $Apache::lonnet::passwdmin) {
+ $ruleok = 1;
+ }
+ }
+ } elsif (($env{'form.passwords_'.$rule} =~ /^\d+$/) &&
+ ($env{'form.passwords_'.$rule} ne '0')) {
$ruleok = 1;
}
if ($ruleok) {
@@ -14736,7 +14811,7 @@ sub modify_passwords {
}
}
}
- } elsif (!exists($domconfig{passwords})) {
+ } elsif (!(ref($domconfig{passwords}) eq 'HASH')) {
foreach my $item ('by','for') {
if (@{$crsownerchg{$item}} > 0) {
$changes{'crsownerchg'} = 1;
@@ -14766,9 +14841,11 @@ sub modify_passwords {
$resulttext .= ''.&mt('CAPTCHA validation set to use: original CAPTCHA').' ';
} elsif ($confighash{'passwords'}{'captcha'} eq 'recaptcha') {
$resulttext .= ''.&mt('CAPTCHA validation set to use: reCAPTCHA').' '.
- &mt('version: [_1]',$confighash{'passwords'}{'recaptchaversion'}).' '.
- &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchapub'}).''.
- &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchapriv'}).' ';
+ &mt('version: [_1]',$confighash{'passwords'}{'recaptchaversion'}).' ';
+ if (ref($confighash{'passwords'}{'recaptchakeys'}) eq 'HASH') {
+ $resulttext .= &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchakeys'}{'public'}).''.
+ &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchakeys'}{'private'}).'';
+ }
} else {
$resulttext .= ''.&mt('No CAPTCHA validation').' ';
}
@@ -14847,8 +14924,9 @@ sub modify_passwords {
}
if ($confighash{'passwords'}{'resetcustom'}) {
my $customlink = &Apache::loncommon::modal_link($confighash{'passwords'}{'resetcustom'},
- $titles{custom},600,500);
- $resulttext .= ''.&mt('Preamble to "Forgot Password" form includes [_1]',$customlink).' ';
+ &mt('custom text'),600,500,undef,undef,
+ undef,undef,'background-color:#ffffff');
+ $resulttext .= ''.&mt('Preamble to "Forgot Password" form includes: [_1]',$customlink).' ';
} else {
$resulttext .= ''.&mt('No custom text included in preamble to "Forgot Password" form').' ';
}
@@ -14885,7 +14963,8 @@ sub modify_passwords {
if ($confighash{'passwords'}{$rule} eq '') {
if ($rule eq 'min') {
$resulttext .= ''.&mt('[_1] not set.',$titles{$rule});
- ' '.&mt('Default of 7 will be used').' ';
+ ' '.&mt('Default of [_1] will be used',
+ $Apache::lonnet::passwdmin).'';
} else {
$resulttext .= ''.&mt('[_1] set to none',$titles{$rule}).' ';
}
@@ -16032,19 +16111,25 @@ sub modify_selfcreation {
}
sub process_captcha {
- my ($container,$changes,$newsettings,$current) = @_;
- return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH') || (ref($current) eq 'HASH'));
+ my ($container,$changes,$newsettings,$currsettings) = @_;
+ return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH'));
$newsettings->{'captcha'} = $env{'form.'.$container.'_captcha'};
unless ($newsettings->{'captcha'} eq 'recaptcha' || $newsettings->{'captcha'} eq 'notused') {
$newsettings->{'captcha'} = 'original';
}
- if ($current->{'captcha'} ne $newsettings->{'captcha'}) {
+ my %current;
+ if (ref($currsettings) eq 'HASH') {
+ %current = %{$currsettings};
+ }
+ if ($current{'captcha'} ne $newsettings->{'captcha'}) {
if ($container eq 'cancreate') {
if (ref($changes->{'cancreate'}) eq 'ARRAY') {
push(@{$changes->{'cancreate'}},'captcha');
} elsif (!defined($changes->{'cancreate'})) {
$changes->{'cancreate'} = ['captcha'];
}
+ } elsif ($container eq 'passwords') {
+ $changes->{'reset'} = 1;
} else {
$changes->{'captcha'} = 1;
}
@@ -16066,9 +16151,9 @@ sub process_captcha {
}
$newsettings->{'recaptchaversion'} = $newversion;
}
- if (ref($current->{'recaptchakeys'}) eq 'HASH') {
- $currpub = $current->{'recaptchakeys'}{'public'};
- $currpriv = $current->{'recaptchakeys'}{'private'};
+ if (ref($current{'recaptchakeys'}) eq 'HASH') {
+ $currpub = $current{'recaptchakeys'}{'public'};
+ $currpriv = $current{'recaptchakeys'}{'private'};
unless ($newsettings->{'captcha'} eq 'recaptcha') {
$newsettings->{'recaptchakeys'} = {
public => '',
@@ -16076,8 +16161,8 @@ sub process_captcha {
}
}
}
- if ($current->{'captcha'} eq 'recaptcha') {
- $currversion = $current->{'recaptchaversion'};
+ if ($current{'captcha'} eq 'recaptcha') {
+ $currversion = $current{'recaptchaversion'};
if ($currversion ne '2') {
$currversion = 1;
}
@@ -16089,6 +16174,8 @@ sub process_captcha {
} elsif (!defined($changes->{'cancreate'})) {
$changes->{'cancreate'} = ['recaptchaversion'];
}
+ } elsif ($container eq 'passwords') {
+ $changes->{'reset'} = 1;
} else {
$changes->{'recaptchaversion'} = 1;
}
@@ -16100,6 +16187,8 @@ sub process_captcha {
} elsif (!defined($changes->{'cancreate'})) {
$changes->{'cancreate'} = ['recaptchakeys'];
}
+ } elsif ($container eq 'passwords') {
+ $changes->{'reset'} = 1;
} else {
$changes->{'recaptchakeys'} = 1;
}