'.
''.&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) {
@@ -5072,150 +5912,430 @@ sub print_selfcreation {
$$rowtotal ++;
} elsif ($position eq 'middle') {
my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
- my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
- $usertypes->{'default'} = $othertitle;
+ my @posstypes;
if (ref($types) eq 'ARRAY') {
- push(@{$types},'default');
- $usertypes->{'default'} = $othertitle;
- foreach my $status (@{$types}) {
- $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
- $numinrow,$$rowtotal,$usertypes);
- $$rowtotal ++;
- }
+ @posstypes = @{$types};
+ }
+ unless (grep(/^default$/,@posstypes)) {
+ push(@posstypes,'default');
+ }
+ my %usertypeshash;
+ if (ref($usertypes) eq 'HASH') {
+ %usertypeshash = %{$usertypes};
+ }
+ $usertypeshash{'default'} = $othertitle;
+ foreach my $status (@posstypes) {
+ $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
+ $numinrow,$$rowtotal,\%usertypeshash);
+ $$rowtotal ++;
}
} else {
my %choices = &Apache::lonlocal::texthash (
- cancreate_email => 'E-mail address as username',
+ 'cancreate_email' => 'Non-institutional username (via e-mail verification)',
);
my @toggles = sort(keys(%choices));
my %defaultchecked = (
'cancreate_email' => 'off',
);
- my $itemcount = 0;
+ my $customclass = 'LC_selfcreate_email';
+ my $classprefix = 'LC_canmodify_emailusername_';
+ my $optionsprefix = 'LC_options_emailusername_';
my $display = 'none';
+ my $rowstyle = 'display:none';
if (grep(/^\Qemail\E$/,@selfcreate)) {
$display = 'block';
+ $rowstyle = 'display:table-row';
}
- my $onclick = "toggleDisplay(this.form,'emailoptions');";
- my $additional = '';
+ my $onclick = "toggleRows(this.form,'cancreate_email','selfassign','$customclass','$classprefix','$optionsprefix');";
+ ($datatable,$$rowtotal) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
+ \%choices,$$rowtotal,$onclick);
+ $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal,$customclass,
+ $rowstyle);
+ $$rowtotal ++;
+ $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal,$customclass,
+ $rowstyle);
+ $$rowtotal ++;
+ my (@ordered,@posstypes,%usertypeshash);
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
- my $usertypes = {};
- my $order = [];
- if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) {
- $usertypes = $domdefaults{'inststatustypes'};
- $order = $domdefaults{'inststatusguest'};
- }
- if (ref($order) eq 'ARRAY') {
- push(@{$order},'default');
- if (@{$order} > 1) {
- $usertypes->{'default'} = &mt('Other users');
- $additional .= ' ';
- foreach my $status (@{$order}) {
- $additional .= ''.$usertypes->{$status}.' | ';
- }
- $additional .= ' ';
- foreach my $status (@{$order}) {
- $additional .= ''.&email_as_username($rowtotal,$processing,$status).' | ';
+ my ($emailrules,$emailruleorder) =
+ &Apache::lonnet::inst_userrules($dom,'email');
+ my $primary_id = &Apache::lonnet::domain($dom,'primary');
+ my $intdom = &Apache::lonnet::internet_dom($primary_id);
+ if (ref($types) eq 'ARRAY') {
+ @posstypes = @{$types};
+ }
+ if (@posstypes) {
+ unless (grep(/^default$/,@posstypes)) {
+ push(@posstypes,'default');
+ }
+ if (ref($usertypes) eq 'HASH') {
+ %usertypeshash = %{$usertypes};
+ }
+ my $currassign;
+ if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {
+ $currassign = {
+ selfassign => $domdefaults{'inststatusguest'},
+ };
+ @ordered = @{$domdefaults{'inststatusguest'}};
+ } else {
+ $currassign = { selfassign => [] };
+ }
+ my $onclicktypes = "toggleDataRow(this.form,'selfassign','$customclass','$optionsprefix',);".
+ "toggleDataRow(this.form,'selfassign','$customclass','$classprefix',1);";
+ $datatable .= &insttypes_row($currassign,$types,$usertypes,$dom,
+ $numinrow,$othertitle,'selfassign',
+ $rowtotal,$onclicktypes,$customclass,
+ $rowstyle);
+ $$rowtotal ++;
+ $usertypeshash{'default'} = $othertitle;
+ foreach my $status (@posstypes) {
+ my $css_class;
+ if ($$rowtotal%2) {
+ $css_class = 'LC_odd_row ';
+ }
+ $css_class .= $customclass;
+ my $rowid = $optionsprefix.$status;
+ my $hidden = 1;
+ my $currstyle = 'display:none';
+ if (grep(/^\Q$status\E$/,@ordered)) {
+ $currstyle = $rowstyle;
+ $hidden = 0;
+ }
+ $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
+ $emailrules,$emailruleorder,$settings,$status,$rowid,
+ $usertypeshash{$status},$css_class,$currstyle,$intdom);
+ unless ($hidden) {
+ $$rowtotal ++;
}
- $additional .= '
';
- } else {
- $usertypes->{'default'} = &mt('All users');
- $additional .= &email_as_username($rowtotal,$processing);
}
+ } else {
+ my $css_class;
+ if ($$rowtotal%2) {
+ $css_class = 'LC_odd_row ';
+ }
+ $css_class .= $customclass;
+ $usertypeshash{'default'} = $othertitle;
+ $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
+ $emailrules,$emailruleorder,$settings,'default','',
+ $othertitle,$css_class,$rowstyle,$intdom);
+ $$rowtotal ++;
}
- $additional .= ' '."\n";
-
- ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
- \%choices,$$rowtotal,$onclick,$additional);
- $$rowtotal ++;
- $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal);
- $$rowtotal ++;
my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
$numinrow = 1;
- if (ref($order) eq 'ARRAY') {
- foreach my $status (@{$order}) {
+ if (@posstypes) {
+ foreach my $status (@posstypes) {
+ my $rowid = $classprefix.$status;
+ my $datarowstyle = 'display:none';
+ if (grep(/^\Q$status\E$/,@ordered)) {
+ $datarowstyle = $rowstyle;
+ }
$datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
- $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles);
- $$rowtotal ++;
+ $numinrow,$$rowtotal,\%usertypeshash,$infofields,
+ $infotitles,$rowid,$customclass,$datarowstyle);
+ unless ($datarowstyle eq 'display:none') {
+ $$rowtotal ++;
+ }
}
+ } else {
+ $datatable .= &modifiable_userdata_row('cancreate','emailusername_default',$settings,
+ $numinrow,$$rowtotal,\%usertypeshash,$infofields,
+ $infotitles,'',$customclass,$rowstyle);
}
- my ($emailrules,$emailruleorder) =
- &Apache::lonnet::inst_userrules($dom,'email');
- if (ref($emailrules) eq 'HASH') {
- if (keys(%{$emailrules}) > 0) {
- $datatable .= &user_formats_row('email',$settings,$emailrules,
- $emailruleorder,$numinrow,$$rowtotal);
- $$rowtotal ++;
+ }
+ return $datatable;
+}
+
+sub selfcreate_javascript {
+ return <<"ENDSCRIPT";
+
+
+
+ENDSCRIPT
+}
+
+sub noninst_users {
+ my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,
+ $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_;
+ my $class = 'LC_left_item';
+ if ($css_class) {
+ $css_class = ' class="'.$css_class.'"';
+ }
+ if ($rowid) {
+ $rowid = ' id="'.$rowid.'"';
+ }
+ if ($rowstyle) {
+ $rowstyle = ' style="'.$rowstyle.'"';
+ }
+ my ($output,$description);
+ if ($type eq 'default') {
+ $description = &mt('Requests for: [_1]',$typetitle);
+ } else {
+ $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);
+ }
+ $output = ''.
+ "$description | \n".
+ ''.
+ '';
+ my %headers = &Apache::lonlocal::texthash(
+ approve => 'Processing',
+ email => 'E-mail',
+ username => 'Username',
+ );
+ foreach my $item ('approve','email','username') {
+ $output .= ''.$headers{$item}.' | ';
+ }
+ $output .= ' ';
+ foreach my $item ('approve','email','username') {
+ $output .= '';
+ my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);
+ if ($item eq 'approve') {
+ %choices = &Apache::lonlocal::texthash (
+ automatic => 'Automatically approved',
+ approval => 'Queued for approval',
+ );
+ @options = ('automatic','approval');
+ $hashref = $processing;
+ $defoption = 'automatic';
+ $name = 'cancreate_emailprocess_'.$type;
+ } elsif ($item eq 'email') {
+ %choices = &Apache::lonlocal::texthash (
+ any => 'Any e-mail',
+ inst => 'Institutional only',
+ noninst => 'Non-institutional only',
+ custom => 'Custom restrictions',
+ );
+ @options = ('any','inst','noninst');
+ my $showcustom;
+ if (ref($emailrules) eq 'HASH') {
+ if (keys(%{$emailrules}) > 0) {
+ push(@options,'custom');
+ $showcustom = 'cancreate_emailrule';
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{'email_rule'}) eq 'ARRAY') {
+ foreach my $rule (@{$settings->{'email_rule'}}) {
+ if (exists($emailrules->{$rule})) {
+ $hascustom ++;
+ }
+ }
+ } elsif (ref($settings->{'email_rule'}) eq 'HASH') {
+ if (ref($settings->{'email_rule'}{$type}) eq 'ARRAY') {
+ foreach my $rule (@{$settings->{'email_rule'}{$type}}) {
+ if (exists($emailrules->{$rule})) {
+ $hascustom ++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ $onclick = ' onclick="toggleEmailOptions(this.form,'."'cancreate_emailoptions','$showcustom',".
+ "'cancreate_emaildomain','$type'".');"';
+ $hashref = $emailoptions;
+ $defoption = 'any';
+ $name = 'cancreate_emailoptions_'.$type;
+ } elsif ($item eq 'username') {
+ %choices = &Apache::lonlocal::texthash (
+ all => 'Same as e-mail',
+ first => 'Omit @domain',
+ free => 'Free to choose',
+ );
+ @options = ('all','first','free');
+ $hashref = $emailverified;
+ $defoption = 'all';
+ $name = 'cancreate_usernameoptions_'.$type;
+ }
+ foreach my $option (@options) {
+ my $checked;
+ if (ref($hashref) eq 'HASH') {
+ if ($type eq '') {
+ if (!exists($hashref->{'default'})) {
+ if ($option eq $defoption) {
+ $checked = ' checked="checked"';
+ }
+ } else {
+ if ($hashref->{'default'} eq $option) {
+ $checked = ' checked="checked"';
+ }
}
} else {
- if ($processing->{$type} eq $option) {
- $checked = ' checked="checked"';
+ if (!exists($hashref->{$type})) {
+ if ($option eq $defoption) {
+ $checked = ' checked="checked"';
+ }
+ } else {
+ if ($hashref->{$type} eq $option) {
+ $checked = ' checked="checked"';
+ }
}
}
+ } elsif (($item eq 'email') && ($hascustom)) {
+ if ($option eq 'custom') {
+ $checked = ' checked="checked"';
+ }
+ } elsif ($option eq $defoption) {
+ $checked = ' checked="checked"';
+ }
+ $output .= ' ';
+ if ($item eq 'email') {
+ if ($option eq 'custom') {
+ my $id = 'cancreate_emailrule_'.$type;
+ my $display = 'none';
+ if ($checked) {
+ $display = 'inline';
+ }
+ my $numinrow = 2;
+ $output .= '';
+ } elsif (($option eq 'inst') || ($option eq 'noninst')) {
+ my %text = &Apache::lonlocal::texthash (
+ inst => 'must end:',
+ noninst => 'cannot end:',
+ );
+ my $value;
+ if (ref($emaildomain) eq 'HASH') {
+ if (ref($emaildomain->{$type}) eq 'HASH') {
+ $value = $emaildomain->{$type}->{$option};
+ }
+ }
+ if ($value eq '') {
+ $value = '@'.$intdom;
+ }
+ my $condition = 'cancreate_emaildomain_'.$option.'_'.$type;
+ my $display = 'none';
+ if ($checked) {
+ $display = 'inline';
+ }
+ $output .= ''.
+ ''.$text{$option}.' '.
+ ''.
+ ' ';
+ }
}
- } elsif ($option eq 'automatic') {
- $checked = ' checked="checked"';
- }
- my $name = 'cancreate_emailprocess';
- if (($type ne '') && ($type ne 'default')) {
- $name .= '_'.$type;
- }
- $output .= '';
- if ($type eq '') {
- $output .= ' ';
- } else {
- $output .= ' ';
}
+ $output .= ' | '."\n";
}
- $$rowtotal ++;
+ $output .= "
| \n";
return $output;
}
sub captcha_choice {
- my ($context,$settings,$itemcount) = @_;
+ my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;
my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,
$vertext,$currver);
my %lt = &captcha_phrases();
$keyentry = 'hidden';
+ my $colspan=2;
if ($context eq 'cancreate') {
$rowname = &mt('CAPTCHA validation');
} elsif ($context eq 'login') {
$rowname = &mt('"Contact helpdesk" CAPTCHA validation');
+ } elsif ($context eq 'passwords') {
+ $rowname = &mt('"Forgot Password" CAPTCHA validation');
+ $colspan=1;
}
if (ref($settings) eq 'HASH') {
if ($settings->{'captcha'}) {
@@ -5240,9 +6360,22 @@ sub captcha_choice {
} else {
$checked{'original'} = ' checked="checked"';
}
- my $css_class = $itemcount%2?' class="LC_odd_row"':'';
+ my $css_class;
+ if ($itemcount%2) {
+ $css_class = 'LC_odd_row';
+ }
+ if ($customcss) {
+ $css_class .= " $customcss";
+ }
+ $css_class =~ s/^\s+//;
+ if ($css_class) {
+ $css_class = ' class="'.$css_class.'"';
+ }
+ if ($rowstyle) {
+ $css_class .= ' style="'.$rowstyle.'"';
+ }
my $output = ''.
- ''.$rowname.' | '."\n".
+ ' | '.$rowname.' | '."\n".
''."\n";
foreach my $option ('original','recaptcha','notused') {
$output .= ' | ';
}
$css_class = $rownum%2?' class="LC_odd_row"':'';
my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';
@@ -5606,13 +6656,8 @@ sub print_defaults {
''.
' '.&mt('(new)').
''.
- &mt('Name displayed:').
+ &mt('Name displayed').
' | '.
- ''.
- ''.
- &mt('Yes').''.(' 'x2).
- ''.
- &mt('No').' | ';
''."\n";
$rownum ++;
}
@@ -5659,6 +6704,58 @@ sub defaults_titles {
return (\%titles);
}
+sub print_scantron {
+ my ($r,$position,$dom,$confname,$settings,$rowtotal) = @_;
+ if ($position eq 'top') {
+ return &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
+ } else {
+ return &print_scantronconfig($dom,$settings,\$rowtotal);
+ }
+}
+
+sub scantron_javascript {
+ return <<"ENDSCRIPT";
+
+
+
+ENDSCRIPT
+
+}
+
sub print_scantronformat {
my ($r,$dom,$confname,$settings,$rowtotal) = @_;
my $itemcount = 1;
@@ -5685,8 +6782,8 @@ sub print_scantronformat {
if ($configuserok eq 'ok') {
if ($author_ok eq 'ok') {
my %legacyfile = (
- default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab',
- custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab',
+ default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab',
+ custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab',
);
my %md5chk;
foreach my $type (keys(%legacyfile)) {
@@ -5695,7 +6792,7 @@ sub print_scantronformat {
}
if ($md5chk{'default'} ne $md5chk{'custom'}) {
foreach my $type (keys(%legacyfile)) {
- ($scantronurls{$type},my $error) =
+ ($scantronurls{$type},my $error) =
&legacy_scantronformat($r,$dom,$confname,
$type,$legacyfile{$type},
$scantronurls{$type},
@@ -5706,13 +6803,13 @@ sub print_scantronformat {
}
if (keys(%error) == 0) {
$is_custom = 1;
- $confhash{'scantron'}{'scantronformat'} =
+ $confhash{'scantron'}{'scantronformat'} =
$scantronurls{'custom'};
- my $putresult =
+ my $putresult =
&Apache::lonnet::put_dom('configuration',
\%confhash,$dom);
if ($putresult ne 'ok') {
- $error{'custom'} =
+ $error{'custom'} =
''.
&mt('An error occurred updating the domain configuration: [_1]',$putresult).'';
}
@@ -5832,6 +6929,129 @@ sub legacy_scantronformat {
return ($url,$error);
}
+sub print_scantronconfig {
+ my ($dom,$settings,$rowtotal) = @_;
+ my $itemcount = 2;
+ my $is_checked = ' checked="checked"';
+ my %optionson = (
+ hdr => ' checked="checked"',
+ pad => ' checked="checked"',
+ rem => ' checked="checked"',
+ );
+ my %optionsoff = (
+ hdr => '',
+ pad => '',
+ rem => '',
+ );
+ my $currcsvsty = 'none';
+ my ($datatable,%csvfields,%checked,%onclick,%csvoptions);
+ my @fields = &scantroncsv_fields();
+ my %titles = &scantronconfig_titles();
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{config}) eq 'HASH') {
+ if ($settings->{config}->{dat}) {
+ $checked{'dat'} = $is_checked;
+ }
+ if (ref($settings->{config}->{csv}) eq 'HASH') {
+ if (ref($settings->{config}->{csv}->{fields}) eq 'HASH') {
+ %csvfields = %{$settings->{config}->{csv}->{fields}};
+ if (keys(%csvfields) > 0) {
+ $checked{'csv'} = $is_checked;
+ $currcsvsty = 'block';
+ }
+ }
+ if (ref($settings->{config}->{csv}->{options}) eq 'HASH') {
+ %csvoptions = %{$settings->{config}->{csv}->{options}};
+ foreach my $option (keys(%optionson)) {
+ unless ($csvoptions{$option}) {
+ $optionsoff{$option} = $optionson{$option};
+ $optionson{$option} = '';
+ }
+ }
+ }
+ }
+ } else {
+ $checked{'dat'} = $is_checked;
+ }
+ } else {
+ $checked{'dat'} = $is_checked;
+ }
+ $onclick{'csv'} = ' onclick="toggleScantron(this.form);"';
+ my $css_class = $itemcount%2? ' class="LC_odd_row"':'';
+ $datatable = ''.&mt('Supported formats').' | '.
+ '';
+ foreach my $item ('dat','csv') {
+ my $id;
+ if ($item eq 'csv') {
+ $id = 'id="scantronconfcsv" ';
+ }
+ $datatable .= ''.
+ $titles{$item}.''.(' 'x3);
+ if ($item eq 'csv') {
+ $datatable .= ''.
+ '';
+ $itemcount ++;
+ }
+ }
+ $datatable .= ' | ';
+ $$rowtotal ++;
+ return $datatable;
+}
+
+sub scantronconfig_titles {
+ return &Apache::lonlocal::texthash(
+ dat => 'Standard format (.dat)',
+ csv => 'Comma separated values (.csv)',
+ hdr => 'Remove first line in file (contains column titles)',
+ pad => 'Prepend 0s to PaperID',
+ rem => 'Remove leading spaces (except Question Response columns)',
+ CODE => 'CODE',
+ ID => 'Student ID',
+ PaperID => 'Paper ID',
+ FirstName => 'First Name',
+ LastName => 'Last Name',
+ FirstQuestion => 'First Question Response',
+ Section => 'Section',
+ );
+}
+
+sub scantroncsv_fields {
+ return ('PaperID','LastName','FirstName','ID','Section','CODE','FirstQuestion');
+}
+
sub print_coursecategories {
my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;
my $datatable;
@@ -5874,7 +7094,7 @@ sub print_coursecategories {
''.$lt{$type}.' ';
}
- $datatable .= '';
+ $datatable .= '';
$itemcount ++;
}
$$rowtotal += $itemcount;
@@ -6085,7 +7305,7 @@ sub print_coursecategories {
$datatable .= &initialize_categories($itemcount);
}
} else {
- $datatable .= ''.$hdritem->{'header'}->[1]->{'col2'}.' | '
+ $datatable .= ''.$hdritem->{'header'}->[1]->{'col2'}.' | '
.&initialize_categories($itemcount);
}
$$rowtotal += $itemcount;
@@ -6133,7 +7353,7 @@ sub print_serverstatuses {
''.
''.
- ''."\n";
+ ''."\n";
}
$$rowtotal += $rownum;
return $datatable;
@@ -6148,35 +7368,7 @@ sub serverstatus_pages {
sub defaults_javascript {
my ($settings) = @_;
- 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);
- }
+ return unless (ref($settings) eq 'HASH');
if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
my $maxnum = scalar(@{$settings->{'inststatusorder'}});
if ($maxnum eq '') {
@@ -6230,15 +7422,99 @@ $jstext
return;
}
-$intauthjs
-
// ]]>
ENDSCRIPT
+ }
+}
+
+sub passwords_javascript {
+ 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('$intalert{authcheck}');
+ }
+ }
+ if (field.name == 'intauth_cost') {
+ field.value.replace(/\s/g,'');
+ if (field.value != '') {
+ var regexdigit=/^\\d+\$/;
+ if (!regexdigit.test(field.value)) {
+ 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 {
- return &Apache::lonhtmlcommon::scripttag($intauthjs);
+ 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 = '';
+ }
+ }
+ }
}
+ return;
+}
+
+ENDSCRIPT
+ return &Apache::lonhtmlcommon::scripttag($intauthjs);
}
sub coursecategories_javascript {
@@ -6350,7 +7626,7 @@ ENDSCRIPT
sub initialize_categories {
my ($itemcount) = @_;
my ($datatable,$css_class,$chgstr);
- my %default_names = (
+ my %default_names = &Apache::lonlocal::texthash (
instcode => 'Official courses (with institutional codes)',
communities => 'Communities',
);
@@ -6358,7 +7634,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 = '';
@@ -6383,8 +7659,9 @@ sub initialize_categories {
.''
.''
.' '
- .&mt('Add category').''.&mt('Name:')
- .' | ';
+ .&mt('Add category').''.&mt('Name:')
+ .' '
+ .' | ';
return $datatable;
}
@@ -6439,7 +7716,7 @@ sub build_category_rows {
pop(@{$path});
}
} else {
- $text .= &mt('Add subcategory:').' '.&mt('Add subcategory:').'';
+ $text .= ''.&mt('Add subcategory:').' | ';
}
}
}
@@ -6471,13 +7748,14 @@ sub build_category_rows {
}
sub modifiable_userdata_row {
- my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_;
+ my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,
+ $rowid,$customcss,$rowstyle) = @_;
my ($role,$rolename,$statustype);
$role = $item;
if ($context eq 'cancreate') {
- if ($item =~ /^emailusername_(.+)$/) {
- $statustype = $1;
- $role = 'emailusername';
+ if ($item =~ /^(emailusername)_(.+)$/) {
+ $role = $1;
+ $statustype = $2;
if (ref($usertypes) eq 'HASH') {
if ($usertypes->{$statustype}) {
$rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});
@@ -6512,8 +7790,25 @@ sub modifiable_userdata_row {
%fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
}
my $output;
- my $css_class = $rowcount%2?' class="LC_odd_row"':'';
- $output = ''.
+ my $css_class;
+ if ($rowcount%2) {
+ $css_class = 'LC_odd_row';
+ }
+ if ($customcss) {
+ $css_class .= " $customcss";
+ }
+ $css_class =~ s/^\s+//;
+ if ($css_class) {
+ $css_class = ' class="'.$css_class.'"';
+ }
+ if ($rowstyle) {
+ $css_class .= ' style="'.$rowstyle.'"';
+ }
+ if ($rowid) {
+ $rowid = ' id="'.$rowid.'"';
+ }
+
+ $output = ' '.
''.$rolename.' | '.
'';
my $rem;
@@ -6547,9 +7842,10 @@ sub modifiable_userdata_row {
}
}
}
-
- for (my $i=0; $i<@fields; $i++) {
- my $rem = $i%($numinrow);
+
+ my $total = scalar(@fields);
+ for (my $i=0; $i<$total; $i++) {
+ $rem = $i%($numinrow);
if ($rem == 0) {
if ($i > 0) {
$output .= '';
@@ -6559,7 +7855,7 @@ sub modifiable_userdata_row {
my $check = ' ';
unless ($role eq 'emailusername') {
if (exists($checks{$fields[$i]})) {
- $check = $checks{$fields[$i]}
+ $check = $checks{$fields[$i]};
} else {
if ($role eq 'st') {
if (ref($settings) ne 'HASH') {
@@ -6591,10 +7887,13 @@ sub modifiable_userdata_row {
'';
}
$output .= '';
- $rem = @fields%($numinrow);
}
- my $colsleft = $numinrow - $rem;
- if ($colsleft > 1 ) {
+ $rem = $total%$numinrow;
+ my $colsleft;
+ if ($rem) {
+ $colsleft = $numinrow - $rem;
+ }
+ if ($colsleft > 1) {
$output .= ''.
' | ';
} elsif ($colsleft == 1) {
@@ -6605,11 +7904,14 @@ sub modifiable_userdata_row {
}
sub insttypes_row {
- my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_;
+ my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,
+ $customcss,$rowstyle) = @_;
my %lt = &Apache::lonlocal::texthash (
cansearch => 'Users allowed to search',
statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
lockablenames => 'User preference to lock name',
+ selfassign => 'Self-reportable affiliations',
+ overrides => "Override domain's helpdesk settings based on requester's affiliation",
);
my $showdom;
if ($context eq 'cansearch') {
@@ -6619,9 +7921,22 @@ sub insttypes_row {
if ($context eq 'statustocreate') {
$class = 'LC_right_item';
}
- my $css_class = ' class="LC_odd_row"';
- if ($rownum ne '') {
- $css_class = ($rownum%2? ' class="LC_odd_row"':'');
+ my $css_class;
+ if ($$rowtotal%2) {
+ $css_class = 'LC_odd_row';
+ }
+ if ($customcss) {
+ $css_class .= ' '.$customcss;
+ }
+ $css_class =~ s/^\s+//;
+ if ($css_class) {
+ $css_class = ' class="'.$css_class.'"';
+ }
+ if ($rowstyle) {
+ $css_class .= ' style="'.$rowstyle.'"';
+ }
+ if ($onclick) {
+ $onclick = 'onclick="'.$onclick.'" ';
}
my $output = ''.
''.$lt{$context}.$showdom.
@@ -6643,6 +7958,10 @@ sub insttypes_row {
if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
$check = ' checked="checked" ';
}
+ } elsif (ref($settings->{$context}) eq 'HASH') {
+ if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {
+ $check = ' checked="checked" ';
+ }
} elsif ($context eq 'statustocreate') {
$check = ' checked="checked" ';
}
@@ -6650,36 +7969,45 @@ sub insttypes_row {
$output .= ' | '.
''.
'[$i].'"'.$check.'/>'.
+ 'value="'.$types->[$i].'"'.$check.$onclick.'/>'.
$usertypes->{$types->[$i]}.' | ';
}
}
$rem = @{$types}%($numinrow);
}
my $colsleft = $numinrow - $rem;
- if (($rem == 0) && (@{$types} > 0)) {
- $output .= ' ';
- }
- if ($colsleft > 1) {
- $output .= '';
+ if ($context eq 'overrides') {
+ if ($colsleft > 1) {
+ $output .= ' | ';
+ } else {
+ $output .= ' | ';
+ }
+ $output .= ' ';
} else {
- $output .= ' | ';
- }
- my $defcheck = ' ';
- if (ref($settings) eq 'HASH') {
- if (ref($settings->{$context}) eq 'ARRAY') {
- if (grep(/^default$/,@{$settings->{$context}})) {
+ if ($rem == 0) {
+ $output .= ' | ';
+ }
+ if ($colsleft > 1) {
+ $output .= '';
+ } else {
+ $output .= ' | ';
+ }
+ my $defcheck = ' ';
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{$context}) eq 'ARRAY') {
+ if (grep(/^default$/,@{$settings->{$context}})) {
+ $defcheck = ' checked="checked" ';
+ }
+ } elsif ($context eq 'statustocreate') {
$defcheck = ' checked="checked" ';
}
- } elsif ($context eq 'statustocreate') {
- $defcheck = ' checked="checked" ';
}
+ $output .= ''.
+ ''.
+ $othertitle.'';
}
- $output .= ''.
- ''.
- $othertitle.' | '.
- ' | ';
+ $output .= '
| ';
return $output;
}
@@ -7639,7 +8967,7 @@ sub check_configuser {
my ($configuserok,%currroles);
if ($uhome eq 'no_host') {
srand( time() ^ ($$ + ($$ << 15)) ); # Seed rand.
- my $configpass = &LONCAPA::Enrollment::create_password();
+ my $configpass = &LONCAPA::Enrollment::create_password($dom);
$configuserok =
&Apache::lonnet::modifyuser($dom,$confname,'','internal',
$configpass,'','','','','',undef,$servadm);
@@ -7713,14 +9041,14 @@ sub publishlogo {
} else {
my $source = $filepath.'/'.$file;
my $logfile;
- if (!open($logfile,">>$source".'.log')) {
+ if (!open($logfile,">>",$source.'.log')) {
return (&mt('No write permission to Authoring Space'));
}
print $logfile
"\n================= Publish ".localtime()." ================\n".
$env{'user.name'}.':'.$env{'user.domain'}."\n";
# Save the file
- if (!open(FH,'>'.$source)) {
+ if (!open(FH,">",$source)) {
&Apache::lonnet::logthis('Failed to create '.$source);
return (&mt('Failed to create file'));
}
@@ -7781,7 +9109,8 @@ $env{'user.name'}.':'.$env{'user.domain'
if ($fullwidth ne '' && $fullheight ne '') {
if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {
my $thumbsize = $thumbwidth.'x'.$thumbheight;
- system("convert -sample $thumbsize $inputfile $outfile");
+ my @args = ('convert','-sample',$thumbsize,$inputfile,$outfile);
+ system({$args[0]} @args);
chmod(0660, $filepath.'/tn-'.$file);
if (-e $outfile) {
my $copyfile=$targetdir.'/tn-'.$file;
@@ -7860,7 +9189,7 @@ sub write_metadata {
{
print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;
my $mfh;
- if (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) {
+ if (open($mfh,">",$targetdir.'/'.$file.'.meta')) {
foreach (sort(keys(%metadatafields))) {
unless ($_=~/\./) {
my $unikey=$_;
@@ -7894,7 +9223,7 @@ sub notifysubscribed {
next unless (ref($targetsource) eq 'ARRAY');
my ($target,$source)=@{$targetsource};
if ($source ne '') {
- if (open(my $logfh,'>>'.$source.'.log')) {
+ if (open(my $logfh,">>",$source.'.log')) {
print $logfh "\nCleanup phase: Notifications\n";
my @subscribed=&subscribed_hosts($target);
foreach my $subhost (@subscribed) {
@@ -7920,7 +9249,7 @@ sub notifysubscribed {
sub subscribed_hosts {
my ($target) = @_;
my @subscribed;
- if (open(my $fh,"<$target.subscription")) {
+ if (open(my $fh,"<","$target.subscription")) {
while (my $subline=<$fh>) {
if ($subline =~ /^($match_lonid):/) {
my $host = $1;
@@ -8119,16 +9448,20 @@ sub modify_quotas {
#FIXME need to obsolete item in RES space
} elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {
my ($cdom,$cnum) = split(/_/,$key);
- my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
- $cdom,$cnum,$type,$configuserok,
- $switchserver,$author_ok);
- if ($imgurl) {
- $confhash{$type}{$key}{'image'} = $imgurl;
- $changes{$type}{$key} = 1;
- }
- if ($error) {
- &Apache::lonnet::logthis($error);
- $errors .= ''.$error.'';
+ if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
+ $errors .= ''.&mt('Image not saved: could not find textbook course').'';
+ } else {
+ my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
+ $cdom,$cnum,$type,$configuserok,
+ $switchserver,$author_ok);
+ if ($imgurl) {
+ $confhash{$type}{$key}{'image'} = $imgurl;
+ $changes{$type}{$key} = 1;
+ }
+ if ($error) {
+ &Apache::lonnet::logthis($error);
+ $errors .= ''.$error.'';
+ }
}
} elsif ($domconfig{$action}{$type}{$key}{'image'}) {
$confhash{$type}{$key}{'image'} =
@@ -8162,15 +9495,19 @@ sub modify_quotas {
if ($type eq 'textbooks') {
if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {
my ($cdom,$cnum) = split(/_/,$newbook{$type});
- my ($imageurl,$error) =
- &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,
- $configuserok,$switchserver,$author_ok);
- if ($imageurl) {
- $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;
- }
- if ($error) {
- &Apache::lonnet::logthis($error);
- $errors .= ''.$error.'';
+ if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
+ $errors .= ''.&mt('Image not saved: could not find textbook course').'';
+ } else {
+ my ($imageurl,$error) =
+ &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,
+ $configuserok,$switchserver,$author_ok);
+ if ($imageurl) {
+ $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;
+ }
+ if ($error) {
+ &Apache::lonnet::logthis($error);
+ $errors .= ''.$error.'';
+ }
}
}
}
@@ -8662,7 +9999,7 @@ sub process_textbook_image {
} elsif ($author_ok eq 'ok') {
my ($result,$imageurl) =
&publishlogo($r,'upload',$caller,$dom,$confname,
- "$type/$dom/$cnum/cover",$width,$height);
+ "$type/$cdom/$cnum/cover",$width,$height);
if ($result eq 'ok') {
$url = $imageurl;
} else {
@@ -8762,9 +10099,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') {
@@ -9043,7 +10380,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') {
@@ -9237,6 +10574,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');
}
@@ -9258,8 +10599,9 @@ sub modify_contacts {
my (%others,%to,%bcc,%includestr,%includeloc);
my @contacts = ('supportemail','adminemail');
my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',
- 'lonstatusmail','requestsmail','updatesmail','idconflictsmail');
- my @toggles = ('reporterrors','reportupdates');
+ 'lonstatusmail','requestsmail','updatesmail','idconflictsmail','hostipmail');
+ my @toggles = ('reporterrors','reportupdates','reportstatus');
+ my @lonstatus = ('threshold','sysmail','weights','excluded');
my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
foreach my $type (@mailings) {
@{$newsetting{$type}} =
@@ -9292,23 +10634,98 @@ sub modify_contacts {
$contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
}
}
+ my ($lonstatus_defs,$lonstatus_names) = &Apache::loncommon::lon_status_items();
+ foreach my $item (@lonstatus) {
+ if ($item eq 'excluded') {
+ my (%serverhomes,@excluded);
+ map { $serverhomes{$_} = 1; } values(%Apache::lonnet::serverhomeIDs);
+ my @possexcluded = &Apache::loncommon::get_env_multiple('form.errorexcluded');
+ if (@possexcluded) {
+ foreach my $id (sort(@possexcluded)) {
+ if ($serverhomes{$id}) {
+ push(@excluded,$id);
+ }
+ }
+ }
+ if (@excluded) {
+ $contacts_hash{'contacts'}{'lonstatus'}{$item} = \@excluded;
+ }
+ } elsif ($item eq 'weights') {
+ foreach my $type ('E','W','N','U') {
+ $env{'form.error'.$item.'_'.$type} =~ s/^\s+|\s+$//g;
+ if ($env{'form.error'.$item.'_'.$type} =~ /^\d+$/) {
+ unless ($env{'form.error'.$item.'_'.$type} == $lonstatus_defs->{$type}) {
+ $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type} =
+ $env{'form.error'.$item.'_'.$type};
+ }
+ }
+ }
+ } elsif (($item eq 'threshold') || ($item eq 'sysmail')) {
+ $env{'form.error'.$item} =~ s/^\s+|\s+$//g;
+ if ($env{'form.error'.$item} =~ /^\d+$/) {
+ unless ($env{'form.error'.$item} == $lonstatus_defs->{$item}) {
+ $contacts_hash{'contacts'}{'lonstatus'}{$item} = $env{'form.error'.$item};
+ }
+ }
+ }
+ }
if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {
foreach my $field (@{$fields}) {
if (ref($possoptions->{$field}) eq 'ARRAY') {
my $value = $env{'form.helpform_'.$field};
$value =~ s/^\s+|\s+$//g;
if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {
- $contacts_hash{contacts}{'helpform'}{$field} = $value;
+ $contacts_hash{'contacts'}{'helpform'}{$field} = $value;
if ($field eq 'screenshot') {
$env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;
if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {
- $contacts_hash{contacts}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};
+ $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};
}
}
}
}
}
}
+ my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
+ my (@statuses,%usertypeshash,@overrides);
+ if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) {
+ @statuses = @{$types};
+ if (ref($usertypes) eq 'HASH') {
+ %usertypeshash = %{$usertypes};
+ }
+ }
+ if (@statuses) {
+ my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides');
+ foreach my $type (@possoverrides) {
+ if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) {
+ push(@overrides,$type);
+ }
+ }
+ if (@overrides) {
+ foreach my $type (@overrides) {
+ my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type);
+ foreach my $item (@contacts) {
+ if (grep(/^\Q$item\E$/,@standard)) {
+ $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1;
+ $newsetting{'override_'.$type}{$item} = 1;
+ } else {
+ $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0;
+ $newsetting{'override_'.$type}{$item} = 0;
+ }
+ }
+ $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'};
+ $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
+ $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'};
+ $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
+ if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) {
+ $includestr{$type} = $env{'form.override_'.$type.'_includestr'};
+ $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'};
+ $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});
+ $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};
+ }
+ }
+ }
+ }
if (keys(%currsetting) > 0) {
foreach my $item (@contacts) {
if ($to{$item} ne $currsetting{$item}) {
@@ -9363,6 +10780,103 @@ sub modify_contacts {
}
}
}
+ if (@statuses) {
+ if (ref($currsetting{'overrides'}) eq 'HASH') {
+ foreach my $key (keys(%{$currsetting{'overrides'}})) {
+ if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {
+ if (ref($newsetting{'override_'.$key}) eq 'HASH') {
+ foreach my $item (@contacts,'bcc','others','include') {
+ if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) {
+ push(@{$changes{'overrides'}},$key);
+ last;
+ }
+ }
+ } else {
+ push(@{$changes{'overrides'}},$key);
+ }
+ }
+ }
+ foreach my $key (@overrides) {
+ unless (exists($currsetting{'overrides'}{$key})) {
+ push(@{$changes{'overrides'}},$key);
+ }
+ }
+ } else {
+ foreach my $key (@overrides) {
+ push(@{$changes{'overrides'}},$key);
+ }
+ }
+ }
+ if (ref($currsetting{'lonstatus'}) eq 'HASH') {
+ foreach my $key ('excluded','weights','threshold','sysmail') {
+ if ($key eq 'excluded') {
+ if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') &&
+ (ref($contacts_hash{contacts}{lonstatus}{excluded}) eq 'ARRAY')) {
+ if ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') &&
+ (@{$currsetting{'lonstatus'}{$key}})) {
+ my @diffs =
+ &Apache::loncommon::compare_arrays($contacts_hash{contacts}{lonstatus}{excluded},
+ $currsetting{'lonstatus'}{$key});
+ if (@diffs) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ } elsif (@{$contacts_hash{contacts}{lonstatus}{excluded}}) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ } elsif ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') &&
+ (@{$currsetting{'lonstatus'}{$key}})) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ } elsif ($key eq 'weights') {
+ if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') &&
+ (ref($contacts_hash{contacts}{lonstatus}{$key}) eq 'HASH')) {
+ if (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') {
+ foreach my $type ('E','W','N','U') {
+ unless ($contacts_hash{contacts}{lonstatus}{$key}{$type} eq
+ $currsetting{'lonstatus'}{$key}{$type}) {
+ push(@{$changes{'lonstatus'}},$key);
+ last;
+ }
+ }
+ } else {
+ foreach my $type ('E','W','N','U') {
+ if ($contacts_hash{contacts}{lonstatus}{$key}{$type} ne '') {
+ push(@{$changes{'lonstatus'}},$key);
+ last;
+ }
+ }
+ }
+ } elsif (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') {
+ foreach my $type ('E','W','N','U') {
+ if ($currsetting{'lonstatus'}{$key}{$type} ne '') {
+ push(@{$changes{'lonstatus'}},$key);
+ last;
+ }
+ }
+ }
+ } elsif (($key eq 'threshold') || ($key eq 'sysmail')) {
+ if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
+ if ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) {
+ if ($currsetting{'lonstatus'}{$key} != $contacts_hash{contacts}{lonstatus}{$key}) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ } elsif ($contacts_hash{contacts}{lonstatus}{$key} =~ /^\d+$/) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ } elsif ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ }
+ }
+ } else {
+ if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
+ foreach my $key ('excluded','weights','threshold','sysmail') {
+ if (exists($contacts_hash{contacts}{lonstatus}{$key})) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ }
+ }
+ }
} else {
my %default;
$default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
@@ -9374,6 +10888,7 @@ sub modify_contacts {
$default{'lonstatusmail'} = 'adminemail';
$default{'requestsmail'} = 'adminemail';
$default{'updatesmail'} = 'adminemail';
+ $default{'hostipmail'} = 'adminemail';
foreach my $item (@contacts) {
if ($to{$item} ne $default{$item}) {
$changes{$item} = 1;
@@ -9407,6 +10922,13 @@ sub modify_contacts {
}
}
}
+ if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
+ foreach my $key ('excluded','weights','threshold','sysmail') {
+ if (exists($contacts_hash{contacts}{lonstatus}{$key})) {
+ push(@{$changes{'lonstatus'}},$key);
+ }
+ }
+ }
}
foreach my $item (@toggles) {
if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) {
@@ -9477,23 +10999,134 @@ sub modify_contacts {
$resulttext .= '';
}
}
+ if (ref($changes{'overrides'}) eq 'ARRAY') {
+ my @deletions;
+ foreach my $type (@{$changes{'overrides'}}) {
+ if ($usertypeshash{$type}) {
+ if (grep(/^\Q$type\E/,@overrides)) {
+ $resulttext .= ''.&mt("Overrides based on requester's affiliation set for [_1]",
+ $usertypeshash{$type}).'- ';
+ if (ref($newsetting{'override_'.$type}) eq 'HASH') {
+ my @text;
+ foreach my $item (@contacts) {
+ if ($newsetting{'override_'.$type}{$item}) {
+ push(@text,$short_titles->{$item});
+ }
+ }
+ if ($newsetting{'override_'.$type}{'others'} ne '') {
+ push(@text,$newsetting{'override_'.$type}{'others'});
+ }
+
+ if (@text) {
+ $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',
+ ''.join(', ',@text).'');
+ }
+ if ($newsetting{'override_'.$type}{'bcc'} ne '') {
+ my $bcctext;
+ if (@text) {
+ $bcctext = ' '.&mt('with Bcc to');
+ } else {
+ $bcctext = '(Bcc)';
+ }
+ $resulttext .= $bcctext.': '.$newsetting{'override_'.$type}{'bcc'}.'';
+ } elsif (!@text) {
+ $resulttext .= &mt('Helpdesk e-mail sent to no one');
+ }
+ $resulttext .= '
';
+ if ($newsetting{'override_'.$type}{'include'} ne '') {
+ my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'});
+ if ($loc eq 'b') {
+ $resulttext .= '- '.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'
';
+ } elsif ($loc eq 's') {
+ $resulttext .= '- '.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'
';
+ }
+ }
+ }
+ $resulttext .= ' ';
+ } else {
+ push(@deletions,$usertypeshash{$type});
+ }
+ }
+ }
+ if (@deletions) {
+ $resulttext .= ''.&mt("Overrides based on requester's affiliation discontinued for: [_1]",
+ join(', ',@deletions)).'';
+ }
+ }
my @offon = ('off','on');
+ my $corelink = &core_link_msu();
if ($changes{'reporterrors'}) {
$resulttext .= ''.
&mt('E-mail error reports to [_1] set to "'.
$offon[$env{'form.reporterrors'}].'".',
- &Apache::loncommon::modal_link('http://loncapa.org/core.html',
- &mt('LON-CAPA core group - MSU'),600,500)).
+ $corelink).
'';
}
if ($changes{'reportupdates'}) {
$resulttext .= ''.
&mt('E-mail record of completed LON-CAPA updates to [_1] set to "'.
$offon[$env{'form.reportupdates'}].'".',
- &Apache::loncommon::modal_link('http://loncapa.org/core.html',
- &mt('LON-CAPA core group - MSU'),600,500)).
+ $corelink).
+ '';
+ }
+ if ($changes{'reportstatus'}) {
+ $resulttext .= ''.
+ &mt('E-mail status if errors above threshold to [_1] set to "'.
+ $offon[$env{'form.reportstatus'}].'".',
+ $corelink).
'';
}
+ if (ref($changes{'lonstatus'}) eq 'ARRAY') {
+ $resulttext .= ''.
+ &mt('Nightly status check e-mail settings').':';
+ my (%defval,%use_def,%shown);
+ $defval{'threshold'} = $lonstatus_defs->{'threshold'};
+ $defval{'sysmail'} = $lonstatus_defs->{'sysmail'};
+ $defval{'weights'} =
+ join(', ',map { $lonstatus_names->{$_}.'='.$lonstatus_defs->{$_}; } ('E','W','N','U'));
+ $defval{'excluded'} = &mt('None');
+ if (ref($contacts_hash{'contacts'}{'lonstatus'}) eq 'HASH') {
+ foreach my $item ('threshold','sysmail','weights','excluded') {
+ if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item})) {
+ if (($item eq 'threshold') || ($item eq 'sysmail')) {
+ $shown{$item} = $contacts_hash{'contacts'}{'lonstatus'}{$item};
+ } elsif ($item eq 'weights') {
+ if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'HASH') {
+ foreach my $type ('E','W','N','U') {
+ $shown{$item} .= $lonstatus_names->{$type}.'=';
+ if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item}{$type})) {
+ $shown{$item} .= $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type};
+ } else {
+ $shown{$item} .= $lonstatus_defs->{$type};
+ }
+ $shown{$item} .= ', ';
+ }
+ $shown{$item} =~ s/, $//;
+ } else {
+ $shown{$item} = $defval{$item};
+ }
+ } elsif ($item eq 'excluded') {
+ if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'ARRAY') {
+ $shown{$item} = join(', ',@{$contacts_hash{'contacts'}{'lonstatus'}{$item}});
+ } else {
+ $shown{$item} = $defval{$item};
+ }
+ }
+ } else {
+ $shown{$item} = $defval{$item};
+ }
+ }
+ } else {
+ foreach my $item ('threshold','weights','excluded','sysmail') {
+ $shown{$item} = $defval{$item};
+ }
+ }
+ foreach my $item ('threshold','weights','excluded','sysmail') {
+ $resulttext .= '- '.&mt($titles->{'error'.$item}.' -- [_1]',
+ $shown{$item}).'
';
+ }
+ $resulttext .= ' ';
+ }
if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {
my (@optional,@required,@unused,$maxsizechg);
foreach my $field (@{$changes{'helpform'}}) {
@@ -9532,7 +11165,6 @@ sub modify_contacts {
&mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',
$contacts_hash{'contacts'}{'helpform'}{'maxsize'}).
'';
-
}
}
$resulttext .= '';
@@ -9546,6 +11178,549 @@ sub modify_contacts {
return $resulttext;
}
+sub modify_passwords {
+ my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
+ my ($resulttext,%current,%changes,%newvalues,@oktypes,$errors,
+ $updatedefaults,$updateconf);
+ my $customfn = 'resetpw.html';
+ if (ref($domconfig{'passwords'}) eq 'HASH') {
+ %current = %{$domconfig{'passwords'}};
+ }
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+ my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
+ if (ref($types) eq 'ARRAY') {
+ @oktypes = @{$types};
+ }
+ push(@oktypes,'default');
+
+ my %titles = &Apache::lonlocal::texthash (
+ 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',
+ permanent => 'Permanent e-mail address',
+ critical => 'Critical notification address',
+ notify => 'Notification address',
+ min => 'Minimum password length',
+ max => 'Maximum password length',
+ chars => 'Required characters',
+ numsaved => 'Number of previous passwords to save',
+ reset => 'Resetting Forgotten Password',
+ intauth => 'Encryption of Stored Passwords (Internal Auth)',
+ rules => 'Rules for LON-CAPA Passwords',
+ crsownerchg => 'Course Owner Changing Student Passwords',
+ username => 'Username',
+ email => 'E-mail address',
+ );
+
+#
+# Retrieve current domain configuration for internal authentication from $domconfig{'defaults'}.
+#
+ my (%curr_defaults,%save_defaults);
+ if (ref($domconfig{'defaults'}) eq 'HASH') {
+ foreach my $key (keys(%{$domconfig{'defaults'}})) {
+ if ($key =~ /^intauth_(cost|check|switch)$/) {
+ $curr_defaults{$key} = $domconfig{'defaults'}{$key};
+ } else {
+ $save_defaults{$key} = $domconfig{'defaults'}{$key};
+ }
+ }
+ }
+ my %staticdefaults = (
+ 'resetlink' => 2,
+ 'resetcase' => \@oktypes,
+ 'resetprelink' => 'both',
+ 'resetemail' => ['critical','notify','permanent'],
+ 'intauth_cost' => 10,
+ 'intauth_check' => 0,
+ 'intauth_switch' => 0,
+ );
+ $staticdefaults{'min'} = $Apache::lonnet::passwdmin;
+ foreach my $type (@oktypes) {
+ $staticdefaults{'resetpostlink'}{$type} = ['email','username'];
+ }
+ my $linklife = $env{'form.passwords_link'};
+ $linklife =~ s/^\s+|\s+$//g;
+ if (($linklife =~ /^\d+(|\.\d*)$/) && ($linklife > 0)) {
+ $newvalues{'resetlink'} = $linklife;
+ if ($current{'resetlink'}) {
+ if ($current{'resetlink'} ne $linklife) {
+ $changes{'reset'} = 1;
+ }
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
+ if ($staticdefaults{'resetlink'} ne $linklife) {
+ $changes{'reset'} = 1;
+ }
+ }
+ } elsif ($current{'resetlink'}) {
+ $changes{'reset'} = 1;
+ }
+ my @casesens;
+ my @posscase = &Apache::loncommon::get_env_multiple('form.passwords_case_sensitive');
+ foreach my $case (sort(@posscase)) {
+ if (grep(/^\Q$case\E$/,@oktypes)) {
+ push(@casesens,$case);
+ }
+ }
+ $newvalues{'resetcase'} = \@casesens;
+ if (ref($current{'resetcase'}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($current{'resetcase'},\@casesens);
+ if (@diffs > 0) {
+ $changes{'reset'} = 1;
+ }
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
+ my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetcase'},\@casesens);
+ if (@diffs > 0) {
+ $changes{'reset'} = 1;
+ }
+ }
+ if ($env{'form.passwords_prelink'} =~ /^(both|either)$/) {
+ $newvalues{'resetprelink'} = $env{'form.passwords_prelink'};
+ if (exists($current{'resetprelink'})) {
+ if ($current{'resetprelink'} ne $newvalues{'resetprelink'}) {
+ $changes{'reset'} = 1;
+ }
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
+ if ($staticdefaults{'resetprelink'} ne $newvalues{'resetprelink'}) {
+ $changes{'reset'} = 1;
+ }
+ }
+ } elsif ($current{'resetprelink'}) {
+ $changes{'reset'} = 1;
+ }
+ foreach my $type (@oktypes) {
+ my @possplink = &Apache::loncommon::get_env_multiple('form.passwords_postlink_'.$type);
+ my @postlink;
+ foreach my $item (sort(@possplink)) {
+ if ($item =~ /^(email|username)$/) {
+ push(@postlink,$item);
+ }
+ }
+ $newvalues{'resetpostlink'}{$type} = \@postlink;
+ unless ($changes{'reset'}) {
+ if (ref($current{'resetpostlink'}) eq 'HASH') {
+ if (ref($current{'resetpostlink'}{$type}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($current{'resetpostlink'}{$type},\@postlink);
+ if (@diffs > 0) {
+ $changes{'reset'} = 1;
+ }
+ } else {
+ $changes{'reset'} = 1;
+ }
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
+ my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetpostlink'}{$type},\@postlink);
+ if (@diffs > 0) {
+ $changes{'reset'} = 1;
+ }
+ }
+ }
+ }
+ my @possemailsrc = &Apache::loncommon::get_env_multiple('form.passwords_emailsrc');
+ my @resetemail;
+ foreach my $item (sort(@possemailsrc)) {
+ if ($item =~ /^(permanent|critical|notify)$/) {
+ push(@resetemail,$item);
+ }
+ }
+ $newvalues{'resetemail'} = \@resetemail;
+ unless ($changes{'reset'}) {
+ if (ref($current{'resetemail'}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($current{'resetemail'},\@resetemail);
+ if (@diffs > 0) {
+ $changes{'reset'} = 1;
+ }
+ } elsif (!ref($domconfig{passwords}) eq 'HASH') {
+ my @diffs = &Apache::loncommon::compare_arrays($staticdefaults{'resetemail'},\@resetemail);
+ if (@diffs > 0) {
+ $changes{'reset'} = 1;
+ }
+ }
+ }
+ if ($env{'form.passwords_stdtext'} == 0) {
+ $newvalues{'resetremove'} = 1;
+ unless ($current{'resetremove'}) {
+ $changes{'reset'} = 1;
+ }
+ } elsif ($current{'resetremove'}) {
+ $changes{'reset'} = 1;
+ }
+ if ($env{'form.passwords_customfile.filename'} ne '') {
+ my $servadm = $r->dir_config('lonAdmEMail');
+ my $servadm = $r->dir_config('lonAdmEMail');
+ my ($configuserok,$author_ok,$switchserver) =
+ &config_check($dom,$confname,$servadm);
+ my $error;
+ if ($configuserok eq 'ok') {
+ if ($switchserver) {
+ $error = &mt("Upload of file containing domain-specific text is not permitted to this server: [_1]",$switchserver);
+ } else {
+ if ($author_ok eq 'ok') {
+ my ($result,$customurl) =
+ &publishlogo($r,'upload','passwords_customfile',$dom,
+ $confname,'customtext/resetpw','','',$customfn);
+ if ($result eq 'ok') {
+ $newvalues{'resetcustom'} = $customurl;
+ $changes{'reset'} = 1;
+ } else {
+ $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$customfn,$result);
+ }
+ } else {
+ $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$customfn,$confname,$dom,$author_ok);
+ }
+ }
+ } else {
+ $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$customfn,$confname,$dom,$configuserok);
+ }
+ if ($error) {
+ &Apache::lonnet::logthis($error);
+ $errors .= ''.$error.'';
+ }
+ } elsif ($current{'resetcustom'}) {
+ if ($env{'form.passwords_custom_del'}) {
+ $changes{'reset'} = 1;
+ } else {
+ $newvalues{'resetcustom'} = $current{'resetcustom'};
+ }
+ }
+ $env{'form.intauth_cost'} =~ s/^\s+|\s+$//g;
+ if (($env{'form.intauth_cost'} ne '') && ($env{'form.intauth_cost'} =~ /^\d+$/)) {
+ $save_defaults{'intauth_cost'} = $env{'form.intauth_cost'};
+ if ($save_defaults{'intauth_cost'} ne $curr_defaults{'intauth_cost'}) {
+ $changes{'intauth'} = 1;
+ }
+ } else {
+ $save_defaults{'intauth_cost'} = $curr_defaults{'intauth_cost'};
+ }
+ if ($env{'form.intauth_check'} =~ /^(0|1|2)$/) {
+ $save_defaults{'intauth_check'} = $env{'form.intauth_check'};
+ if ($save_defaults{'intauth_check'} ne $curr_defaults{'intauth_check'}) {
+ $changes{'intauth'} = 1;
+ }
+ } else {
+ $save_defaults{'intauth_check'} = $curr_defaults{'intauth_check'};
+ }
+ if ($env{'form.intauth_switch'} =~ /^(0|1|2)$/) {
+ $save_defaults{'intauth_switch'} = $env{'form.intauth_switch'};
+ if ($save_defaults{'intauth_switch'} ne $curr_defaults{'intauth_switch'}) {
+ $changes{'intauth'} = 1;
+ }
+ } else {
+ $save_defaults{'intauth_check'} = $curr_defaults{'intauth_check'};
+ }
+ foreach my $item ('cost','check','switch') {
+ if ($save_defaults{'intauth_'.$item} ne $domdefaults{'intauth_'.$item}) {
+ $domdefaults{'intauth_'.$item} = $save_defaults{'intauth_'.$item};
+ $updatedefaults = 1;
+ }
+ }
+ foreach my $rule ('min','max','numsaved') {
+ $env{'form.passwords_'.$rule} =~ s/^\s+|\s+$//g;
+ my $ruleok;
+ if ($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) {
+ $newvalues{$rule} = $env{'form.passwords_'.$rule};
+ if (exists($current{$rule})) {
+ if ($newvalues{$rule} ne $current{$rule}) {
+ $changes{'rules'} = 1;
+ }
+ } elsif ($rule eq 'min') {
+ if ($staticdefaults{$rule} ne $newvalues{$rule}) {
+ $changes{'rules'} = 1;
+ }
+ } else {
+ $changes{'rules'} = 1;
+ }
+ } elsif (exists($current{$rule})) {
+ $changes{'rules'} = 1;
+ }
+ }
+ my @posschars = &Apache::loncommon::get_env_multiple('form.passwords_chars');
+ my @chars;
+ foreach my $item (sort(@posschars)) {
+ if ($item =~ /^(uc|lc|num|spec)$/) {
+ push(@chars,$item);
+ }
+ }
+ $newvalues{'chars'} = \@chars;
+ unless ($changes{'rules'}) {
+ if (ref($current{'chars'}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($current{'chars'},\@chars);
+ if (@diffs > 0) {
+ $changes{'rules'} = 1;
+ }
+ } else {
+ if (@chars > 0) {
+ $changes{'rules'} = 1;
+ }
+ }
+ }
+ my %crsownerchg = (
+ by => [],
+ for => [],
+ );
+ foreach my $item ('by','for') {
+ my @posstypes = &Apache::loncommon::get_env_multiple('form.passwords_crsowner_'.$item);
+ foreach my $type (sort(@posstypes)) {
+ if (grep(/^\Q$type\E$/,@oktypes)) {
+ push(@{$crsownerchg{$item}},$type);
+ }
+ }
+ }
+ $newvalues{'crsownerchg'} = \%crsownerchg;
+ if (ref($current{'crsownerchg'}) eq 'HASH') {
+ foreach my $item ('by','for') {
+ if (ref($current{'crsownerchg'}{$item}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($current{'crsownerchg'}{$item},$crsownerchg{$item});
+ if (@diffs > 0) {
+ $changes{'crsownerchg'} = 1;
+ last;
+ }
+ }
+ }
+ } elsif (!(ref($domconfig{passwords}) eq 'HASH')) {
+ foreach my $item ('by','for') {
+ if (@{$crsownerchg{$item}} > 0) {
+ $changes{'crsownerchg'} = 1;
+ last;
+ }
+ }
+ }
+
+ my %confighash = (
+ defaults => \%save_defaults,
+ passwords => \%newvalues,
+ );
+ &process_captcha('passwords',\%changes,$confighash{'passwords'},$domconfig{'passwords'});
+
+ my $putresult = &Apache::lonnet::put_dom('configuration',\%confighash,$dom);
+ if ($putresult eq 'ok') {
+ if (keys(%changes) > 0) {
+ $resulttext = &mt('Changes made: ').'';
+ foreach my $key ('reset','intauth','rules','crsownerchg') {
+ if ($changes{$key}) {
+ unless ($key eq 'intauth') {
+ $updateconf = 1;
+ }
+ $resulttext .= '- '.$titles{$key}.':
';
+ if ($key eq 'reset') {
+ if ($confighash{'passwords'}{'captcha'} eq 'original') {
+ $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'}).'
';
+ 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').'
';
+ }
+ if ($confighash{'passwords'}{'resetlink'}) {
+ $resulttext .= '- '.&mt('Reset link expiration set to [quant,_1,hour]',$confighash{'passwords'}{'resetlink'}).'
';
+ } else {
+ $resulttext .= '- '.&mt('No reset link expiration set.').' '.
+ &mt('Will default to 2 hours').'
';
+ }
+ if (ref($confighash{'passwords'}{'resetcase'}) eq 'ARRAY') {
+ if (@{$confighash{'passwords'}{'resetcase'}} == 0) {
+ $resulttext .= '- '.&mt('User input for username and/or e-mail address not case sensitive for "Forgot Password" web form').'
';
+ } else {
+ my $casesens;
+ foreach my $type (@{$confighash{'passwords'}{'resetcase'}}) {
+ if ($type eq 'default') {
+ $casesens .= $othertitle.', ';
+ } elsif ($usertypes->{$type} ne '') {
+ $casesens .= $usertypes->{$type}.', ';
+ }
+ }
+ $casesens =~ s/\Q, \E$//;
+ $resulttext .= '- '.&mt('"Forgot Password" web form input for username and/or e-mail address is case-sensitive for: [_1]',$casesens).'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('Case-sensitivity not set for "Forgot Password" web form').' '.&mt('Will default to case-sensitive for username and/or e-mail address for all').'
';
+ }
+ if ($confighash{'passwords'}{'resetprelink'} eq 'either') {
+ $resulttext .= '- '.&mt('Users can enter either a username or an e-mail address in "Forgot Password" web form').'
';
+ } else {
+ $resulttext .= '- '.&mt('Users can enter both a username and an e-mail address in "Forgot Password" web form').'
';
+ }
+ if (ref($confighash{'passwords'}{'resetpostlink'}) eq 'HASH') {
+ my $output;
+ if (ref($types) eq 'ARRAY') {
+ foreach my $type (@{$types}) {
+ if (ref($confighash{'passwords'}{'resetpostlink'}{$type}) eq 'ARRAY') {
+ if (@{$confighash{'passwords'}{'resetpostlink'}{$type}} == 0) {
+ $output .= $usertypes->{$type}.' -- '.&mt('none');
+ } else {
+ $output .= $usertypes->{$type}.' -- '.
+ join(', ',map { $titles{$_}; } (@{$confighash{'passwords'}{'resetpostlink'}{$type}})).'; ';
+ }
+ }
+ }
+ }
+ if (ref($confighash{'passwords'}{'resetpostlink'}{'default'}) eq 'ARRAY') {
+ if (@{$confighash{'passwords'}{'resetpostlink'}{'default'}} == 0) {
+ $output .= $othertitle.' -- '.&mt('none');
+ } else {
+ $output .= $othertitle.' -- '.
+ join(', ',map { $titles{$_}; } (@{$confighash{'passwords'}{'resetpostlink'}{'default'}}));
+ }
+ }
+ if ($output) {
+ $resulttext .= '- '.&mt('Information required for new password form (by user type) set to: [_1]',$output).'
';
+ } else {
+ $resulttext .= '- '.&mt('Information required for new password form not set.').' '.&mt('Will default to requiring both the username and an e-mail address').'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('Information required for new password form not set.').' '.&mt('Will default to requiring both the username and an e-mail address').'
';
+ }
+ if (ref($confighash{'passwords'}{'resetemail'}) eq 'ARRAY') {
+ if (@{$confighash{'passwords'}{'resetemail'}} > 0) {
+ $resulttext .= '- '.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$confighash{'passwords'}{'resetemail'}})).'
';
+ } else {
+ $resulttext .= '- '.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('E-mail address(es) in LON-CAPA used for verification will include: [_1]',join(', ',map { $titles{$_}; } @{$staticdefaults{'resetemail'}})).'
';
+ }
+ if ($confighash{'passwords'}{'resetremove'}) {
+ $resulttext .= '- '.&mt('Preamble to "Forgot Password" web form not shown').'
';
+ } else {
+ $resulttext .= '- '.&mt('Preamble to "Forgot Password" web form is shown').'
';
+ }
+ if ($confighash{'passwords'}{'resetcustom'}) {
+ my $customlink = &Apache::loncommon::modal_link($confighash{'passwords'}{'resetcustom'},
+ &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').'
';
+ }
+ } elsif ($key eq 'intauth') {
+ foreach my $item ('cost','switch','check') {
+ my $value = $save_defaults{$key.'_'.$item};
+ if ($item eq '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 '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]"',$titles{$key.'_'.$item},$value).'
';
+ }
+ } elsif ($key eq 'rules') {
+ foreach my $rule ('min','max','numsaved') {
+ if ($confighash{'passwords'}{$rule} eq '') {
+ if ($rule eq 'min') {
+ $resulttext .= '- '.&mt('[_1] not set.',$titles{$rule});
+ ' '.&mt('Default of [_1] will be used',
+ $Apache::lonnet::passwdmin).'
';
+ } else {
+ $resulttext .= '- '.&mt('[_1] set to none',$titles{$rule}).'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('[_1] set to [_2]',$titles{$rule},$confighash{'passwords'}{$rule}).'
';
+ }
+ }
+ if (ref($confighash{'passwords'}{'chars'}) eq 'ARRAY') {
+ if (@{$confighash{'passwords'}{'chars'}} > 0) {
+ my %rulenames = &Apache::lonlocal::texthash(
+ uc => 'At least one upper case letter',
+ lc => 'At least one lower case letter',
+ num => 'At least one number',
+ spec => 'At least one non-alphanumeric',
+ );
+ my $needed = '- '.
+ join('
- ',map {$rulenames{$_} } @{$confighash{'passwords'}{'chars'}}).
+ '
';
+ $resulttext .= '- '.&mt('[_1] set to: [_2]',$titles{'chars'},$needed).'
';
+ } else {
+ $resulttext .= '- '.&mt('[_1] set to none',$titles{'chars'}).'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('[_1] set to none',$titles{'chars'}).'
';
+ }
+ } elsif ($key eq 'crsownerchg') {
+ if (ref($confighash{'passwords'}{'crsownerchg'}) eq 'HASH') {
+ if ((@{$confighash{'passwords'}{'crsownerchg'}{'by'}} == 0) ||
+ (@{$confighash{'passwords'}{'crsownerchg'}{'for'}} == 0)) {
+ $resulttext .= '- '.&mt('Course owner may not change student passwords.').'
';
+ } else {
+ my %crsownerstr;
+ foreach my $item ('by','for') {
+ if (ref($confighash{'passwords'}{'crsownerchg'}{$item}) eq 'ARRAY') {
+ foreach my $type (@{$confighash{'passwords'}{'crsownerchg'}{$item}}) {
+ if ($type eq 'default') {
+ $crsownerstr{$item} .= $othertitle.', ';
+ } elsif ($usertypes->{$type} ne '') {
+ $crsownerstr{$item} .= $usertypes->{$type}.', ';
+ }
+ }
+ $crsownerstr{$item} =~ s/\Q, \E$//;
+ }
+ }
+ $resulttext .= '- '.&mt('Course owner (with status: [_1]) may change passwords for students (with status: [_2]).',
+ $crsownerstr{'by'},$crsownerstr{'for'}).'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('Course owner may not change student passwords.').'
';
+ }
+ }
+ $resulttext .= ' ';
+ }
+ }
+ $resulttext .= ' ';
+ } else {
+ $resulttext = &mt('No changes made to password settings');
+ }
+ my $cachetime = 24*60*60;
+ if ($updatedefaults) {
+ &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'domdefaults'} = 1;
+ }
+ }
+ if ($updateconf) {
+ &Apache::lonnet::do_cache_new('passwdconf',$dom,$confighash{'passwords'},$cachetime);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'passwdconf'} = 1;
+ }
+ }
+ } else {
+ $resulttext = ''.
+ &mt('An error occurred: [_1]',$putresult).'';
+ }
+ if ($errors) {
+ $resulttext .= ''.&mt('The following errors occurred: ').' ';
+ }
+ return $resulttext;
+}
+
sub modify_usercreation {
my ($dom,%domconfig) = @_;
my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);
@@ -9555,12 +11730,10 @@ sub modify_usercreation {
if ($key eq 'cancreate') {
if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
- if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
- ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
- ($item eq 'recaptchaversion')) {
- $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
- } else {
+ if (($item eq 'requestcrs') || ($item eq 'course') || ($item eq 'author')) {
$curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
+ } else {
+ $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
}
}
}
@@ -9763,14 +11936,18 @@ sub modify_usercreation {
}
sub modify_selfcreation {
- my ($dom,%domconfig) = @_;
- my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate);
- my (%save_usercreate,%save_usermodify);
- my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
- if (ref($types) eq 'ARRAY') {
- $usertypes->{'default'} = $othertitle;
- push(@{$types},'default');
+ my ($dom,$lastactref,%domconfig) = @_;
+ my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%curr_inststatus,%changes,%cancreate);
+ my (%save_usercreate,%save_usermodify,%save_inststatus,@types,%usertypes);
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+ my ($othertitle,$usertypesref,$typesref) = &Apache::loncommon::sorted_inst_types($dom);
+ if (ref($typesref) eq 'ARRAY') {
+ @types = @{$typesref};
}
+ if (ref($usertypesref) eq 'HASH') {
+ %usertypes = %{$usertypesref};
+ }
+ $usertypes{'default'} = $othertitle;
#
# Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.
#
@@ -9780,10 +11957,11 @@ sub modify_selfcreation {
if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
- ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
- ($item eq 'recaptchaversion') ||
- ($item eq 'emailusername') || ($item eq 'notify') ||
- ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) {
+ ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
+ ($item eq 'recaptchaversion') || ($item eq 'notify') ||
+ ($item eq 'emailusername') || ($item eq 'shibenv') ||
+ ($item eq 'selfcreateprocessing') || ($item eq 'emailverified') ||
+ ($item eq 'emailoptions') || ($item eq 'emaildomain')) {
$curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
} else {
$save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
@@ -9809,41 +11987,161 @@ sub modify_selfcreation {
}
}
}
+#
+# Retrieve current domain configuration for institutional status types from $domconfig{'inststatus'}.
+#
+ if (ref($domconfig{'inststatus'}) eq 'HASH') {
+ foreach my $key (keys(%{$domconfig{'inststatus'}})) {
+ if ($key eq 'inststatusguest') {
+ $curr_inststatus{$key} = $domconfig{'inststatus'}{$key};
+ } else {
+ $save_inststatus{$key} = $domconfig{'inststatus'}{$key};
+ }
+ }
+ }
my @contexts = ('selfcreate');
@{$cancreate{'selfcreate'}} = ();
%{$cancreate{'emailusername'}} = ();
- @{$cancreate{'statustocreate'}} = ();
+ if (@types) {
+ @{$cancreate{'statustocreate'}} = ();
+ }
%{$cancreate{'selfcreateprocessing'}} = ();
%{$cancreate{'shibenv'}} = ();
+ %{$cancreate{'emailverified'}} = ();
+ %{$cancreate{'emailoptions'}} = ();
+ %{$cancreate{'emaildomain'}} = ();
my %selfcreatetypes = (
sso => 'users authenticated by institutional single sign on',
login => 'users authenticated by institutional log-in',
- email => 'users who provide a valid e-mail address for use as username',
+ email => 'users verified by e-mail',
);
#
# Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts
# is permitted.
#
- my @statuses;
- if (ref($domconfig{'inststatus'}) eq 'HASH') {
- if (ref($domconfig{'inststatus'}{'inststatusguest'}) eq 'ARRAY') {
- @statuses = @{$domconfig{'inststatus'}{'inststatusguest'}};
- }
- }
- push(@statuses,'default');
+ my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email');
+ my (@statuses,%email_rule);
foreach my $item ('login','sso','email') {
if ($item eq 'email') {
if ($env{'form.cancreate_email'}) {
- push(@{$cancreate{'selfcreate'}},'email');
- push(@contexts,'selfcreateprocessing');
- foreach my $type (@statuses) {
- if ($type eq 'default') {
- $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess'};
- } else {
- $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};
+ if (@types) {
+ my @poss_statuses = &Apache::loncommon::get_env_multiple('form.selfassign');
+ foreach my $status (@poss_statuses) {
+ if (grep(/^\Q$status\E$/,(@types,'default'))) {
+ push(@statuses,$status);
+ }
+ }
+ $save_inststatus{'inststatusguest'} = \@statuses;
+ } else {
+ push(@statuses,'default');
+ }
+ if (@statuses) {
+ my %curr_rule;
+ if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
+ foreach my $type (@statuses) {
+ $curr_rule{$type} = $curr_usercreation{'email_rule'};
+ }
+ } elsif (ref($curr_usercreation{'email_rule'}) eq 'HASH') {
+ foreach my $type (@statuses) {
+ $curr_rule{$type} = $curr_usercreation{'email_rule'}{$type};
+ }
+ }
+ push(@{$cancreate{'selfcreate'}},'email');
+ push(@contexts,('selfcreateprocessing','emailverified','emailoptions'));
+ my %curremaildom;
+ if (ref($curr_usercreation{'cancreate'}{'emaildomain'}) eq 'HASH') {
+ %curremaildom = %{$curr_usercreation{'cancreate'}{'emaildomain'}};
+ }
+ foreach my $type (@statuses) {
+ if ($env{'form.cancreate_emailprocess_'.$type} =~ /^(?:approval|automatic)$/) {
+ $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};
+ }
+ if ($env{'form.cancreate_usernameoptions_'.$type} =~ /^(?:all|first|free)$/) {
+ $cancreate{'emailverified'}{$type} = $env{'form.cancreate_usernameoptions_'.$type};
+ }
+ if ($env{'form.cancreate_emailoptions_'.$type} =~ /^(any|inst|noninst|custom)$/) {
+#
+# Retrieve rules (if any) governing types of e-mail address which may be used to verify a username.
+#
+ my $chosen = $1;
+ if (($chosen eq 'inst') || ($chosen eq 'noninst')) {
+ my $emaildom;
+ if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {
+ $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type};
+ $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;
+ if (ref($curremaildom{$type}) eq 'HASH') {
+ if (exists($curremaildom{$type}{$chosen})) {
+ if ($curremaildom{$type}{$chosen} ne $emaildom) {
+ push(@{$changes{'cancreate'}},'emaildomain');
+ }
+ } elsif ($emaildom ne '') {
+ push(@{$changes{'cancreate'}},'emaildomain');
+ }
+ } elsif ($emaildom ne '') {
+ push(@{$changes{'cancreate'}},'emaildomain');
+ }
+ }
+ $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
+ } elsif ($chosen eq 'custom') {
+ my @possemail_rules = &Apache::loncommon::get_env_multiple('form.email_rule_'.$type);
+ $email_rule{$type} = [];
+ if (ref($emailrules) eq 'HASH') {
+ foreach my $rule (@possemail_rules) {
+ if (exists($emailrules->{$rule})) {
+ push(@{$email_rule{$type}},$rule);
+ }
+ }
+ }
+ if (@{$email_rule{$type}}) {
+ $cancreate{'emailoptions'}{$type} = 'custom';
+ if (ref($curr_rule{$type}) eq 'ARRAY') {
+ if (@{$curr_rule{$type}} > 0) {
+ foreach my $rule (@{$curr_rule{$type}}) {
+ if (!grep(/^\Q$rule\E$/,@{$email_rule{$type}})) {
+ push(@{$changes{'email_rule'}},$type);
+ }
+ }
+ }
+ foreach my $type (@{$email_rule{$type}}) {
+ if (!grep(/^\Q$type\E$/,@{$curr_rule{$type}})) {
+ push(@{$changes{'email_rule'}},$type);
+ }
+ }
+ } else {
+ push(@{$changes{'email_rule'}},$type);
+ }
+ }
+ } else {
+ $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
+ }
+ }
+ }
+ if (@types) {
+ if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
+ my @changed = &Apache::loncommon::compare_arrays(\@statuses,$curr_inststatus{'inststatusguest'});
+ if (@changed) {
+ push(@{$changes{'inststatus'}},'inststatusguest');
+ }
+ } else {
+ push(@{$changes{'inststatus'}},'inststatusguest');
+ }
+ }
+ } else {
+ delete($env{'form.cancreate_email'});
+ if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
+ if (@{$curr_inststatus{'inststatusguest'}} > 0) {
+ push(@{$changes{'inststatus'}},'inststatusguest');
+ }
+ }
+ }
+ } else {
+ $save_inststatus{'inststatusguest'} = [];
+ if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
+ if (@{$curr_inststatus{'inststatusguest'}} > 0) {
+ push(@{$changes{'inststatus'}},'inststatusguest');
}
}
}
@@ -9853,7 +12151,7 @@ sub modify_selfcreation {
}
}
}
- my (@email_rule,%userinfo,%savecaptcha);
+ my (%userinfo,%savecaptcha);
my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
#
# Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data
@@ -9862,8 +12160,8 @@ sub modify_selfcreation {
if ($env{'form.cancreate_email'}) {
push(@contexts,'emailusername');
- if (ref($types) eq 'ARRAY') {
- foreach my $type (@{$types}) {
+ if (@statuses) {
+ foreach my $type (@statuses) {
if (ref($infofields) eq 'ARRAY') {
foreach my $field (@{$infofields}) {
if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {
@@ -9875,7 +12173,7 @@ sub modify_selfcreation {
}
#
# Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of
-# queued requests for self-creation of account using e-mail address as username
+# queued requests for self-creation of account verified by e-mail.
#
my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');
@@ -9895,36 +12193,13 @@ sub modify_selfcreation {
push(@{$changes{'cancreate'}},'notify');
}
-#
-# Retrieve rules (if any) governing types of e-mail address which may be used as a username
-#
- @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule');
&process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});
- if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
- if (@{$curr_usercreation{'email_rule'}} > 0) {
- foreach my $type (@{$curr_usercreation{'email_rule'}}) {
- if (!grep(/^\Q$type\E$/,@email_rule)) {
- push(@{$changes{'email_rule'}},$type);
- }
- }
- }
- if (@email_rule > 0) {
- foreach my $type (@email_rule) {
- if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) {
- push(@{$changes{'email_rule'}},$type);
- }
- }
- }
- } elsif (@email_rule > 0) {
- push(@{$changes{'email_rule'}},@email_rule);
- }
}
#
# Check if domain default is set appropriately, if self-creation of accounts is to be available for
# institutional log-in.
#
if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {
- my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) ||
($domdefaults{'auth_def'} eq 'localauth'))) {
$warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.
@@ -9943,14 +12218,10 @@ sub modify_selfcreation {
# which the user may supply, if institutional data is unavailable.
#
if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {
- if (ref($types) eq 'ARRAY') {
- if (@{$types} > 1) {
- @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
- push(@contexts,'statustocreate');
- } else {
- undef($cancreate{'statustocreate'});
- }
- foreach my $type (@{$types}) {
+ if (@types) {
+ @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
+ push(@contexts,'statustocreate');
+ foreach my $type (@types) {
my @modifiable = &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);
foreach my $field (@fields) {
if (grep(/^\Q$field\E$/,@modifiable)) {
@@ -9961,7 +12232,7 @@ sub modify_selfcreation {
}
}
if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {
- foreach my $type (@{$types}) {
+ foreach my $type (@types) {
if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {
foreach my $field (@fields) {
if ($save_usermodify{'selfcreate'}{$type}{$field} ne
@@ -9973,7 +12244,7 @@ sub modify_selfcreation {
}
}
} else {
- foreach my $type (@{$types}) {
+ foreach my $type (@types) {
push(@{$changes{'selfcreate'}},$type);
}
}
@@ -10022,34 +12293,28 @@ sub modify_selfcreation {
}
} elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {
if (ref($cancreate{$item}) eq 'HASH') {
- foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
- if (ref($curr_usercreation{'cancreate'}{$item}{$curr}) eq 'HASH') {
- foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$curr}})) {
- unless ($curr_usercreation{'cancreate'}{$item}{$curr}{$field} eq $cancreate{$item}{$curr}{$field}) {
+ foreach my $type (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
+ if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {
+ foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$type}})) {
+ unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {
if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
push(@{$changes{'cancreate'}},$item);
}
}
}
- } elsif ($item eq 'selfcreateprocessing') {
- if ($cancreate{$item}{$curr} ne $curr_usercreation{'cancreate'}{$item}{$curr}) {
- if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
- push(@{$changes{'cancreate'}},$item);
- }
- }
- } else {
- if (!$cancreate{$item}{$curr}) {
+ } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
+ if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {
if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
push(@{$changes{'cancreate'}},$item);
}
}
}
}
- foreach my $field (keys(%{$cancreate{$item}})) {
- if (ref($cancreate{$item}{$field}) eq 'HASH') {
- foreach my $inner (keys(%{$cancreate{$item}{$field}})) {
- if (ref($curr_usercreation{'cancreate'}{$item}{$field}) eq 'HASH') {
- unless ($curr_usercreation{'cancreate'}{$item}{$field}{$inner} eq $cancreate{$item}{$field}{$inner}) {
+ foreach my $type (keys(%{$cancreate{$item}})) {
+ if (ref($cancreate{$item}{$type}) eq 'HASH') {
+ foreach my $field (keys(%{$cancreate{$item}{$type}})) {
+ if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {
+ unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {
if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
push(@{$changes{'cancreate'}},$item);
}
@@ -10060,14 +12325,8 @@ sub modify_selfcreation {
}
}
}
- } elsif ($item eq 'selfcreateprocessing') {
- if ($cancreate{$item}{$field} ne $curr_usercreation{'cancreate'}{$item}{$field}) {
- if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
- push(@{$changes{'cancreate'}},$item);
- }
- }
- } else {
- if (!$curr_usercreation{'cancreate'}{$item}{$field}) {
+ } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
+ if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {
if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
push(@{$changes{'cancreate'}},$item);
}
@@ -10082,11 +12341,11 @@ sub modify_selfcreation {
push(@{$changes{'cancreate'}},$item);
}
}
- } elsif (ref($cancreate{$item}) eq 'HASH') {
- if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) {
- if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
- push(@{$changes{'cancreate'}},$item);
- }
+ }
+ } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
+ if (ref($cancreate{$item}) eq 'HASH') {
+ if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
+ push(@{$changes{'cancreate'}},$item);
}
}
} elsif ($item eq 'emailusername') {
@@ -10119,6 +12378,15 @@ sub modify_selfcreation {
if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {
$save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};
}
+ if (ref($cancreate{'emailverified'}) eq 'HASH') {
+ $save_usercreate{'cancreate'}{'emailverified'} = $cancreate{'emailverified'};
+ }
+ if (ref($cancreate{'emailoptions'}) eq 'HASH') {
+ $save_usercreate{'cancreate'}{'emailoptions'} = $cancreate{'emailoptions'};
+ }
+ if (ref($cancreate{'emaildomain'}) eq 'HASH') {
+ $save_usercreate{'cancreate'}{'emaildomain'} = $cancreate{'emaildomain'};
+ }
if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
$save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};
}
@@ -10126,16 +12394,18 @@ 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,
usermodification => \%save_usermodify,
+ inststatus => \%save_inststatus,
);
+
my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,
$dom);
#
-# Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext
+# Accumulate details of changes to domain configuration for self-creation of usernames in $resulttext
#
if ($putresult eq 'ok') {
if (keys(%changes) > 0) {
@@ -10143,7 +12413,7 @@ sub modify_selfcreation {
if (ref($changes{'cancreate'}) eq 'ARRAY') {
my %lt = &selfcreation_types();
foreach my $type (@{$changes{'cancreate'}}) {
- my $chgtext;
+ my $chgtext = '';
if ($type eq 'selfcreate') {
if (@{$cancreate{$type}} == 0) {
$chgtext .= &mt('Self creation of a new user account is not permitted.');
@@ -10158,18 +12428,25 @@ sub modify_selfcreation {
if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
if (@{$cancreate{'statustocreate'}} == 0) {
- $chgtext .= ' '.
- ''.
- &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
- '';
+ $chgtext .= ''.
+ &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts via log-in or single sign-on.").
+ ' ';
}
}
}
+ if (grep(/^email$/,@{$cancreate{$type}})) {
+ if (!@statuses) {
+ $chgtext .= ''.
+ &mt("However, e-mail verification is currently set to 'unavailable' for all user types (including 'other'), so self-creation of accounts is not possible for non-institutional log-in.").
+ ' ';
+
+ }
+ }
}
}
} elsif ($type eq 'shibenv') {
if (keys(%{$cancreate{$type}}) == 0) {
- $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information');
+ $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information').' ';
} else {
$chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').
'';
@@ -10182,7 +12459,7 @@ sub modify_selfcreation {
}
}
$chgtext .= ' ';
- }
+ }
} elsif ($type eq 'statustocreate') {
if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&
(ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
@@ -10195,7 +12472,7 @@ sub modify_selfcreation {
&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
'';
}
- } elsif (ref($usertypes) eq 'HASH') {
+ } elsif (keys(%usertypes) > 0) {
if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
$chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
} else {
@@ -10206,12 +12483,12 @@ sub modify_selfcreation {
if ($case eq 'default') {
$chgtext .= ''.$othertitle.'';
} else {
- $chgtext .= ''.$usertypes->{$case}.'';
+ $chgtext .= ''.$usertypes{$case}.'';
}
}
$chgtext .= '';
if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
- $chgtext .= ' '.
+ $chgtext .= ''.
&mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').
'';
}
@@ -10223,26 +12500,129 @@ sub modify_selfcreation {
$chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');
}
}
+ $chgtext .= ' ';
}
} elsif ($type eq 'selfcreateprocessing') {
my %choices = &Apache::lonlocal::texthash (
automatic => 'Automatic approval',
approval => 'Queued for approval',
);
- if (@statuses > 1) {
- $chgtext .= &mt('Processing of requests to create account with e-mail address as username set as follows:').
- '';
- foreach my $type (@statuses) {
- if ($type eq 'default') {
- $chgtext .= '- '.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'
';
- } else {
- $chgtext .= '- '.$usertypes->{$type}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'
';
- }
- }
- $chgtext .= ' ';
+ if (@types) {
+ if (@statuses) {
+ $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:').
+ '';
+ foreach my $status (@statuses) {
+ if ($status eq 'default') {
+ $chgtext .= '- '.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'
';
+ } else {
+ $chgtext .= '- '.$usertypes{$status}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'
';
+ }
+ }
+ $chgtext .= ' ';
+ }
+ } else {
+ $chgtext .= &mt('Processing of requests to create account with e-mail verification set to: "[_1]"',
+ $choices{$cancreate{'selfcreateprocessing'}{'default'}});
+ }
+ } elsif ($type eq 'emailverified') {
+ my %options = &Apache::lonlocal::texthash (
+ all => 'Same as e-mail',
+ first => 'Omit @domain',
+ free => 'Free to choose',
+ );
+ if (@types) {
+ if (@statuses) {
+ $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').
+ '';
+ foreach my $status (@statuses) {
+ if ($status eq 'default') {
+ $chgtext .= '- '.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'
';
+ } else {
+ $chgtext .= '- '.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'
';
+ }
+ }
+ $chgtext .= ' ';
+ }
} else {
- $chgtext .= &mt('Processing of requests to create account with e-mail address as username set to: "[_1]"',
- $choices{$cancreate{'selfcreateprocessing'}{'default'}});
+ $chgtext .= &mt("For self-created accounts verified by e-mail address, user's username is: '[_1]'",
+ $options{$cancreate{'emailverified'}{'default'}});
+ }
+ } elsif ($type eq 'emailoptions') {
+ my %options = &Apache::lonlocal::texthash (
+ any => 'Any e-mail',
+ inst => 'Institutional only',
+ noninst => 'Non-institutional only',
+ custom => 'Custom restrictions',
+ );
+ if (@types) {
+ if (@statuses) {
+ $chgtext .= &mt('For self-created accounts verified by e-mail address, requirements for e-mail address are as follows:').
+ '';
+ foreach my $status (@statuses) {
+ if ($type eq 'default') {
+ $chgtext .= '- '.$othertitle.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'
';
+ } else {
+ $chgtext .= '- '.$usertypes{$status}.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'
';
+ }
+ }
+ $chgtext .= ' ';
+ }
+ } else {
+ if ($cancreate{'emailoptions'}{'default'} eq 'any') {
+ $chgtext .= &mt('For self-created accounts verified by e-mail address, any e-mail may be used');
+ } else {
+ $chgtext .= &mt('For self-created accounts verified by e-mail address, e-mail restricted to: "[_1]"',
+ $options{$cancreate{'emailoptions'}{'default'}});
+ }
+ }
+ } elsif ($type eq 'emaildomain') {
+ my $output;
+ if (@statuses) {
+ foreach my $type (@statuses) {
+ if (ref($cancreate{'emaildomain'}{$type}) eq 'HASH') {
+ if ($cancreate{'emailoptions'}{$type} eq 'inst') {
+ if ($type eq 'default') {
+ if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
+ ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {
+ $output = ''.$othertitle.' -- '.&mt('No restriction on e-mail domain').'';
+ } else {
+ $output = ''.$othertitle.' -- '.&mt("User's e-mail address needs to end: [_1]",
+ $cancreate{'emaildomain'}{$type}{'inst'}).'';
+ }
+ } else {
+ if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
+ ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {
+ $output = ''.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'';
+ } else {
+ $output = ''.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",
+ $cancreate{'emaildomain'}{$type}{'inst'}).'';
+ }
+ }
+ } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {
+ if ($type eq 'default') {
+ if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
+ ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {
+ $output = ''.$othertitle.' -- '.&mt('No restriction on e-mail domain').'';
+ } else {
+ $output = ''.$othertitle.' -- '.&mt("User's e-mail address must not end: [_1]",
+ $cancreate{'emaildomain'}{$type}{'noninst'}).'';
+ }
+ } else {
+ if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
+ ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {
+ $output = ''.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'';
+ } else {
+ $output = ''.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",
+ $cancreate{'emaildomain'}{$type}{'noninst'}).'';
+ }
+ }
+ }
+ }
+ }
+ }
+ if ($output ne '') {
+ $chgtext .= &mt('For self-created accounts verified by e-mail address:').
+ '';
}
} elsif ($type eq 'captcha') {
if ($savecaptcha{$type} eq 'notused') {
@@ -10279,11 +12659,11 @@ sub modify_selfcreation {
}
} elsif ($type eq 'emailusername') {
if (ref($cancreate{'emailusername'}) eq 'HASH') {
- if (ref($types) eq 'ARRAY') {
- foreach my $type (@{$types}) {
+ if (@statuses) {
+ foreach my $type (@statuses) {
if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {
if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {
- $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',"'$usertypes->{$type}'").
+ $chgtext .= &mt('When self-creating account with e-mail verification, the following information will be provided by [_1]:',"'$usertypes{$type}'").
'';
foreach my $field (@{$infofields}) {
if ($cancreate{'emailusername'}{$type}{$field}) {
@@ -10292,48 +12672,86 @@ sub modify_selfcreation {
}
$chgtext .= ' ';
} else {
- $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").' ';
+ $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").' ';
}
} else {
- $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").' ';
+ $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").' ';
}
}
}
}
} elsif ($type eq 'notify') {
- $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
+ my $numapprove = 0;
if (ref($changes{'cancreate'}) eq 'ARRAY') {
if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {
if ($cancreate{'notify'}{'approval'}) {
- $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
+ $chgtext .= &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
+ $numapprove ++;
}
}
}
+ unless ($numapprove) {
+ $chgtext .= &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
+ }
}
if ($chgtext) {
$resulttext .= ''.$chgtext.'';
}
}
}
- if (ref($changes{'email_rule'}) eq 'ARRAY') {
+ if ((ref($changes{'email_rule'}) eq 'ARRAY') && (@{$changes{'email_rule'}} > 0)) {
my ($emailrules,$emailruleorder) =
&Apache::lonnet::inst_userrules($dom,'email');
- my $chgtext = '';
- foreach my $type (@email_rule) {
- if (ref($emailrules->{$type}) eq 'HASH') {
- $chgtext .= '- '.$emailrules->{$type}{'name'}.'
';
+ foreach my $type (@{$changes{'email_rule'}}) {
+ if (ref($email_rule{$type}) eq 'ARRAY') {
+ my $chgtext = '';
+ foreach my $rule (@{$email_rule{$type}}) {
+ if (ref($emailrules->{$rule}) eq 'HASH') {
+ $chgtext .= '- '.$emailrules->{$rule}{'name'}.'
';
+ }
+ }
+ $chgtext .= ' ';
+ my $typename;
+ if (@types) {
+ if ($type eq 'default') {
+ $typename = $othertitle;
+ } else {
+ $typename = $usertypes{$type};
+ }
+ $chgtext .= &mt('(Affiliation: [_1])',$typename);
+ }
+ if (@{$email_rule{$type}} > 0) {
+ $resulttext .= '- '.
+ &mt('Accounts may not be created by users verified by e-mail, for e-mail addresses of the following types: ',
+ $usertypes{$type}).
+ $chgtext.
+ '
';
+ } else {
+ $resulttext .= '- '.
+ &mt('There are now no restrictions on e-mail addresses which may be used for verification when a user requests an account.').
+ '
'.
+ &mt('(Affiliation: [_1])',$typename);
+ }
}
}
- $chgtext .= ' ';
- if (@email_rule > 0) {
- $resulttext .= ''.
- &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').
- $chgtext.
- '';
- } else {
- $resulttext .= ''.
- &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').
- '';
+ }
+ if (ref($changes{'inststatus'}) eq 'ARRAY') {
+ if (ref($save_inststatus{'inststatusguest'}) eq 'ARRAY') {
+ if (@{$save_inststatus{'inststatusguest'}} > 0) {
+ my $chgtext = '';
+ foreach my $type (@{$save_inststatus{'inststatusguest'}}) {
+ $chgtext .= '- '.$usertypes{$type}.'
';
+ }
+ $chgtext .= ' ';
+ $resulttext .= ''.
+ &mt('A user will self-report one of the following affiliations when requesting an account verified by e-mail: ').
+ $chgtext.
+ '';
+ } else {
+ $resulttext .= ''.
+ &mt('No affiliations available for self-reporting when requesting an account verified by e-mail.').
+ '';
+ }
}
}
if (ref($changes{'selfcreate'}) eq 'ARRAY') {
@@ -10341,9 +12759,9 @@ sub modify_selfcreation {
my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
foreach my $type (@{$changes{'selfcreate'}}) {
my $typename = $type;
- if (ref($usertypes) eq 'HASH') {
- if ($usertypes->{$type} ne '') {
- $typename = $usertypes->{$type};
+ if (keys(%usertypes) > 0) {
+ if ($usertypes{$type} ne '') {
+ $typename = $usertypes{$type};
}
}
my @modifiable;
@@ -10366,6 +12784,12 @@ sub modify_selfcreation {
$resulttext .= '';
}
$resulttext .= '';
+ my $cachetime = 24*60*60;
+ $domdefaults{'inststatusguest'} = $save_inststatus{'inststatusguest'};
+ &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'domdefaults'} = 1;
+ }
} else {
$resulttext = &mt('No changes made to self-creation settings');
}
@@ -10380,19 +12804,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;
}
@@ -10414,9 +12844,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 => '',
@@ -10424,8 +12854,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;
}
@@ -10437,6 +12867,8 @@ sub process_captcha {
} elsif (!defined($changes->{'cancreate'})) {
$changes->{'cancreate'} = ['recaptchaversion'];
}
+ } elsif ($container eq 'passwords') {
+ $changes->{'reset'} = 1;
} else {
$changes->{'recaptchaversion'} = 1;
}
@@ -10448,6 +12880,8 @@ sub process_captcha {
} elsif (!defined($changes->{'cancreate'})) {
$changes->{'cancreate'} = ['recaptchakeys'];
}
+ } elsif ($container eq 'passwords') {
+ $changes->{'reset'} = 1;
} else {
$changes->{'recaptchakeys'} = 1;
}
@@ -10563,7 +12997,7 @@ sub modify_defaults {
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','intauth_cost','intauth_check','intauth_switch');
+ 'portal_def');
my @authtypes = ('internal','krb4','krb5','localauth');
foreach my $item (@items) {
$newvalues{$item} = $env{'form.'.$item};
@@ -10605,24 +13039,6 @@ 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};
@@ -10631,6 +13047,18 @@ sub modify_defaults {
}
$domdefaults{$item} = $newvalues{$item};
}
+ my %staticdefaults = (
+ 'intauth_cost' => 10,
+ 'intauth_check' => 0,
+ 'intauth_switch' => 0,
+ );
+ foreach my $item ('intauth_cost','intauth_check','intauth_switch') {
+ if (exists($domdefaults{$item})) {
+ $newvalues{$item} = $domdefaults{$item};
+ } else {
+ $newvalues{$item} = $staticdefaults{$item};
+ }
+ }
my %defaults_hash = (
defaults => \%newvalues,
);
@@ -10649,9 +13077,18 @@ sub modify_defaults {
}
my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');
my @allpos;
- my %guests;
my %alltypes;
- my ($currtitles,$currguests,$currorder);
+ my @inststatusguest;
+ if (ref($currinststatus) eq 'HASH') {
+ if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
+ foreach my $type (@{$currinststatus->{'inststatusguest'}}) {
+ unless (grep(/^\Q$type\E$/,@todelete)) {
+ push(@inststatusguest,$type);
+ }
+ }
+ }
+ }
+ my ($currtitles,$currorder);
if (ref($currinststatus) eq 'HASH') {
if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {
foreach my $type (@{$currinststatus->{'inststatusorder'}}) {
@@ -10666,14 +13103,8 @@ sub modify_defaults {
$allpos[$position] = $type;
$alltypes{$type} = $env{'form.inststatus_title_'.$type};
$alltypes{$type} =~ s/`//g;
- if ($env{'form.inststatus_guest_'.$type}) {
- $guests{$type} = 1;
- }
}
}
- if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
- $currguests = join(',',@{$currinststatus->{'inststatusguest'}});
- }
$currorder = join(',',@{$currinststatus->{'inststatusorder'}});
$currtitles =~ s/,$//;
}
@@ -10682,9 +13113,6 @@ sub modify_defaults {
my $newtype = $env{'form.addinststatus'};
$newtype =~ s/\W//g;
unless (exists($alltypes{$newtype})) {
- if ($env{'form.addinststatus_guest'}) {
- $guests{$newtype} = 1;
- }
$alltypes{$newtype} = $env{'form.addinststatus_title'};
$alltypes{$newtype} =~ s/`//g;
my $position = $env{'form.addinststatus_pos'};
@@ -10694,13 +13122,10 @@ sub modify_defaults {
}
}
}
- my (@orderedstatus,@orderedguests);
+ my @orderedstatus;
foreach my $type (@allpos) {
unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {
push(@orderedstatus,$type);
- if ($guests{$type}) {
- push(@orderedguests,$type);
- }
}
}
foreach my $type (keys(%alltypes)) {
@@ -10711,7 +13136,7 @@ sub modify_defaults {
$defaults_hash{'inststatus'} = {
inststatustypes => \%alltypes,
inststatusorder => \@orderedstatus,
- inststatusguest => \@orderedguests,
+ inststatusguest => \@inststatusguest,
};
if (ref($defaults_hash{'inststatus'}) eq 'HASH') {
foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {
@@ -10721,9 +13146,6 @@ sub modify_defaults {
if ($currorder ne join(',',@orderedstatus)) {
$changes{'inststatus'}{'inststatusorder'} = 1;
}
- if ($currguests ne join(',',@orderedguests)) {
- $changes{'inststatus'}{'inststatusguest'} = 1;
- }
my $newtitles;
foreach my $item (@orderedstatus) {
$newtitles .= $alltypes{$item}.',';
@@ -10742,26 +13164,15 @@ sub modify_defaults {
foreach my $item (sort(keys(%changes))) {
if ($item eq 'inststatus') {
if (ref($changes{'inststatus'}) eq 'HASH') {
- if (($changes{'inststatus'}{'inststatustypes'}) || $changes{'inststatus'}{'inststatusorder'}) {
+ if (@orderedstatus) {
$resulttext .= ''.&mt('Institutional user status types set to:').' ';
foreach my $type (@orderedstatus) {
$resulttext .= $alltypes{$type}.', ';
}
$resulttext =~ s/, $//;
$resulttext .= '';
- }
- if ($changes{'inststatus'}{'inststatusguest'}) {
- $resulttext .= '';
- if (@orderedguests) {
- $resulttext .= &mt('Types assignable to "non-institutional" usernames set to:').' ';
- foreach my $type (@orderedguests) {
- $resulttext .= $alltypes{$type}.', ';
- }
- $resulttext =~ s/, $//;
- } else {
- $resulttext .= &mt('Types assignable to "non-institutional" usernames set to none.');
- }
- $resulttext .= '';
+ } else {
+ $resulttext .= ''.&mt('Institutional user status types deleted').'';
}
}
} else {
@@ -10777,28 +13188,6 @@ 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";
@@ -10847,7 +13236,7 @@ sub modify_scantron {
my $custom = 'custom.tab';
my $default = 'default.tab';
my $servadm = $r->dir_config('lonAdmEMail');
- my ($configuserok,$author_ok,$switchserver) =
+ my ($configuserok,$author_ok,$switchserver) =
&config_check($dom,$confname,$servadm);
if ($env{'form.scantronformat.filename'} ne '') {
my $error;
@@ -10882,6 +13271,67 @@ sub modify_scantron {
if ($env{'form.scantronformat_del'}) {
$confhash{'scantron'}{'scantronformat'} = '';
$changes{'scantronformat'} = 1;
+ } else {
+ $confhash{'scantron'}{'scantronformat'} = $domconfig{'scantron'}{'scantronformat'};
+ }
+ }
+ }
+ my @options = ('hdr','pad','rem');
+ my @fields = &scantroncsv_fields();
+ my %titles = &scantronconfig_titles();
+ my @formats = &Apache::loncommon::get_env_multiple('form.scantronconfig');
+ my ($newdat,$currdat,%newcol,%currcol);
+ if (grep(/^dat$/,@formats)) {
+ $confhash{'scantron'}{config}{dat} = 1;
+ $newdat = 1;
+ } else {
+ $newdat = 0;
+ }
+ if (grep(/^csv$/,@formats)) {
+ my %bynum;
+ foreach my $field (@fields) {
+ if ($env{'form.scantronconfig_csv_'.$field} =~ /^(\d+)$/) {
+ my $posscol = $1;
+ if (($posscol < 20) && (!$bynum{$posscol})) {
+ $confhash{'scantron'}{config}{csv}{fields}{$field} = $posscol;
+ $bynum{$posscol} = $field;
+ $newcol{$field} = $posscol;
+ }
+ }
+ }
+ if (keys(%newcol)) {
+ foreach my $option (@options) {
+ if ($env{'form.scantroncsv_'.$option}) {
+ $confhash{'scantron'}{config}{csv}{options}{$option} = 1;
+ }
+ }
+ }
+ }
+ $currdat = 1;
+ if (ref($domconfig{'scantron'}) eq 'HASH') {
+ if (ref($domconfig{'scantron'}{'config'}) eq 'HASH') {
+ unless (exists($domconfig{'scantron'}{'config'}{'dat'})) {
+ $currdat = 0;
+ }
+ if (ref($domconfig{'scantron'}{'config'}{'csv'}) eq 'HASH') {
+ if (ref($domconfig{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {
+ %currcol = %{$domconfig{'scantron'}{'config'}{'csv'}{'fields'}};
+ }
+ }
+ }
+ }
+ if ($currdat != $newdat) {
+ $changes{'config'} = 1;
+ } else {
+ foreach my $field (@fields) {
+ if ($currcol{$field} ne '') {
+ if ($currcol{$field} ne $newcol{$field}) {
+ $changes{'config'} = 1;
+ last;
+ }
+ } elsif ($newcol{$field} ne '') {
+ $changes{'config'} = 1;
+ last;
}
}
}
@@ -10892,29 +13342,64 @@ sub modify_scantron {
if (keys(%changes) > 0) {
if (ref($confhash{'scantron'}) eq 'HASH') {
$resulttext = &mt('Changes made:').'';
- if ($confhash{'scantron'}{'scantronformat'} eq '') {
- $resulttext .= '- '.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'
';
- } else {
- $resulttext .= '- '.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'
';
+ if ($changes{'scantronformat'}) {
+ if ($confhash{'scantron'}{'scantronformat'} eq '') {
+ $resulttext .= '- '.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'
';
+ } else {
+ $resulttext .= '- '.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'
';
+ }
+ }
+ if ($changes{'config'}) {
+ if (ref($confhash{'scantron'}{'config'}) eq 'HASH') {
+ if ($confhash{'scantron'}{'config'}{'dat'}) {
+ $resulttext .= '- '.&mt('Bubblesheet data upload formats includes .dat format').'
';
+ }
+ if (ref($confhash{'scantron'}{'config'}{'csv'}) eq 'HASH') {
+ if (ref($confhash{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {
+ if (keys(%{$confhash{'scantron'}{'config'}{'csv'}{'fields'}})) {
+ $resulttext .= '- '.&mt('Bubblesheet data upload formats includes .csv format, with following fields/column numbers supported:').'
';
+ foreach my $field (@fields) {
+ if ($confhash{'scantron'}{'config'}{'csv'}{'fields'}{$field} ne '') {
+ my $showcol = $confhash{'scantron'}{'config'}{'csv'}{'fields'}{$field} + 1;
+ $resulttext .= '- '.$titles{$field}.': '.$showcol.'
';
+ }
+ }
+ $resulttext .= ' ';
+ if (ref($confhash{'scantron'}{'config'}{'csv'}{'options'}) eq 'HASH') {
+ if (keys(%{$confhash{'scantron'}{'config'}{'csv'}{'options'}})) {
+ $resulttext .= '- '.&mt('Bubblesheet data upload formats includes .csv format, with following options:').'
';
+ foreach my $option (@options) {
+ if ($confhash{'scantron'}{'config'}{'csv'}{'options'}{$option} ne '') {
+ $resulttext .= '- '.$titles{$option}.'
';
+ }
+ }
+ $resulttext .= ' ';
+ }
+ }
+ }
+ }
+ }
+ } else {
+ $resulttext .= '- '.&mt('No bubblesheet data upload formats set -- will default to assuming .dat format').'
';
+ }
}
$resulttext .= ' ';
} else {
$resulttext = &mt('Changes made to bubblesheet format file.');
}
- $resulttext .= '';
&Apache::loncommon::devalidate_domconfig_cache($dom);
if (ref($lastactref) eq 'HASH') {
$lastactref->{'domainconfig'} = 1;
}
} else {
- $resulttext = &mt('No changes made to bubblesheet format file');
+ $resulttext = &mt('No changes made to bubblesheet format settings');
}
} else {
$resulttext = ''.
&mt('An error occurred: [_1]',$putresult).'';
}
} else {
- $resulttext = &mt('No changes made to bubblesheet format file');
+ $resulttext = &mt('No changes made to bubblesheet format settings');
}
if ($errors) {
$resulttext .= &mt('The following errors occurred: ').''.
@@ -11163,6 +13648,10 @@ sub modify_coursecategories {
}
$resulttext .= ' ';
}
+ &Apache::lonnet::do_cache_new('cats',$dom,$cathash,3600);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'cats'} = 1;
+ }
}
$resulttext .= '';
if ($changes{'unauth'} || $changes{'auth'}) {
@@ -11559,7 +14048,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',
);
@@ -11656,7 +14145,11 @@ sub modify_coursedefaults {
postsubmit => 60,
mysqltables => 172800,
);
-
+ my %texoptions = (
+ MathJax => 'MathJax',
+ mimetex => &mt('Convert to Images'),
+ tth => &mt('TeX to HTML'),
+ );
$defaultshash{'coursedefaults'} = {};
if (ref($domconfig{'coursedefaults'}) ne 'HASH') {
@@ -11703,7 +14196,6 @@ sub modify_coursedefaults {
$defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;
}
if ($currdef ne $newdef) {
- my $staticdef;
if ($item eq 'anonsurvey_threshold') {
unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {
$changes{$item} = 1;
@@ -11716,6 +14208,21 @@ sub modify_coursedefaults {
}
}
}
+ my $texengine;
+ if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {
+ $texengine = $env{'form.texengine'};
+ my $currdef = $domconfig{'coursedefaults'}{'texengine'};
+ if ($currdef eq '') {
+ unless ($texengine eq $Apache::lonnet::deftex) {
+ $changes{'texengine'} = 1;
+ }
+ } elsif ($currdef ne $texengine) {
+ $changes{'texengine'} = 1;
+ }
+ }
+ if ($texengine ne '') {
+ $defaultshash{'coursedefaults'}{'texengine'} = $texengine;
+ }
my $currclone = $domconfig{'coursedefaults'}{'canclone'};
my @currclonecode;
if (ref($currclone) eq 'HASH') {
@@ -11836,8 +14343,8 @@ sub modify_coursedefaults {
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
- ($changes{'canclone'}) || ($changes{'mysqltables'})) {
- foreach my $item ('uselcmath','usejsme') {
+ ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'})) {
+ foreach my $item ('uselcmath','usejsme','texengine') {
if ($changes{$item}) {
$domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
}
@@ -11900,6 +14407,11 @@ sub modify_coursedefaults {
} else {
$resulttext .= ''.&mt('Molecule editor uses JME (Java), if supported by client OS.').'';
}
+ } elsif ($item eq 'texengine') {
+ if ($defaultshash{'coursedefaults'}{'texengine'} ne '') {
+ $resulttext .= ''.&mt('Default method to display mathematics set to: "[_1]"',
+ $texoptions{$defaultshash{'coursedefaults'}{'texengine'}}).'';
+ }
} elsif ($item eq 'anonsurvey_threshold') {
$resulttext .= ''.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'';
} elsif ($item eq 'uploadquota') {
@@ -12224,12 +14736,12 @@ sub modify_selfenrollment {
$resulttext .= '';
}
}
- if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {
- my $cachetime = 24*60*60;
- &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
- if (ref($lastactref) eq 'HASH') {
- $lastactref->{'domdefaults'} = 1;
- }
+ }
+ if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {
+ my $cachetime = 24*60*60;
+ &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'domdefaults'} = 1;
}
}
$resulttext .= '';
@@ -12410,6 +14922,7 @@ sub modify_usersessions {
}
}
$defaultshash{'usersessions'}{'offloadnow'} = {};
+ $defaultshash{'usersessions'}{'offloadoth'} = {};
my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow');
my @okoffload;
if (@offloadnow) {
@@ -12426,6 +14939,22 @@ sub modify_usersessions {
}
}
}
+ my @offloadoth = &Apache::loncommon::get_env_multiple('form.offloadoth');
+ my @okoffloadoth;
+ if (@offloadoth) {
+ foreach my $server (@offloadoth) {
+ if (&Apache::lonnet::hostname($server) ne '') {
+ unless (grep(/^\Q$server\E$/,@okoffloadoth)) {
+ push(@okoffloadoth,$server);
+ }
+ }
+ }
+ if (@okoffloadoth) {
+ foreach my $lonhost (@okoffloadoth) {
+ $defaultshash{'usersessions'}{'offloadoth'}{$lonhost} = 1;
+ }
+ }
+ }
if (ref($domconfig{'usersessions'}) eq 'HASH') {
if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {
if (ref($changes{'spares'}) eq 'HASH') {
@@ -12436,26 +14965,38 @@ sub modify_usersessions {
} else {
$savespares = 1;
}
- if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') {
- foreach my $lonhost (keys(%{$domconfig{'usersessions'}{'offloadnow'}})) {
- unless ($defaultshash{'usersessions'}{'offloadnow'}{$lonhost}) {
- $changes{'offloadnow'} = 1;
- last;
- }
- }
- unless ($changes{'offloadnow'}) {
- foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {
- unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
- $changes{'offloadnow'} = 1;
+ foreach my $offload ('offloadnow','offloadoth') {
+ if (ref($domconfig{'usersessions'}{$offload}) eq 'HASH') {
+ foreach my $lonhost (keys(%{$domconfig{'usersessions'}{$offload}})) {
+ unless ($defaultshash{'usersessions'}{$offload}{$lonhost}) {
+ $changes{$offload} = 1;
last;
}
}
+ unless ($changes{$offload}) {
+ foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{$offload}})) {
+ unless ($domconfig{'usersessions'}{$offload}{$lonhost}) {
+ $changes{$offload} = 1;
+ last;
+ }
+ }
+ }
+ } else {
+ if (($offload eq 'offloadnow') && (@okoffload)) {
+ $changes{'offloadnow'} = 1;
+ }
+ if (($offload eq 'offloadoth') && (@okoffloadoth)) {
+ $changes{'offloadoth'} = 1;
+ }
}
- } elsif (@okoffload) {
+ }
+ } else {
+ if (@okoffload) {
$changes{'offloadnow'} = 1;
}
- } elsif (@okoffload) {
- $changes{'offloadnow'} = 1;
+ if (@okoffloadoth) {
+ $changes{'offloadoth'} = 1;
+ }
}
my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');
if ((keys(%changes) > 0) || ($savespares)) {
@@ -12472,11 +15013,16 @@ sub modify_usersessions {
if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {
$domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'};
}
+ if (ref($defaultshash{'usersessions'}{'offloadoth'}) eq 'HASH') {
+ $domdefaults{'offloadoth'} = $defaultshash{'usersessions'}{'offloadoth'};
+ }
}
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();
@@ -12543,16 +15089,31 @@ sub modify_usersessions {
if ($changes{'offloadnow'}) {
if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {
if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) {
- $resulttext .= ''.&mt('Switch active users on next access, for server(s):').'';
+ $resulttext .= '- '.&mt('Switch any active user on next access, for server(s):').'
';
foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) {
$resulttext .= '- '.$lonhost.'
';
}
$resulttext .= ' ';
} else {
- $resulttext .= ' - '.&mt('No servers now set to switch active users on next access.');
+ $resulttext .= '
- '.&mt('No servers now set to switch any active user on next access.');
}
} else {
- $resulttext .= '
- '.&mt('No servers now set to switch active users on next access.').'
';
+ $resulttext .= '- '.&mt('No servers now set to switch any active user on next access.').'
';
+ }
+ }
+ if ($changes{'offloadoth'}) {
+ if (ref($defaultshash{'usersessions'}{'offloadoth'}) eq 'HASH') {
+ if (keys(%{$defaultshash{'usersessions'}{'offloadoth'}}) > 0) {
+ $resulttext .= '- '.&mt('Switch other institutions on next access, for server(s):').'
';
+ foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadoth'}}))) {
+ $resulttext .= '- '.$lonhost.'
';
+ }
+ $resulttext .= ' ';
+ } else {
+ $resulttext .= ' - '.&mt('No servers now set to switch other institutions on next access.');
+ }
+ } else {
+ $resulttext .= '
- '.&mt('No servers now set to switch other institutions on next access.').'
';
}
}
$resulttext .= ' ';
@@ -12580,12 +15141,12 @@ sub modify_loadbalancing {
my @sparestypes = ('primary','default');
my %typetitles = &sparestype_titles();
my $resulttext;
- my (%currbalancer,%currtargets,%currrules,%existing);
+ my (%currbalancer,%currtargets,%currrules,%existing,%currcookies);
if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
%existing = %{$domconfig{'loadbalancing'}};
}
&get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
- \%currtargets,\%currrules);
+ \%currtargets,\%currrules,\%currcookies);
my ($saveloadbalancing,%defaultshash,%changes);
my ($alltypes,$othertypes,$titles) =
&loadbalancing_titles($dom,$intdom,$usertypes,$types);
@@ -12637,6 +15198,18 @@ sub modify_loadbalancing {
}
$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
}
+ if ($env{'form.loadbalancing_cookie_'.$i}) {
+ $defaultshash{'loadbalancing'}{$balancer}{'cookie'} = 1;
+ if (exists($currbalancer{$balancer})) {
+ unless ($currcookies{$balancer}) {
+ $changes{'curr'}{$balancer}{'cookie'} = 1;
+ }
+ }
+ } elsif (exists($currbalancer{$balancer})) {
+ if ($currcookies{$balancer}) {
+ $changes{'curr'}{$balancer}{'cookie'} = 1;
+ }
+ }
if (ref($currtargets{$balancer}) eq 'HASH') {
foreach my $sparetype (@sparestypes) {
if (ref($currtargets{$balancer}{$sparetype}) eq 'ARRAY') {
@@ -12790,24 +15363,28 @@ sub modify_loadbalancing {
}
}
}
- if (keys(%toupdate)) {
- my %thismachine;
- my $updatedhere;
- my $cachetime = 60*60*24;
- map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
- foreach my $lonhost (keys(%toupdate)) {
- if ($thismachine{$lonhost}) {
- unless ($updatedhere) {
- &Apache::lonnet::do_cache_new('loadbalancing',$dom,
- $defaultshash{'loadbalancing'},
- $cachetime);
- $updatedhere = 1;
- }
- } else {
- my $cachekey = &escape('loadbalancing').':'.&escape($dom);
- &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
- }
+ if ($changes{'curr'}{$balancer}{'cookie'}) {
+ $resulttext .= ''.&mt('Load Balancer: [_1] -- cookie use enabled',
+ $balancer).'';
+ }
+ }
+ }
+ if (keys(%toupdate)) {
+ my %thismachine;
+ my $updatedhere;
+ my $cachetime = 60*60*24;
+ map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
+ foreach my $lonhost (keys(%toupdate)) {
+ if ($thismachine{$lonhost}) {
+ unless ($updatedhere) {
+ &Apache::lonnet::do_cache_new('loadbalancing',$dom,
+ $defaultshash{'loadbalancing'},
+ $cachetime);
+ $updatedhere = 1;
}
+ } else {
+ my $cachekey = &escape('loadbalancing').':'.&escape($dom);
+ &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
}
}
}
@@ -13019,12 +15596,12 @@ sub lonbalance_targets_js {
}
push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');
$allinsttypes = join("','",@alltypes);
- my (%currbalancer,%currtargets,%currrules,%existing);
+ my (%currbalancer,%currtargets,%currrules,%existing,%currcookies);
if (ref($settings) eq 'HASH') {
%existing = %{$settings};
}
&get_loadbalancers_config($servers,\%existing,\%currbalancer,
- \%currtargets,\%currrules);
+ \%currtargets,\%currrules,\%currcookies);
my $balancers = join("','",sort(keys(%currbalancer)));
return <<"END";
@@ -13509,6 +16086,7 @@ function toggleDisplay(domForm,caller) {
var optionsElement = domForm.coursecredits;
var checkval = 1;
var dispval = 'block';
+ var selfcreateRegExp = /^cancreate_emailverified/;
if (caller == 'emailoptions') {
optionsElement = domForm.cancreate_email;
}
@@ -13519,6 +16097,11 @@ function toggleDisplay(domForm,caller) {
optionsElement = domForm.canclone;
checkval = 'instcode';
}
+ if (selfcreateRegExp.test(caller)) {
+ optionsElement = domForm.elements[caller];
+ checkval = 'other';
+ dispval = 'inline'
+ }
if (optionsElement.length) {
var currval;
for (var i=0; i |
|