'.
''.&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) {
@@ -6312,10 +8161,14 @@ sub captcha_choice {
$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'}) {
@@ -6355,7 +8208,7 @@ sub captcha_choice {
$css_class .= ' style="'.$rowstyle.'"';
}
my $output = ''.
- ''.$rowname.' | '."\n".
+ ' | '.$rowname.' | '."\n".
''."\n";
foreach my $option ('original','recaptcha','notused') {
$output .= ' | ';
if ($item eq 'auth_def') {
- my @authtypes = ('internal','krb4','krb5','localauth');
+ my @authtypes = ('internal','krb4','krb5','localauth','lti');
my %shortauth = (
internal => 'int',
krb4 => 'krb4',
krb5 => 'krb5',
- localauth => 'loc'
+ localauth => 'loc',
+ lti => 'lti',
);
my %authnames = &authtype_names();
foreach my $auth (@authtypes) {
@@ -6592,85 +8447,6 @@ sub print_defaults {
$datatable .= ' | ';
$rownum ++;
}
- } elsif ($position eq 'middle') {
- my @items = ('intauth_cost','intauth_check','intauth_switch');
- my %defaults;
- if (ref($settings) eq 'HASH') {
- %defaults = %{$settings};
- if ($defaults{'intauth_cost'} !~ /^\d+$/) {
- $defaults{'intauth_cost'} = 10;
- }
- if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) {
- $defaults{'intauth_check'} = 0;
- }
- if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) {
- $defaults{'intauth_switch'} = 0;
- }
- } else {
- %defaults = (
- 'intauth_cost' => 10,
- 'intauth_check' => 0,
- 'intauth_switch' => 0,
- );
- }
- foreach my $item (@items) {
- if ($rownum%2) {
- $css_class = '';
- } else {
- $css_class = ' class="LC_odd_row" ';
- }
- $datatable .= ''.
- ''.$titles->{$item}.
- ' | ';
- if ($item eq 'intauth_switch') {
- my @options = (0,1,2);
- my %optiondesc = &Apache::lonlocal::texthash (
- 0 => 'No',
- 1 => 'Yes',
- 2 => 'Yes, and copy existing passwd file to passwd.bak file',
- );
- $datatable .= '';
- } elsif ($item eq 'intauth_check') {
- my @options = (0,1,2);
- my %optiondesc = &Apache::lonlocal::texthash (
- 0 => 'No',
- 1 => 'Yes, allow login then update passwd file using default cost (if higher)',
- 2 => 'Yes, disallow login if stored cost is less than domain default',
- );
- $datatable .= '';
- } else {
- $datatable .= '';
- }
- $datatable .= ' | ';
- $rownum ++;
- }
} else {
my %defaults;
if (ref($settings) eq 'HASH') {
@@ -6763,6 +8539,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;
@@ -6789,8 +8617,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)) {
@@ -6799,7 +8627,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},
@@ -6810,13 +8638,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).'';
}
@@ -6936,6 +8764,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 .= ''.(' '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;
@@ -6978,7 +8929,7 @@ sub print_coursecategories {
''.$lt{$type}.' ';
}
- $datatable .= '';
+ $datatable .= '';
$itemcount ++;
}
$$rowtotal += $itemcount;
@@ -7064,7 +9015,7 @@ sub print_coursecategories {
$can_catcomm_dom.' value="dom" />'.$level{'dom'}.' '.
''.
- ''.
+ ' '.
''.$title{'togglecatsplace'}.' | '.
' | '
+ $datatable .= ' '.$hdritem->{'header'}->[1]->{'col2'}.' | '
.&initialize_categories($itemcount);
}
$$rowtotal += $itemcount;
@@ -7269,7 +9220,7 @@ sub print_serverstatuses {
''.
''.
- ''."\n";
+ ''."\n";
}
$$rowtotal += $rownum;
return $datatable;
@@ -7284,35 +9235,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 '') {
@@ -7366,15 +9289,100 @@ $jstext
return;
}
-$intauthjs
-
// ]]>
ENDSCRIPT
+ }
+ return;
+}
+
+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 {
@@ -7497,20 +9505,23 @@ sub initialize_categories {
communities => 'Communities',
placement => 'Placement Tests',
);
- my $select0 = ' selected="selected"';
- my $select1 = '';
+ my %selnum = (
+ instcode => '0',
+ communities => '1',
+ placement => '2',
+ );
+ my %selected;
foreach my $default ('instcode','communities','placement') {
$css_class = $itemcount%2?' class="LC_odd_row"':'';
- $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"';
- if (($default eq 'communities') || ($default eq 'placement')) {
- $select1 = $select0;
- $select0 = '';
- }
+ $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','0'".');"';
+ map { $selected{$selnum{$_}} = '' } keys(%selnum);
+ $selected{$selnum{$default}} = ' selected="selected"';
$datatable .= ''
- .' '
+ .' '
.$default_names{$default}
.' | '
.' | '.&mt('Name:')
- .' | ';
+ .''
+ .' '
+ .&mt('Add category').''.&mt('Name:')
+ .' '
+ .' | ';
return $datatable;
}
@@ -7582,7 +9595,7 @@ sub build_category_rows {
pop(@{$path});
}
} else {
- $text .= &mt('Add subcategory:').' '.&mt('Add subcategory:').'';
+ $text .= ''.&mt('Add subcategory:').' | ';
}
}
}
@@ -7615,7 +9628,7 @@ sub build_category_rows {
sub modifiable_userdata_row {
my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,
- $rowid,$customcss,$rowstyle) = @_;
+ $rowid,$customcss,$rowstyle,$itemdesc) = @_;
my ($role,$rolename,$statustype);
$role = $item;
if ($context eq 'cancreate') {
@@ -7636,6 +9649,10 @@ sub modifiable_userdata_row {
} else {
$rolename = $role;
}
+ } elsif ($context eq 'lti') {
+ $rolename = &mt('Institutional data used (if available)');
+ } elsif ($context eq 'privacy') {
+ $rolename = $itemdesc;
} else {
if ($role eq 'cr') {
$rolename = &mt('Custom role');
@@ -7678,30 +9695,39 @@ sub modifiable_userdata_row {
'';
my $rem;
my %checks;
+ my %current;
if (ref($settings) eq 'HASH') {
- if (ref($settings->{$context}) eq 'HASH') {
+ my $hashref;
+ if ($context eq 'lti') {
+ if (ref($settings) eq 'HASH') {
+ $hashref = $settings->{'instdata'};
+ }
+ } elsif ($context eq 'privacy') {
+ my ($key,$inner) = split(/_/,$role);
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{$key}) eq 'HASH') {
+ $hashref = $settings->{$key}->{$inner};
+ }
+ }
+ } elsif (ref($settings->{$context}) eq 'HASH') {
if (ref($settings->{$context}->{$role}) eq 'HASH') {
- my $hashref = $settings->{$context}->{$role};
- if ($role eq 'emailusername') {
- if ($statustype) {
- if (ref($settings->{$context}->{$role}->{$statustype}) eq 'HASH') {
- $hashref = $settings->{$context}->{$role}->{$statustype};
- if (ref($hashref) eq 'HASH') {
- foreach my $field (@fields) {
- if ($hashref->{$field}) {
- $checks{$field} = $hashref->{$field};
- }
- }
- }
- }
+ $hashref = $settings->{'lti_instdata'};
+ }
+ if ($role eq 'emailusername') {
+ if ($statustype) {
+ if (ref($settings->{$context}->{$role}->{$statustype}) eq 'HASH') {
+ $hashref = $settings->{$context}->{$role}->{$statustype};
}
- } else {
- if (ref($hashref) eq 'HASH') {
- foreach my $field (@fields) {
- if ($hashref->{$field}) {
- $checks{$field} = ' checked="checked" ';
- }
- }
+ }
+ }
+ }
+ if (ref($hashref) eq 'HASH') {
+ foreach my $field (@fields) {
+ if ($hashref->{$field}) {
+ if ($role eq 'emailusername') {
+ $checks{$field} = $hashref->{$field};
+ } else {
+ $checks{$field} = ' checked="checked" ';
}
}
}
@@ -7720,8 +9746,26 @@ sub modifiable_userdata_row {
my $check = ' ';
unless ($role eq 'emailusername') {
if (exists($checks{$fields[$i]})) {
- $check = $checks{$fields[$i]}
- } else {
+ $check = $checks{$fields[$i]};
+ } elsif ($context eq 'privacy') {
+ if ($role =~ /^priv_(domain|course)$/) {
+ if (ref($settings) ne 'HASH') {
+ $check = ' checked="checked" ';
+ }
+ } elsif ($role =~ /^priv_(author|community)$/) {
+ if (ref($settings) ne 'HASH') {
+ unless ($fields[$i] eq 'id') {
+ $check = ' checked="checked" ';
+ }
+ }
+ } elsif ($role =~ /^(unpriv|othdom)_/) {
+ if (ref($settings) ne 'HASH') {
+ if (($fields[$i] eq 'lastname') || ($fields[$i] eq 'firstname')) {
+ $check = ' checked="checked" ';
+ }
+ }
+ }
+ } elsif ($context ne 'lti') {
if ($role eq 'st') {
if (ref($settings) ne 'HASH') {
$check = ' checked="checked" ';
@@ -7731,6 +9775,7 @@ sub modifiable_userdata_row {
}
$output .= ''.
'';
+ my $prefix = 'canmodify';
if ($role eq 'emailusername') {
unless ($checks{$fields[$i]} =~ /^(required|optional)$/) {
$checks{$fields[$i]} = 'omit';
@@ -7741,13 +9786,18 @@ sub modifiable_userdata_row {
$checked='checked="checked" ';
}
$output .= ''.(' ' x2);
}
$output .= ''.$fieldtitles{$fields[$i]}.'';
} else {
+ if ($context eq 'lti') {
+ $prefix = 'lti';
+ } elsif ($context eq 'privacy') {
+ $prefix = 'privacy';
+ }
$output .= '';
}
@@ -7776,6 +9826,7 @@ sub insttypes_row {
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') {
@@ -7822,6 +9873,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" ';
}
@@ -7836,29 +9891,38 @@ sub insttypes_row {
$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 .= '';
}
- $output .= ' | '.
- ' | | ';
+ $output .= '
| ';
return $output;
}
@@ -8818,7 +10882,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);
@@ -8892,14 +10956,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'));
}
@@ -8960,7 +11024,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;
@@ -9040,7 +11105,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=$_;
@@ -9074,7 +11139,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) {
@@ -9100,7 +11165,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;
@@ -9142,7 +11207,7 @@ sub modify_quotas {
$context = $action;
}
if ($context eq 'requestcourses') {
- @usertools = ('official','unofficial','community','textbook','placement');
+ @usertools = ('official','unofficial','community','textbook','placement','lti');
@options =('norequest','approval','validate','autolimit');
%validations = &Apache::lonnet::auto_courserequest_checks($dom);
%titles = &courserequest_titles();
@@ -9191,7 +11256,7 @@ sub modify_quotas {
my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');
@approvalnotify = sort(@approvalnotify);
$confhash{'notify'}{'approval'} = join(',',@approvalnotify);
- my @crstypes = ('official','unofficial','community','textbook','placement');
+ my @crstypes = ('official','unofficial','community','textbook','placement','lti');
my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');
foreach my $type (@hasuniquecode) {
if (grep(/^\Q$type\E$/,@crstypes)) {
@@ -9890,8 +11955,11 @@ sub modify_ltitools {
$allpos[$position] = $newid;
}
$changes{$newid} = 1;
- foreach my $item ('title','url','key','secret') {
+ foreach my $item ('title','url','key','secret','lifetime') {
$env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
+ if ($item eq 'lifetime') {
+ $env{'form.ltitools_add_'.$item} =~ s/[^\d.]//g;
+ }
if ($env{'form.ltitools_add_'.$item}) {
if (($item eq 'key') || ($item eq 'secret')) {
$encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item};
@@ -9906,6 +11974,11 @@ sub modify_ltitools {
if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
$confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
}
+ if ($env{'form.ltitools_add_sigmethod'} eq 'HMAC-SHA256') {
+ $confhash{$newid}{'sigmethod'} = $env{'form.ltitools_add_sigmethod'};
+ } else {
+ $confhash{$newid}{'sigmethod'} = 'HMAC-SHA1';
+ }
foreach my $item ('width','height','linktext','explanation') {
$env{'form.ltitools_add_'.$item} =~ s/^\s+//;
$env{'form.ltitools_add_'.$item} =~ s/\s+$//;
@@ -9927,8 +12000,15 @@ sub modify_ltitools {
$confhash{$newid}{'display'}{'target'} = 'iframe';
}
foreach my $item ('passback','roster') {
- if ($env{'form.ltitools_add_'.$item}) {
+ if ($env{'form.ltitools_'.$item.'_add'}) {
$confhash{$newid}{$item} = 1;
+ if ($env{'form.ltitools_'.$item.'valid_add'} ne '') {
+ my $lifetime = $env{'form.ltitools_'.$item.'valid_add'};
+ $lifetime =~ s/^\s+|\s+$//g;
+ if ($lifetime =~ /^\d+\.?\d*$/) {
+ $confhash{$newid}{$item.'valid'} = $lifetime;
+ }
+ }
}
}
if ($env{'form.ltitools_add_image.filename'} ne '') {
@@ -9961,6 +12041,13 @@ sub modify_ltitools {
}
}
}
+ if (ref($confhash{$newid}{'fields'}) eq 'HASH') {
+ if ($confhash{$newid}{'fields'}{'user'}) {
+ if ($env{'form.ltitools_userincdom_add'}) {
+ $confhash{$newid}{'incdom'} = 1;
+ }
+ }
+ }
my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');
foreach my $item (@courseconfig) {
$confhash{$newid}{'crsconf'}{$item} = 1;
@@ -10007,7 +12094,7 @@ sub modify_ltitools {
} else {
my $newpos = $env{'form.ltitools_'.$itemid};
$newpos =~ s/\D+//g;
- foreach my $item ('title','url') {
+ foreach my $item ('title','url','lifetime') {
$confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
$changes{$itemid} = 1;
@@ -10025,6 +12112,18 @@ sub modify_ltitools {
if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {
$confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};
}
+ if ($env{'form.ltitools_sigmethod_'.$i} eq 'HMAC-SHA256') {
+ $confhash{$itemid}{'sigmethod'} = $env{'form.ltitools_sigmethod_'.$i};
+ } else {
+ $confhash{$itemid}{'sigmethod'} = 'HMAC-SHA1';
+ }
+ if ($domconfig{$action}{$itemid}{'sigmethod'} eq '') {
+ if ($confhash{$itemid}{'sigmethod'} ne 'HMAC-SHA1') {
+ $changes{$itemid} = 1;
+ }
+ } elsif ($domconfig{$action}{$itemid}{'sigmethod'} ne $confhash{$itemid}{'sigmethod'}) {
+ $changes{$itemid} = 1;
+ }
foreach my $size ('width','height') {
$env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;
$env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;
@@ -10078,13 +12177,23 @@ sub modify_ltitools {
foreach my $extra ('passback','roster') {
if ($env{'form.ltitools_'.$extra.'_'.$i}) {
$confhash{$itemid}{$extra} = 1;
+ if ($env{'form.ltitools_'.$extra.'valid_'.$i} ne '') {
+ my $lifetime = $env{'form.ltitools_'.$extra.'valid_'.$i};
+ $lifetime =~ s/^\s+|\s+$//g;
+ if ($lifetime =~ /^\d+\.?\d*$/) {
+ $confhash{$itemid}{$extra.'valid'} = $lifetime;
+ }
+ }
}
if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) {
$changes{$itemid} = 1;
}
+ if ($domconfig{$action}{$itemid}{$extra.'valid'} ne $confhash{$itemid}{$extra.'valid'}) {
+ $changes{$itemid} = 1;
+ }
}
my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);
- foreach my $item ('label','title','target','linktext','explanation') {
+ foreach my $item ('label','title','target','linktext','explanation','append') {
if (grep(/^\Q$item\E$/,@courseconfig)) {
$confhash{$itemid}{'crsconf'}{$item} = 1;
if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {
@@ -10128,6 +12237,16 @@ sub modify_ltitools {
}
}
}
+ if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
+ if ($confhash{$itemid}{'fields'}{'user'}) {
+ if ($env{'form.ltitools_userincdom_'.$i}) {
+ $confhash{$itemid}{'incdom'} = 1;
+ }
+ if ($domconfig{$action}{$itemid}{'incdom'} ne $confhash{$itemid}{'incdom'}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
$allpos[$newpos] = $itemid;
}
if ($imgdeletions{$itemid}) {
@@ -10261,7 +12380,7 @@ sub modify_ltitools {
$resulttext .= '';
my $position = $pos + 1;
$resulttext .= '- '.&mt('Order: [_1]',$position).'
';
- foreach my $item ('version','msgtype','url') {
+ foreach my $item ('version','msgtype','sigmethod','url','lifetime') {
if ($confhash{$itemid}{$item} ne '') {
$resulttext .= '- '.$lt{$item}.': '.$confhash{$itemid}{$item}.'
';
}
@@ -10275,7 +12394,7 @@ sub modify_ltitools {
$resulttext .= ('*'x$num).'';
}
$resulttext .= '- '.&mt('Configurable in course:');
- my @possconfig = ('label','title','target','linktext','explanation');
+ my @possconfig = ('label','title','target','linktext','explanation','append');
my $numconfig = 0;
if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') {
foreach my $item (@possconfig) {
@@ -10293,6 +12412,15 @@ sub modify_ltitools {
$resulttext .= '
- '.$lt{$item}.' ';
if ($confhash{$itemid}{$item}) {
$resulttext .= &mt('Yes');
+ if ($confhash{$itemid}{$item.'valid'}) {
+ if ($item eq 'passback') {
+ $resulttext .= ' '.&mt('valid for at least [quant,_1,day] after launch',
+ $confhash{$itemid}{$item.'valid'});
+ } else {
+ $resulttext .= ' '.&mt('valid for at least [quant,_1,second] after launch',
+ $confhash{$itemid}{$item.'valid'});
+ }
+ }
} else {
$resulttext .= &mt('No');
}
@@ -10329,6 +12457,13 @@ sub modify_ltitools {
}
if ($fieldlist) {
$fieldlist =~ s/,$//;
+ if ($confhash{$itemid}{'fields'}{'user'}) {
+ if ($confhash{$itemid}{'incdom'}) {
+ $fieldlist .= ' ('.&mt('username:domain').')';
+ } else {
+ $fieldlist .= ' ('.&mt('username').')';
+ }
+ }
$resulttext .= '
- '.&mt('Data sent').':'.$fieldlist.'
';
}
}
@@ -10353,7 +12488,7 @@ sub modify_ltitools {
}
}
if ($customlist) {
- $resulttext .= '- '.&mt('Custom items').':'.$customlist.'
';
+ $resulttext .= '- '.&mt('Custom items').': '.$customlist.'
';
}
}
$resulttext .= ' ';
@@ -10449,6 +12584,530 @@ sub get_ltitools_id {
return ($id,$error);
}
+sub modify_lti {
+ my ($r,$dom,$action,$lastactref,%domconfig) = @_;
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
+ my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);
+ my (%posslti,%posslticrs,%posscrstype);
+ my @courseroles = ('cc','in','ta','ep','st');
+ my @ltiroles = qw(Learner Instructor ContentDeveloper TeachingAssistant Mentor Member Manager Administrator);
+ my @lticourseroles = qw(Instructor TeachingAssistant Mentor Learner);
+ my @coursetypes = ('official','unofficial','community','textbook','placement');
+ my %coursetypetitles = &Apache::lonlocal::texthash (
+ official => 'Official',
+ unofficial => 'Unofficial',
+ community => 'Community',
+ textbook => 'Textbook',
+ placement => 'Placement Test',
+ );
+ my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
+ my %lt = <i_names();
+ map { $posslti{$_} = 1; } @ltiroles;
+ map { $posslticrs{$_} = 1; } @lticourseroles;
+ map { $posscrstype{$_} = 1; } @coursetypes;
+
+ my %menutitles = <imenu_titles();
+
+ my (@items,%deletions,%itemids);
+ if ($env{'form.lti_add'}) {
+ my $consumer = $env{'form.lti_consumer_add'};
+ $consumer =~ s/(`)/'/g;
+ ($newid,my $error) = &get_lti_id($dom,$consumer);
+ if ($newid) {
+ $itemids{'add'} = $newid;
+ push(@items,'add');
+ $changes{$newid} = 1;
+ } else {
+ my $error = &mt('Failed to acquire unique ID for new LTI configuration');
+ $errors .= ''.$error.'';
+ }
+ }
+ if (ref($domconfig{$action}) eq 'HASH') {
+ my @todelete = &Apache::loncommon::get_env_multiple('form.lti_del');
+ if (@todelete) {
+ map { $deletions{$_} = 1; } @todelete;
+ }
+ my $maxnum = $env{'form.lti_maxnum'};
+ for (my $i=0; $i<=$maxnum; $i++) {
+ my $itemid = $env{'form.lti_id_'.$i};
+ $itemid =~ s/\D+//g;
+ if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
+ if ($deletions{$itemid}) {
+ $changes{$itemid} = $domconfig{$action}{$itemid}{'consumer'};
+ } else {
+ push(@items,$i);
+ $itemids{$i} = $itemid;
+ }
+ }
+ }
+ }
+ foreach my $idx (@items) {
+ my $itemid = $itemids{$idx};
+ next unless ($itemid);
+ my $position = $env{'form.lti_pos_'.$idx};
+ $position =~ s/\D+//g;
+ if ($position ne '') {
+ $allpos[$position] = $itemid;
+ }
+ foreach my $item ('consumer','key','secret','lifetime','requser') {
+ my $formitem = 'form.lti_'.$item.'_'.$idx;
+ $env{$formitem} =~ s/(`)/'/g;
+ if ($item eq 'lifetime') {
+ $env{$formitem} =~ s/[^\d.]//g;
+ }
+ if ($env{$formitem} ne '') {
+ if (($item eq 'key') || ($item eq 'secret')) {
+ $encconfig{$itemid}{$item} = $env{$formitem};
+ } else {
+ $confhash{$itemid}{$item} = $env{$formitem};
+ unless (($idx eq 'add') || ($changes{$itemid})) {
+ if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ }
+ }
+ if ($env{'form.lti_version_'.$idx} eq 'LTI-1p0') {
+ $confhash{$itemid}{'version'} = $env{'form.lti_version_'.$idx};
+ }
+ if ($confhash{$itemid}{'requser'}) {
+ if ($env{'form.lti_mapuser_'.$idx} eq 'sourcedid') {
+ $confhash{$itemid}{'mapuser'} = 'lis_person_sourcedid';
+ } elsif ($env{'form.lti_mapuser_'.$idx} eq 'email') {
+ $confhash{$itemid}{'mapuser'} = 'lis_person_contact_email_primary';
+ } elsif ($env{'form.lti_mapuser_'.$idx} eq 'other') {
+ my $mapuser = $env{'form.lti_customuser_'.$idx};
+ $mapuser =~ s/(`)/'/g;
+ $mapuser =~ s/^\s+|\s+$//g;
+ $confhash{$itemid}{'mapuser'} = $mapuser;
+ }
+ foreach my $ltirole (@lticourseroles) {
+ my $possrole = $env{'form.lti_maprole_'.$ltirole.'_'.$idx};
+ if (grep(/^\Q$possrole\E$/,@courseroles)) {
+ $confhash{$itemid}{'maproles'}{$ltirole} = $possrole;
+ }
+ }
+ my @possmakeuser = &Apache::loncommon::get_env_multiple('form.lti_makeuser_'.$idx);
+ my @makeuser;
+ foreach my $ltirole (sort(@possmakeuser)) {
+ if ($posslti{$ltirole}) {
+ push(@makeuser,$ltirole);
+ }
+ }
+ $confhash{$itemid}{'makeuser'} = \@makeuser;
+ if (@makeuser) {
+ my $lcauth = $env{'form.lti_lcauth_'.$idx};
+ if ($lcauth =~ /^(internal|krb4|krb5|localauth)$/) {
+ $confhash{$itemid}{'lcauth'} = $lcauth;
+ if ($lcauth ne 'internal') {
+ my $lcauthparm = $env{'form.lti_lcauthparm_'.$idx};
+ $lcauthparm =~ s/^(\s+|\s+)$//g;
+ $lcauthparm =~ s/`//g;
+ if ($lcauthparm ne '') {
+ $confhash{$itemid}{'lcauthparm'} = $lcauthparm;
+ }
+ }
+ } else {
+ $confhash{$itemid}{'lcauth'} = 'lti';
+ }
+ }
+ my @possinstdata = &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
+ if (@possinstdata) {
+ foreach my $field (@possinstdata) {
+ if (exists($fieldtitles{$field})) {
+ push(@{$confhash{$itemid}{'instdata'}});
+ }
+ }
+ }
+ if (($env{'form.lti_mapcrs_'.$idx} eq 'course_offering_sourcedid') ||
+ ($env{'form.lti_mapcrs_'.$idx} eq 'context_id')) {
+ $confhash{$itemid}{'mapcrs'} = $env{'form.lti_mapcrs_'.$idx};
+ } elsif ($env{'form.lti_mapcrs_'.$idx} eq 'other') {
+ my $mapcrs = $env{'form.lti_mapcrsfield_'.$idx};
+ $mapcrs =~ s/(`)/'/g;
+ $mapcrs =~ s/^\s+|\s+$//g;
+ $confhash{$itemid}{'mapcrs'} = $mapcrs;
+ }
+ my @posstypes = &Apache::loncommon::get_env_multiple('form.lti_mapcrstype_'.$idx);
+ my @crstypes;
+ foreach my $type (sort(@posstypes)) {
+ if ($posscrstype{$type}) {
+ push(@crstypes,$type);
+ }
+ }
+ $confhash{$itemid}{'mapcrstype'} = \@crstypes;
+ if ($env{'form.lti_makecrs_'.$idx}) {
+ $confhash{$itemid}{'makecrs'} = 1;
+ }
+ my @possenroll = &Apache::loncommon::get_env_multiple('form.lti_selfenroll_'.$idx);
+ my @selfenroll;
+ foreach my $type (sort(@possenroll)) {
+ if ($posslticrs{$type}) {
+ push(@selfenroll,$type);
+ }
+ }
+ $confhash{$itemid}{'selfenroll'} = \@selfenroll;
+ if ($env{'form.lti_crssec_'.$idx}) {
+ if ($env{'form.lti_crssecsrc_'.$idx} eq 'course_section_sourcedid') {
+ $confhash{$itemid}{'section'} = $env{'form.lti_crssecsrc_'.$idx};
+ } elsif ($env{'form.lti_crssecsrc_'.$idx} eq 'other') {
+ my $section = $env{'form.lti_customsection_'.$idx};
+ $section =~ s/(`)/'/g;
+ $section =~ s/^\s+|\s+$//g;
+ if ($section ne '') {
+ $confhash{$itemid}{'section'} = $section;
+ }
+ }
+ }
+ if ($env{'form.lti_callback_'.$idx}) {
+ if ($env{'form.lti_callbackparam_'.$idx}) {
+ my $callback = $env{'form.lti_callbackparam_'.$idx};
+ $callback =~ s/^\s+|\s+$//g;
+ $confhash{$itemid}{'callback'} = $callback;
+ }
+ }
+ foreach my $field ('passback','roster','topmenu','inlinemenu') {
+ if ($env{'form.lti_'.$field.'_'.$idx}) {
+ $confhash{$itemid}{$field} = 1;
+ }
+ }
+ if ($env{'form.lti_passback_'.$idx}) {
+ if ($env{'form.lti_passbackformat_'.$idx} eq '1.0') {
+ $confhash{$itemid}{'passbackformat'} = '1.0';
+ } else {
+ $confhash{$itemid}{'passbackformat'} = '1.1';
+ }
+ }
+ if ($env{'form.lti_topmenu_'.$idx} || $env{'form.lti_inlinemenu_'.$idx}) {
+ $confhash{$itemid}{lcmenu} = [];
+ my @possmenu = &Apache::loncommon::get_env_multiple('form.lti_menuitem_'.$idx);
+ foreach my $field (@possmenu) {
+ if (exists($menutitles{$field})) {
+ if ($field eq 'grades') {
+ next unless ($env{'form.lti_inlinemenu_'.$idx});
+ }
+ push(@{$confhash{$itemid}{lcmenu}},$field);
+ }
+ }
+ }
+ unless (($idx eq 'add') || ($changes{$itemid})) {
+ foreach my $field ('mapuser','mapcrs','makecrs','section','passback','roster','lcauth','lcauthparm','topmenu','inlinemenu','callback') {
+ if ($domconfig{$action}{$itemid}{$field} ne $confhash{$itemid}{$field}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ unless ($changes{$itemid}) {
+ if ($domconfig{$action}{$itemid}{'passback'} eq $confhash{$itemid}{'passback'}) {
+ if ($domconfig{$action}{$itemid}{'passbackformat'} ne $confhash{$itemid}{'passbackformat'}) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ foreach my $field ('makeuser','mapcrstype','selfenroll','instdata','lcmenu') {
+ unless ($changes{$itemid}) {
+ if (ref($domconfig{$action}{$itemid}{$field}) eq 'ARRAY') {
+ if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+ my @diffs = &Apache::loncommon::compare_arrays($domconfig{$action}{$itemid}{$field},
+ $confhash{$itemid}{$field});
+ if (@diffs) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (@{$domconfig{$action}{$itemid}{$field}} > 0) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{$field}} > 0) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ }
+ unless ($changes{$itemid}) {
+ if (ref($domconfig{$action}{$itemid}{'maproles'}) eq 'HASH') {
+ if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+ foreach my $ltirole (keys(%{$domconfig{$action}{$itemid}{'maproles'}})) {
+ if ($domconfig{$action}{$itemid}{'maproles'}{$ltirole} ne
+ $confhash{$itemid}{'maproles'}{$ltirole}) {
+ $changes{$itemid} = 1;
+ last;
+ }
+ }
+ unless ($changes{$itemid}) {
+ foreach my $ltirole (keys(%{$confhash{$itemid}{'maproles'}})) {
+ if ($confhash{$itemid}{'maproles'}{$ltirole} ne
+ $domconfig{$action}{$itemid}{'maproles'}{$ltirole}) {
+ $changes{$itemid} = 1;
+ last;
+ }
+ }
+ }
+ } elsif (keys(%{$domconfig{$action}{$itemid}{'maproles'}}) > 0) {
+ $changes{$itemid} = 1;
+ }
+ } elsif (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+ unless ($changes{$itemid}) {
+ if (keys(%{$confhash{$itemid}{'maproles'}}) > 0) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (@allpos > 0) {
+ my $idx = 0;
+ foreach my $itemid (@allpos) {
+ if ($itemid ne '') {
+ $confhash{$itemid}{'order'} = $idx;
+ if (ref($domconfig{$action}) eq 'HASH') {
+ if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
+ if ($domconfig{$action}{$itemid}{'order'} ne $idx) {
+ $changes{$itemid} = 1;
+ }
+ }
+ }
+ $idx ++;
+ }
+ }
+ }
+ my %ltihash = (
+ $action => { %confhash }
+ );
+ my $putresult = &Apache::lonnet::put_dom('configuration',\%ltihash,
+ $dom);
+ if ($putresult eq 'ok') {
+ my %ltienchash = (
+ $action => { %encconfig }
+ );
+ &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);
+ if (keys(%changes) > 0) {
+ my $cachetime = 24*60*60;
+ my %ltiall = %confhash;
+ foreach my $id (keys(%ltiall)) {
+ if (ref($encconfig{$id}) eq 'HASH') {
+ foreach my $item ('key','secret') {
+ $ltiall{$id}{$item} = $encconfig{$id}{$item};
+ }
+ }
+ }
+ &Apache::lonnet::do_cache_new('lti',$dom,\%ltiall,$cachetime);
+ if (ref($lastactref) eq 'HASH') {
+ $lastactref->{'lti'} = 1;
+ }
+ $resulttext = &mt('Changes made:').'';
+ my %bynum;
+ foreach my $itemid (sort(keys(%changes))) {
+ my $position = $confhash{$itemid}{'order'};
+ $bynum{$position} = $itemid;
+ }
+ foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
+ my $itemid = $bynum{$pos};
+ if (ref($confhash{$itemid}) ne 'HASH') {
+ $resulttext .= '- '.&mt('Deleted: [_1]',$changes{$itemid}).'
';
+ } else {
+ $resulttext .= '- '.$confhash{$itemid}{'consumer'}.'
';
+ my $position = $pos + 1;
+ $resulttext .= '- '.&mt('Order: [_1]',$position).'
';
+ foreach my $item ('version','lifetime') {
+ if ($confhash{$itemid}{$item} ne '') {
+ $resulttext .= '- '.$lt{$item}.': '.$confhash{$itemid}{$item}.'
';
+ }
+ }
+ if ($encconfig{$itemid}{'key'} ne '') {
+ $resulttext .= '- '.$lt{'key'}.': '.$encconfig{$itemid}{'key'}.'
';
+ }
+ if ($encconfig{$itemid}{'secret'} ne '') {
+ $resulttext .= '- '.$lt{'secret'}.': ';
+ my $num = length($encconfig{$itemid}{'secret'});
+ $resulttext .= ('*'x$num).'
';
+ }
+ if ($confhash{$itemid}{'requser'}) {
+ if ($confhash{$itemid}{'mapuser'}) {
+ my $shownmapuser;
+ if ($confhash{$itemid}{'mapuser'} eq 'lis_person_sourcedid') {
+ $shownmapuser = $lt{'sourcedid'}.' (lis_person_sourcedid)';
+ } elsif ($confhash{$itemid}{'mapuser'} eq 'lis_person_contact_email_primary') {
+ $shownmapuser = $lt{'email'}.' (lis_person_contact_email_primary)';
+ } else {
+ $shownmapuser = &mt('Other').' ('.$confhash{$itemid}{'mapuser'}.')';
+ }
+ $resulttext .= '- '.&mt('LON-CAPA username').': '.$shownmapuser.'
';
+ }
+ if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+ my $rolemaps;
+ foreach my $role (@ltiroles) {
+ if ($confhash{$itemid}{'maproles'}{$role}) {
+ $rolemaps .= (' 'x2).$role.'='.
+ &Apache::lonnet::plaintext($confhash{$itemid}{'maproles'}{$role},
+ 'Course').',';
+ }
+ }
+ if ($rolemaps) {
+ $rolemaps =~ s/,$//;
+ $resulttext .= '- '.&mt('Role mapping:').$rolemaps.'
';
+ }
+ }
+ if (ref($confhash{$itemid}{'makeuser'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'makeuser'}} > 0) {
+ $resulttext .= '- '.&mt('Following roles may create user accounts: [_1]',
+ join(', ',@{$confhash{$itemid}{'makeuser'}})).'
';
+ if ($confhash{$itemid}{'lcauth'} eq 'lti') {
+ $resulttext .= &mt('New users will only be able to authenticate via LTI').' ';
+ } else {
+ $resulttext .= &mt('New users will be assigned LON-CAPA authentication: [_1]',
+ $confhash{$itemid}{'lcauth'});
+ if ($confhash{$itemid}{'lcauth'} eq 'internal') {
+ $resulttext .= '; '.&mt('a randomly generated password will be created');
+ } elsif ($confhash{$itemid}{'lcauth'} eq 'localauth') {
+ if ($confhash{$itemid}{'lcauthparm'} ne '') {
+ $resulttext .= ' '.&mt('with argument: [_1]',$confhash{$itemid}{'lcauthparm'});
+ }
+ } else {
+ $resulttext .= '; '.&mt('Kerberos domain: [_1]',$confhash{$itemid}{'lcauthparm'});
+ }
+ }
+ $resulttext .= '';
+ } else {
+ $resulttext .= '- '.&mt('User account creation not permitted.').'
';
+ }
+ }
+ if (ref($confhash{$itemid}{'instdata'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'instdata'}} > 0) {
+ $resulttext .= '- '.&mt('Institutional data will be used when creating a new user for: [_1]',
+ join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'
';
+ } else {
+ $resulttext .= '- '.&mt('No institutional data used when creating a new user.').'
';
+ }
+ }
+ if ($confhash{$itemid}{'mapcrs'}) {
+ $resulttext .= '- '.&mt('Unique course identifier').': '.$confhash{$itemid}{'mapcrs'}.'
';
+ }
+ if (ref($confhash{$itemid}{'mapcrstype'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'mapcrstype'}} > 0) {
+ $resulttext .= '- '.&mt('Mapping for the following LON-CAPA course types: [_1]',
+ join(', ',map { $coursetypetitles{$_}; } @coursetypes)).
+ '
';
+ } else {
+ $resulttext .= '- '.&mt('No mapping to LON-CAPA courses').'
';
+ }
+ }
+ if ($confhash{$itemid}{'makecrs'}) {
+ $resulttext .= '- '.&mt('Instructor may create course (if absent).').'
';
+ } else {
+ $resulttext .= '- '.&mt('Instructor may not create course (if absent).').'
';
+ }
+ if (ref($confhash{$itemid}{'selfenroll'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'selfenroll'}} > 0) {
+ $resulttext .= '- '.&mt('Self-enrollment for following roles: [_1]',
+ join(', ',@{$confhash{$itemid}{'selfenroll'}})).
+ '
';
+ } else {
+ $resulttext .= '- '.&mt('Self-enrollment not permitted').'
';
+ }
+ }
+ if ($confhash{$itemid}{'section'}) {
+ if ($confhash{$itemid}{'section'} eq 'course_section_sourcedid') {
+ $resulttext .= '- '.&mt('User section from standard field:').
+ ' (course_section_sourcedid)'.'
';
+ } else {
+ $resulttext .= '- '.&mt('User section from:').' '.
+ $confhash{$itemid}{'section'}.'
';
+ }
+ } else {
+ $resulttext .= '- '.&mt('No section assignment').'
';
+ }
+ if ($confhash{$itemid}{'callback'}) {
+ $resulttext .= '- '.&mt('Callback setting').': '.$confhash{$itemid}{'callback'}.'
';
+ } else {
+ $resulttext .= '- '.&mt('No callback to logout LON-CAPA session when user logs out of Comsumer');
+ }
+ foreach my $item ('passback','roster','topmenu','inlinemenu') {
+ $resulttext .= '
- '.$lt{$item}.': ';
+ if ($confhash{$itemid}{$item}) {
+ $resulttext .= &mt('Yes');
+ if ($item eq 'passback') {
+ if ($confhash{$itemid}{'passbackformat'} eq '1.0') {
+ $resulttext .= ' ('.&mt('Outcomes Extension (1.0)').')';
+ } elsif ($confhash{$itemid}{'passbackformat'} eq '1.1') {
+ $resulttext .= ' ('.&mt('Outcomes Service (1.1)').')';
+ }
+ }
+ } else {
+ $resulttext .= &mt('No');
+ }
+ $resulttext .= '
';
+ }
+ if (ref($confhash{$itemid}{'lcmenu'}) eq 'ARRAY') {
+ if (@{$confhash{$itemid}{'lcmenu'}} > 0) {
+ $resulttext .= '- '.&mt('Menu items:').' '.
+ join(', ', map { $menutitles{$_}; } (@{$confhash{$itemid}{'lcmenu'}})).'
';
+ } else {
+ $resulttext .= '- '.&mt('No menu items displayed in header or online menu').'
';
+ }
+ }
+ }
+ $resulttext .= ' ';
+ }
+ }
+ $resulttext .= ' ';
+ } else {
+ $resulttext = &mt('No changes made.');
+ }
+ } else {
+ $errors .= ''.&mt('Failed to save changes').'';
+ }
+ if ($errors) {
+ $resulttext .= &mt('The following errors occurred: ').'';
+ }
+ return $resulttext;
+}
+
+sub get_lti_id {
+ my ($domain,$consumer) = @_;
+ # get lock on lti db
+ my $lockhash = {
+ lock => $env{'user.name'}.
+ ':'.$env{'user.domain'},
+ };
+ my $tries = 0;
+ my $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);
+ my ($id,$error);
+
+ while (($gotlock ne 'ok') && ($tries<10)) {
+ $tries ++;
+ sleep (0.1);
+ $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);
+ }
+ if ($gotlock eq 'ok') {
+ my %currids = &Apache::lonnet::dump_dom('lti',$domain);
+ if ($currids{'lock'}) {
+ delete($currids{'lock'});
+ if (keys(%currids)) {
+ my @curr = sort { $a <=> $b } keys(%currids);
+ if ($curr[-1] =~ /^\d+$/) {
+ $id = 1 + $curr[-1];
+ }
+ } else {
+ $id = 1;
+ }
+ if ($id) {
+ unless (&Apache::lonnet::newput_dom('lti',{ $id => $consumer },$domain) eq 'ok') {
+ $error = 'nostore';
+ }
+ } else {
+ $error = 'nonumber';
+ }
+ }
+ my $dellockoutcome = &Apache::lonnet::del_dom('lti',['lock'],$domain);
+ } else {
+ $error = 'nolock';
+ }
+ return ($id,$error);
+}
+
sub modify_autoenroll {
my ($dom,$lastactref,%domconfig) = @_;
my ($resulttext,%changes);
@@ -11034,8 +13693,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}} =
@@ -11068,23 +13728,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') {
+ $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}) {
@@ -11139,6 +13874,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'};
@@ -11150,6 +13982,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;
@@ -11183,6 +14016,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)) {
@@ -11253,23 +14093,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'}}) {
@@ -11308,7 +14259,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 .= '';
@@ -11322,6 +14272,755 @@ sub modify_contacts {
return $resulttext;
}
+sub modify_privacy {
+ my ($dom,%domconfig) = @_;
+ my ($resulttext,%current,%changes);
+ if (ref($domconfig{'privacy'}) eq 'HASH') {
+ %current = %{$domconfig{'privacy'}};
+ }
+ my @fields = ('lastname','firstname','middlename','generation','permanentemail','id');
+ my @items = ('domain','author','course','community');
+ my %names = &Apache::lonlocal::texthash (
+ domain => 'Assigned domain role(s)',
+ author => 'Assigned co-author role(s)',
+ course => 'Assigned course role(s)',
+ community => 'Assigned community role',
+ );
+ my %roles = &Apache::lonlocal::texthash (
+ domain => 'Domain role',
+ author => 'Co-author role',
+ course => 'Course role',
+ community => 'Community role',
+ );
+ my %titles = &Apache::lonlocal::texthash (
+ approval => 'Approval for role in different domain',
+ othdom => 'User information available in other domain',
+ priv => 'Information viewable by privileged user in same domain',
+ unpriv => 'Information viewable by unprivileged user in same domain',
+ instdom => 'Other domain shares institution/provider',
+ extdom => 'Other domain has different institution/provider',
+ none => 'Not allowed',
+ user => 'User authorizes',
+ domain => 'Domain Coordinator authorizes',
+ auto => 'Unrestricted',
+ );
+ my %fieldnames = &Apache::lonlocal::texthash (
+ id => 'Student/Employee ID',
+ permanentemail => 'E-mail address',
+ lastname => 'Last Name',
+ firstname => 'First Name',
+ middlename => 'Middle Name',
+ generation => 'Generation',
+ );
+ my ($othertitle,$usertypes,$types) =
+ &Apache::loncommon::sorted_inst_types($dom);
+ my (%by_ip,%by_location,@intdoms,@instdoms);
+ &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
+
+ my %privacyhash = (
+ 'approval' => {
+ instdom => {},
+ extdom => {},
+ },
+ 'othdom' => {},
+ 'priv' => {},
+ 'unpriv' => {},
+ );
+ foreach my $item (@items) {
+ if (@instdoms > 1) {
+ if ($env{'form.privacy_approval_instdom'.$item} =~ /^(none|user|domain|auto)$/) {
+ $privacyhash{'approval'}{'instdom'}{$item} = $env{'form.privacy_approval_instdom_'.$item};
+ }
+ if (ref($current{'approval'}) eq 'HASH') {
+ if (ref($current{'approval'}{'instdom'}) eq 'HASH') {
+ unless ($privacyhash{'approval'}{'instdom'}{$item} eq $current{'approval'}{'instdom'}{$item}) {
+ $changes{'approval'} = 1;
+ }
+ }
+ } elsif ($privacyhash{'approval'}{'instdom'}{$item} ne 'auto') {
+ $changes{'approval'} = 1;
+ }
+ }
+ if (keys(%by_location) > 0) {
+ if ($env{'form.privacy_approval_extdom_'.$item} =~ /^(none|user|domain|auto)$/) {
+ $privacyhash{'approval'}{'extdom'}{$item} = $env{'form.privacy_approval_extdom_'.$item};
+ }
+ if (ref($current{'approval'}) eq 'HASH') {
+ if (ref($current{'approval'}{'extdom'}) eq 'HASH') {
+ unless ($privacyhash{'approval'}{'extdom'}{$item} eq $current{'approval'}{'extdom'}{$item}) {
+ $changes{'approval'} = 1;
+ }
+ }
+ } elsif ($privacyhash{'approval'}{'extdom'}{$item} ne 'auto') {
+ $changes{'approval'} = 1;
+ }
+ }
+ foreach my $status ('priv','unpriv') {
+ my @possibles = sort(&Apache::loncommon::get_env_multiple('form.privacy_'.$status.'_'.$item));
+ my @newvalues;
+ foreach my $field (@possibles) {
+ if (grep(/^\Q$field\E$/,@fields)) {
+ $privacyhash{$status}{$item}{$field} = 1;
+ push(@newvalues,$field);
+ }
+ }
+ @newvalues = sort(@newvalues);
+ if (ref($current{$status}) eq 'HASH') {
+ if (ref($current{$status}{$item}) eq 'HASH') {
+ my @currvalues = sort(keys(%{$current{$status}{$item}}));
+ my @diffs = &Apache::loncommon::compare_arrays(\@currvalues,\@newvalues);
+ if (@diffs > 0) {
+ $changes{$status} = 1;
+ }
+ }
+ } else {
+ my @stdfields;
+ foreach my $field (@fields) {
+ if ($field eq 'id') {
+ next if ($status eq 'unpriv');
+ next if (($status eq 'priv') && ($item eq 'community'));
+ }
+ push(@stdfields,$field);
+ }
+ my @diffs = &Apache::loncommon::compare_arrays(\@stdfields,\@newvalues);
+ if (@diffs > 0) {
+ $changes{$status} = 1;
+ }
+ }
+ }
+ }
+ if ((@instdoms > 1) || (keys(%by_location) > 0)) {
+ my @statuses;
+ if (ref($types) eq 'ARRAY') {
+ @statuses = @{$types};
+ }
+ foreach my $type (@statuses,'default') {
+ my @possfields = &Apache::loncommon::get_env_multiple('form.privacy_othdom_'.$type);
+ my @newvalues;
+ foreach my $field (sort(@possfields)) {
+ if (grep(/^\Q$field\E$/,@fields)) {
+ $privacyhash{'othdom'}{$type}{$field} = 1;
+ push(@newvalues,$field);
+ }
+ }
+ @newvalues = sort(@newvalues);
+ if (ref($current{'othdom'}) eq 'HASH') {
+ if (ref($current{'othdom'}{$type}) eq 'HASH') {
+ my @currvalues = sort(keys(%{$current{'othdom'}{$type}}));
+ my @diffs = &Apache::loncommon::compare_arrays(\@currvalues,\@newvalues);
+ if (@diffs > 0) {
+ $changes{'othdom'} = 1;
+ }
+ }
+ } else {
+ my @stdfields = ('lastname','firstname','middlename','generation','permanentemail');
+ my @diffs = &Apache::loncommon::compare_arrays(\@stdfields,\@newvalues);
+ if (@diffs > 0) {
+ $changes{'othdom'} = 1;
+ }
+ }
+ }
+ }
+ my %confighash = (
+ privacy => \%privacyhash,
+ );
+ my $putresult = &Apache::lonnet::put_dom('configuration',\%confighash,$dom);
+ if ($putresult eq 'ok') {
+ if (keys(%changes) > 0) {
+ $resulttext = &mt('Changes made: ').'';
+ foreach my $key ('approval','othdom','priv','unpriv') {
+ if ($changes{$key}) {
+ $resulttext .= '- '.$titles{$key}.':
';
+ if ($key eq 'approval') {
+ if (keys(%{$privacyhash{$key}{instdom}})) {
+ $resulttext .= '- '.$titles{'instdom'}.'
';
+ foreach my $item (@items) {
+ $resulttext .= '- '.$roles{$item}.': '.$titles{$privacyhash{$key}{instdom}{$item}}.'
';
+ }
+ $resulttext .= ' ';
+ }
+ if (keys(%{$privacyhash{$key}{extdom}})) {
+ $resulttext .= '- '.$titles{'extdom'}.'
';
+ foreach my $item (@items) {
+ $resulttext .= '- '.$roles{$item}.': '.$titles{$privacyhash{$key}{extdom}{$item}}.'
';
+ }
+ $resulttext .= ' ';
+ }
+ } elsif ($key eq 'othdom') {
+ my @statuses;
+ if (ref($types) eq 'ARRAY') {
+ @statuses = @{$types};
+ }
+ if (ref($privacyhash{$key}) eq 'HASH') {
+ foreach my $status (@statuses,'default') {
+ if ($status eq 'default') {
+ $resulttext .= '- '.$othertitle.': ';
+ } elsif (ref($usertypes) eq 'HASH') {
+ $resulttext .= '
- '.$usertypes->{$status}.': ';
+ } else {
+ next;
+ }
+ if (ref($privacyhash{$key}{$status}) eq 'HASH') {
+ if (keys(%{$privacyhash{$key}{$status}})) {
+ $resulttext .= join(', ', map { $fieldnames{$_}; } (sort(keys(%{$privacyhash{$key}{$status}}))));
+ } else {
+ $resulttext .= &mt('none');
+ }
+ }
+ $resulttext .= '
';
+ }
+ }
+ } else {
+ foreach my $item (@items) {
+ if (ref($privacyhash{$key}{$item}) eq 'HASH') {
+ $resulttext .= '- '.$names{$item}.': ';
+ if (keys(%{$privacyhash{$key}{$item}})) {
+ $resulttext .= join(', ', map { $fieldnames{$_}; } (sort(keys(%{$privacyhash{$key}{$item}}))));
+ } else {
+ $resulttext .= &mt('none');
+ }
+ $resulttext .= '
';
+ }
+ }
+ }
+ $resulttext .= ' ';
+ }
+ }
+ } else {
+ $resulttext = &mt('No changes made to user information settings');
+ }
+ } else {
+ $resulttext = ''.
+ &mt('An error occurred: [_1]',$putresult).'';
+ }
+ 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',
+ expire => 'Password expiration (days)',
+ 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 (!exists($domconfig{passwords})) {
+ 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 (!exists($domconfig{passwords})) {
+ 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 (!exists($domconfig{passwords})) {
+ 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 (!exists($domconfig{passwords})) {
+ 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 (!exists($domconfig{passwords})) {
+ 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 ($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','expire','numsaved') {
+ $env{'form.passwords_'.$rule} =~ s/^\s+|\s+$//g;
+ my $ruleok;
+ if ($rule eq 'expire') {
+ if (($env{'form.passwords_'.$rule} =~ /^\d+(|\.\d*)$/) &&
+ ($env{'form.passwords_'.$rule} ne '0')) {
+ $ruleok = 1;
+ }
+ } elsif ($rule eq 'min') {
+ if ($env{'form.passwords_'.$rule} =~ /^\d+$/) {
+ if ($env{'form.passwords_'.$rule} >= $Apache::lonnet::passwdmin) {
+ $ruleok = 1;
+ }
+ }
+ } elsif (($env{'form.passwords_'.$rule} =~ /^\d+$/) &&
+ ($env{'form.passwords_'.$rule} ne '0')) {
+ $ruleok = 1;
+ }
+ if ($ruleok) {
+ $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;
+ }
+ }
+ } 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 (!exists($domconfig{passwords})) {
+ 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'}).'
'.
+ &mt('Public key: [_1]',$confighash{'passwords'}{'recaptchapub'}).''.
+ &mt('Private key: [_1]',$confighash{'passwords'}{'recaptchapriv'}).' ';
+ } 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 usedfor 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'},
+ $titles{custom},600,500);
+ $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','expire','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}).'
';
+ }
+ }
+ } 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);
@@ -11406,7 +15105,7 @@ sub modify_usercreation {
}
my @authen_contexts = ('author','course','domain');
- my @authtypes = ('int','krb4','krb5','loc');
+ my @authtypes = ('int','krb4','krb5','loc','lti');
my %authhash;
foreach my $item (@authen_contexts) {
my @authallowed = &Apache::loncommon::get_env_multiple('form.'.$item.'_auth');
@@ -12135,7 +15834,7 @@ sub modify_selfcreation {
$chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').
'';
foreach my $status (@statuses) {
- if ($type eq 'default') {
+ if ($status eq 'default') {
$chgtext .= '- '.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'
';
} else {
$chgtext .= '- '.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'
';
@@ -12587,8 +16286,8 @@ 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');
- my @authtypes = ('internal','krb4','krb5','localauth');
+ 'portal_def');
+ my @authtypes = ('internal','krb4','krb5','localauth','lti');
foreach my $item (@items) {
$newvalues{$item} = $env{'form.'.$item};
if ($item eq 'auth_def') {
@@ -12629,24 +16328,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};
@@ -12655,6 +16336,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,
);
@@ -12780,30 +16473,9 @@ sub modify_defaults {
krb4 => 'krb4',
krb5 => 'krb5',
localauth => 'loc',
+ lti => 'lti',
);
$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";
@@ -12852,7 +16524,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;
@@ -12887,6 +16559,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;
}
}
}
@@ -12897,22 +16630,57 @@ 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 = ''.
@@ -12922,8 +16690,8 @@ sub modify_scantron {
$resulttext = &mt('No changes made to bubblesheet format file');
}
if ($errors) {
- $resulttext .= &mt('The following errors occurred: ').'';
+ $resulttext .= ''.&mt('The following errors occurred: ').' ';
}
return $resulttext;
}
@@ -13198,6 +16966,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'}) {
@@ -13744,7 +17516,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;
@@ -13760,11 +17531,12 @@ sub modify_coursedefaults {
my $texengine;
if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {
$texengine = $env{'form.texengine'};
- if ($defaultshash{'coursedefaults'}{'texengine'} eq '') {
- unless ($texengine eq 'MathJax') {
+ my $currdef = $domconfig{'coursedefaults'}{'texengine'};
+ if ($currdef eq '') {
+ unless ($texengine eq $Apache::lonnet::deftex) {
$changes{'texengine'} = 1;
}
- } elsif ($defaultshash{'coursedefaults'}{'texengine'} ne $texengine) {
+ } elsif ($currdef ne $texengine) {
$changes{'texengine'} = 1;
}
}
@@ -14581,14 +18353,18 @@ sub modify_usersessions {
} else {
foreach my $type (@{$types{$prefix}}) {
if (defined($changes{$prefix}{$type})) {
- my $newvalue;
+ my ($newvalue,$notinuse);
if (ref($defaultshash{'usersessions'}) eq 'HASH') {
if (ref($defaultshash{'usersessions'}{$prefix})) {
if ($type eq 'version') {
$newvalue = $defaultshash{'usersessions'}{$prefix}{$type};
- } elsif (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
- if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) {
- $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}});
+ } else {
+ if (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
+ if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) {
+ $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}});
+ }
+ } else {
+ $notinuse = 1;
}
}
}
@@ -14596,12 +18372,14 @@ sub modify_usersessions {
if ($newvalue eq '') {
if ($type eq 'version') {
$resulttext .= ''.&mt('[_1] set to: off',$lt{$type}).'';
+ } elsif ($notinuse) {
+ $resulttext .= ''.&mt('[_1] set to: not in use',$lt{$type}).'';
} else {
$resulttext .= ''.&mt('[_1] set to: none',$lt{$type}).'';
}
} else {
if ($type eq 'version') {
- $newvalue .= ' '.&mt('(or later)');
+ $newvalue .= ' '.&mt('(or later)');
}
$resulttext .= ''.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'';
}
@@ -14669,12 +18447,17 @@ sub modify_ssl {
if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
$value = $env{'form.'.$prefix.'_'.$type};
}
- if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
- if ($domconfig{$action}{$prefix}{$type} ne '') {
- if ($value ne $domconfig{$action}{$prefix}{$type}) {
+ if (ref($domconfig{$action}) eq 'HASH') {
+ if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
+ if ($domconfig{$action}{$prefix}{$type} ne '') {
+ if ($value ne $domconfig{$action}{$prefix}{$type}) {
+ $changes{$prefix}{$type} = 1;
+ }
+ $defaultshash{$action}{$prefix}{$type} = $value;
+ } else {
+ $defaultshash{$action}{$prefix}{$type} = $value;
$changes{$prefix}{$type} = 1;
}
- $defaultshash{$action}{$prefix}{$type} = $value;
} else {
$defaultshash{$action}{$prefix}{$type} = $value;
$changes{$prefix}{$type} = 1;
@@ -14744,6 +18527,17 @@ sub modify_ssl {
}
}
}
+ if (keys(%changes)) {
+ foreach my $prefix (keys(%changes)) {
+ if (ref($changes{$prefix}) eq 'HASH') {
+ if (scalar(keys(%{$changes{$prefix}})) == 0) {
+ delete($changes{$prefix});
+ }
+ } else {
+ delete($changes{$prefix});
+ }
+ }
+ }
my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
if (keys(%changes) > 0) {
my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
@@ -14754,10 +18548,10 @@ sub modify_ssl {
$domdefaults{'replication'} = $defaultshash{$action}{'replication'};
}
if (ref($defaultshash{$action}{'connto'}) eq 'HASH') {
- $domdefaults{'connto'} = $domconfig{$action}{'connto'};
+ $domdefaults{'connto'} = $defaultshash{$action}{'connto'};
}
if (ref($defaultshash{$action}{'connfrom'}) eq 'HASH') {
- $domdefaults{'connfrom'} = $domconfig{$action}{'connfrom'};
+ $domdefaults{'connfrom'} = $defaultshash{$action}{'connfrom'};
}
}
my $cachetime = 24*60*60;
@@ -14773,18 +18567,24 @@ sub modify_ssl {
$resulttext .= ''.$titles{$prefix}.'';
foreach my $type (@{$types{$prefix}}) {
if (defined($changes{$prefix}{$type})) {
- my $newvalue;
+ my ($newvalue,$notinuse);
if (ref($defaultshash{$action}) eq 'HASH') {
if (ref($defaultshash{$action}{$prefix})) {
if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
$newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
- } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
- if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
- $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
+ } else {
+ if (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
+ if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
+ $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
+ }
+ } else {
+ $notinuse = 1;
}
}
}
- if ($newvalue eq '') {
+ if ($notinuse) {
+ $resulttext .= '- '.&mt('[_1] set to: not in use',$titles{$type}).'
';
+ } elsif ($newvalue eq '') {
$resulttext .= '- '.&mt('[_1] set to: none',$titles{$type}).'
';
} else {
$resulttext .= '- '.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'
';
@@ -14898,17 +18698,21 @@ sub modify_trust {
$resulttext .= '- '.$lt{$prefix}.'
';
foreach my $type (@types) {
if (defined($changes{$prefix}{$type})) {
- my $newvalue;
+ my ($newvalue,$notinuse);
if (ref($defaultshash{'trust'}) eq 'HASH') {
if (ref($defaultshash{'trust'}{$prefix})) {
if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
$newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
}
+ } else {
+ $notinuse = 1;
}
}
}
- if ($newvalue eq '') {
+ if ($notinuse) {
+ $resulttext .= '- '.&mt('[_1] set to: not in use',$lt{$type}).'
';
+ } elsif ($newvalue eq '') {
$resulttext .= '- '.&mt('[_1] set to: none',$lt{$type}).'
';
} else {
$resulttext .= '- '.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'
';
@@ -14943,12 +18747,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);
@@ -15000,6 +18804,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') {
@@ -15153,6 +18969,10 @@ sub modify_loadbalancing {
}
}
}
+ if ($changes{'curr'}{$balancer}{'cookie'}) {
+ $resulttext .= '- '.&mt('Load Balancer: [_1] -- cookie use enabled',
+ $balancer).'
';
+ }
if (keys(%toupdate)) {
my %thismachine;
my $updatedhere;
@@ -15382,12 +19202,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";
@@ -15929,7 +19749,8 @@ sub devalidate_remote_domconfs {
my %servers = &Apache::lonnet::internet_dom_servers($dom);
my %thismachine;
map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
- my @posscached = ('domainconfig','domdefaults','ltitools','usersessions','directorysrch');
+ my @posscached = ('domainconfig','domdefaults','ltitools','usersessions',
+ 'directorysrch','passwdconf','cats');
if (keys(%servers)) {
foreach my $server (keys(%servers)) {
next if ($thismachine{$server});
|
|