'.$domservers{$lonhost}.' '.
' '.
&mt('Yes').' '.
''.
- ''.&mt('SSO').' '.
- ''.&mt('Non-SSO').' '.
+ ' '.
+ ''.
' ';
@@ -2176,7 +2226,7 @@ sub print_quotas {
@options = ('norequest','approval','automatic');
%titles = &authorrequest_titles();
} else {
- @usertools = ('aboutme','blog','webdav','portfolio');
+ @usertools = ('aboutme','blog','webdav','portfolio','timezone');
%titles = &tool_titles();
}
if (ref($types) eq 'ARRAY') {
@@ -2280,9 +2330,12 @@ sub print_quotas {
}
} else {
my $checked = 'checked="checked" ';
+ if ($item eq 'timezone') {
+ $checked = '';
+ }
if (ref($settings) eq 'HASH') {
if (ref($settings->{$item}) eq 'HASH') {
- if ($settings->{$item}->{$type} == 0) {
+ if (!$settings->{$item}->{$type}) {
$checked = '';
} elsif ($settings->{$item}->{$type} == 1) {
$checked = 'checked="checked" ';
@@ -3098,6 +3151,140 @@ function toggleWAF() {
ENDSCRIPT
}
+sub lti_javascript {
+ my ($dom,$settings) = @_;
+ my $togglejs = <i_toggle_js($dom);
+ my $linkprot_js = &Apache::courseprefs::linkprot_javascript();
+ return <<"ENDSCRIPT";
+
+
+$togglejs
+
+ENDSCRIPT
+}
+
+sub lti_toggle_js {
+ my ($dom) = @_;
+ my %servers = &Apache::lonnet::get_servers($dom,'library');
+ my $primary = &Apache::lonnet::domain($dom,'primary');
+ my $course_servers = "'".join("','",keys(%servers))."'";
+ return <<"ENDSCRIPT";
+
+
+ENDSCRIPT
+}
+
sub autoupdate_javascript {
return <<"ENDSCRIPT";
+
+ENDSCRIPT
+ } else {
+return <<"ENDSCRIPT";
+
@@ -8973,17 +9411,26 @@ ENDSCRIPT
}
sub passwords_javascript {
- my %intalert = &Apache::lonlocal::texthash (
- authcheck => 'Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.',
- authcost => 'Warning: bcrypt encryption cost for internal authentication must be an integer.',
- passmin => 'Warning: minimum password length must be a positive integer greater than 6.',
- passmax => 'Warning: maximum password length must be a positive integer (or blank).',
- passexp => 'Warning: days before password expiration must be a positive integer (or blank).',
- passnum => 'Warning: number of previous passwords to save must be a positive integer (or blank).',
- );
+ my ($prefix) = @_;
+ my %intalert;
+ if ($prefix eq 'passwords') {
+ %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).',
+ passnum => 'Warning: number of previous passwords to save must be a positive integer (or blank).',
+ );
+ } elsif ($prefix eq 'secrets') {
+ %intalert = &Apache::lonlocal::texthash (
+ passmin => 'Warning: minimum secret length must be a positive integer greater than 6.',
+ passmax => 'Warning: maximum secret length must be a positive integer (or blank).',
+ );
+ }
&js_escape(\%intalert);
my $defmin = $Apache::lonnet::passwdmin;
- my $intauthjs = <<"ENDSCRIPT";
+ my $intauthjs;
+ if ($prefix eq 'passwords') { $intauthjs = <<"ENDSCRIPT";
function warnIntAuth(field) {
if (field.name == 'intauth_check') {
@@ -9003,11 +9450,17 @@ function warnIntAuth(field) {
return;
}
-function warnIntPass(field) {
+ENDSCRIPT
+
+ }
+
+ $intauthjs .= <<"ENDSCRIPT";
+
+function warnInt$prefix(field) {
field.value.replace(/^\s+/,'');
field.value.replace(/\s+\$/,'');
var regexdigit=/^\\d+\$/;
- if (field.name == 'passwords_min') {
+ if (field.name == '${prefix}_min') {
if (field.value == '') {
alert('$intalert{passmin}');
field.value = '$defmin';
@@ -9027,29 +9480,15 @@ function warnIntPass(field) {
field.value = '';
}
if (field.value != '') {
- if (field.name == 'passwords_expire') {
- var regexpposnum=/^\\d+(|\\.\\d*)\$/;
- if (!regexpposnum.test(field.value)) {
- alert('$intalert{passexp}');
- field.value = '';
+ if (!regexdigit.test(field.value)) {
+ if (field.name == '${prefix}_max') {
+ alert('$intalert{passmax}');
} 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}');
- }
+ if (field.name == '${prefix}_numsaved') {
+ alert('$intalert{passnum}');
}
- field.value = '';
}
+ field.value = '';
}
}
}
@@ -9628,7 +10067,7 @@ sub modify_login {
my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,
%curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon,
- %currsaml,%saml,%samltext,%samlimg,%samlalt,%samlurl,%samltitle,%samlnotsso);
+ %currsaml,%saml,%samltext,%samlimg,%samlalt,%samlurl,%samltitle,%samlwindow,%samlnotsso);
%title = ( coursecatalog => 'Display course catalog',
adminmail => 'Display administrator E-mail address',
helpdesk => 'Display "Contact Helpdesk" link',
@@ -9652,6 +10091,7 @@ sub modify_login {
$samlalt{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'alt'};
$samlimg{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'img'};
$samltitle{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'title'};
+ $samlwindow{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'window'};
$samlnotsso{$lonhost} = $domconfig{login}{'saml'}{$lonhost}{'notsso'};
}
}
@@ -9909,10 +10349,13 @@ sub modify_login {
if ($env{'form.saml_img_'.$lonhost.'.filename'}) {
push(@newsamlimgs,$lonhost);
}
- foreach my $item ('text','alt','url','title','notsso') {
+ foreach my $item ('text','alt','url','title','window','notsso') {
$env{'form.saml_'.$item.'_'.$lonhost} =~ s/^\s+|\s+$//g;
}
if ($saml{$lonhost}) {
+ if ($env{'form.saml_window_'.$lonhost} ne '1') {
+ $env{'form.saml_window_'.$lonhost} = '';
+ }
if (grep(/^\Q$lonhost\E$/,@delsamlimg)) {
#FIXME Need to obsolete published image
delete($currsaml{$lonhost}{'img'});
@@ -9930,13 +10373,16 @@ sub modify_login {
if ($env{'form.saml_title_'.$lonhost} ne $samltitle{$lonhost}) {
$changes{'saml'}{$lonhost} = 1;
}
+ if ($env{'form.saml_window_'.$lonhost} ne $samlwindow{$lonhost}) {
+ $changes{'saml'}{$lonhost} = 1;
+ }
if ($env{'form.saml_notsso_'.$lonhost} ne $samlnotsso{$lonhost}) {
$changes{'saml'}{$lonhost} = 1;
}
} else {
$changes{'saml'}{$lonhost} = 1;
}
- foreach my $item ('text','alt','url','title','notsso') {
+ foreach my $item ('text','alt','url','title','window','notsso') {
$currsaml{$lonhost}{$item} = $env{'form.saml_'.$item.'_'.$lonhost};
}
} else {
@@ -10137,19 +10583,22 @@ sub modify_login {
alt => 'Alt text for button image',
url => 'SSO URL',
title => 'Tooltip for SSO link',
+ window => 'Pop-up window if iframe',
notsso => 'Text for non-SSO log-in',
);
foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
if (ref($currsaml{$lonhost}) eq 'HASH') {
$resulttext .= ''.&mt("$title{$item} in use for [_1]","$lonhost ").
'';
- foreach my $key ('text','img','alt','url','title','notsso') {
+ foreach my $key ('text','img','alt','url','title','window','notsso') {
if ($currsaml{$lonhost}{$key} eq '') {
$resulttext .= ''.&mt("$notlt{$key} not in use").' ';
} else {
my $value = "'$currsaml{$lonhost}{$key}'";
if ($key eq 'img') {
$value = ' ';
+ } elsif ($key eq 'window') {
+ $value = 'On';
}
$resulttext .= ''.&mt("$notlt{$key} set to: [_1]",
$value).' ';
@@ -10911,7 +11360,7 @@ sub display_colorchgs {
}
} elsif (($role eq 'login') && ($key eq 'alttext')) {
if ($confhash->{$role}{$key}{$item} ne '') {
- $resulttext .= ''.&mt("$choices{$key for $choices{$item} set to [_1].",
+ $resulttext .= ' '.&mt("$choices{$key} for $choices{$item} set to [_1].",
$confhash->{$role}{$key}{$item}).' ';
} else {
$resulttext .= ''.&mt("$choices{$key} for $choices{$item} deleted.").' ';
@@ -11313,7 +11762,7 @@ sub modify_quotas {
@usertools = ('author');
%titles = &authorrequest_titles();
} else {
- @usertools = ('aboutme','blog','webdav','portfolio');
+ @usertools = ('aboutme','blog','webdav','portfolio','timezone');
%titles = &tool_titles();
}
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
@@ -12627,6 +13076,255 @@ 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 (%encconfig,$errors,$resulttext);
+
+ my (%currltisec,%secchanges,%newltisec,%newltienc,%keyset,%newkeyset);
+ $newltisec{'private'}{'keys'} = [];
+ $newltisec{'encrypt'} = {};
+ $newltisec{'rules'} = {};
+ $newltisec{'linkprot'} = {};
+ if (ref($domconfig{'ltisec'}) eq 'HASH') {
+ %currltisec = %{$domconfig{'ltisec'}};
+ if (ref($currltisec{'linkprot'}) eq 'HASH') {
+ foreach my $id (keys(%{$currltisec{'linkprot'}})) {
+ unless ($id =~ /^\d+$/) {
+ delete($currltisec{'linkprot'}{$id});
+ }
+ }
+ }
+ if (ref($currltisec{'private'}) eq 'HASH') {
+ if (ref($currltisec{'private'}{'keys'}) eq 'ARRAY') {
+ $newltisec{'private'}{'keys'} = $currltisec{'private'}{'keys'};
+ map { $keyset{$_} = 1; } @{$currltisec{'private'}{'keys'}};
+ }
+ }
+ }
+ foreach my $item ('crs','dom') {
+ my $formelement = 'form.ltisec_'.$item.'linkprot';
+ if ($env{$formelement}) {
+ $newltisec{'encrypt'}{$item} = 1;
+ if (ref($currltisec{'encrypt'}) eq 'HASH') {
+ unless ($currltisec{'encrypt'}{$item}) {
+ $secchanges{'encrypt'} = 1;
+ }
+ } else {
+ $secchanges{'encrypt'} = 1;
+ }
+ } elsif (ref($currltisec{'encrypt'}) eq 'HASH') {
+ if ($currltisec{'encrypt'}{$item}) {
+ $secchanges{'encrypt'} = 1;
+ }
+ }
+ }
+ unless (exists($currltisec{'rules'})) {
+ $currltisec{'rules'} = {};
+ }
+ &password_rule_changes('secrets',$newltisec{'rules'},$currltisec{'rules'},\%secchanges);
+
+ my @ids=&Apache::lonnet::current_machine_ids();
+ my %servers = &Apache::lonnet::get_servers($dom,'library');
+
+ foreach my $hostid (keys(%servers)) {
+ if (($hostid ne '') && (grep(/^\Q$hostid\E$/,@ids))) {
+ my $newkey;
+ my $keyitem = 'form.ltisec_privkey_'.$hostid;
+ if (exists($env{$keyitem})) {
+ $env{$keyitem} =~ s/(`)/'/g;
+ if ($keyset{$hostid}) {
+ if ($env{'form.ltisec_changeprivkey_'.$hostid}) {
+ if ($env{$keyitem} ne '') {
+ $secchanges{'private'} = 1;
+ $newkeyset{$hostid} = $env{$keyitem};
+ }
+ }
+ } elsif ($env{$keyitem} ne '') {
+ unless (grep(/^\Q$hostid\E$/,@{$newltisec{'private'}{'keys'}})) {
+ push(@{$newltisec{'private'}{'keys'}},$hostid);
+ }
+ $secchanges{'private'} = 1;
+ $newkeyset{$hostid} = $env{$keyitem};
+ }
+ }
+ }
+ }
+
+ my (%linkprotchg,$linkprotoutput,$is_home);
+ my $proterror = &Apache::courseprefs::process_linkprot($dom,'',$currltisec{'linkprot'},
+ \%linkprotchg,'domain');
+ my $home = &Apache::lonnet::domain($dom,'primary');
+ unless (($home eq 'no_host') || ($home eq '')) {
+ my @ids=&Apache::lonnet::current_machine_ids();
+ foreach my $id (@ids) { if ($id eq $home) { $is_home=1; } }
+ }
+
+ if (keys(%linkprotchg)) {
+ $secchanges{'linkprot'} = 1;
+ my %oldlinkprot;
+ if (ref($currltisec{'linkprot'}) eq 'HASH') {
+ %oldlinkprot = %{$currltisec{'linkprot'}};
+ }
+ foreach my $id (keys(%linkprotchg)) {
+ if (ref($linkprotchg{$id}) eq 'HASH') {
+ foreach my $inner (keys(%{$linkprotchg{$id}})) {
+ if (($inner eq 'secret') || ($inner eq 'key')) {
+ if ($is_home) {
+ $newltienc{$id}{$inner} = $linkprotchg{$id}{$inner};
+ }
+ }
+ }
+ } else {
+ $newltisec{'linkprot'}{$id} = $linkprotchg{$id};
+ }
+ }
+ $linkprotoutput = &Apache::courseprefs::store_linkprot($dom,'','domain',\%linkprotchg,\%oldlinkprot);
+ if (keys(%linkprotchg)) {
+ %{$newltisec{'linkprot'}} = %linkprotchg;
+ }
+ }
+ if (ref($currltisec{'linkprot'}) eq 'HASH') {
+ foreach my $id (%{$currltisec{'linkprot'}}) {
+ next if ($id !~ /^\d+$/);
+ unless (exists($linkprotchg{$id})) {
+ if (ref($currltisec{'linkprot'}{$id}) eq 'HASH') {
+ foreach my $inner (keys(%{$currltisec{'linkprot'}{$id}})) {
+ if (($inner eq 'secret') || ($inner eq 'key')) {
+ if ($is_home) {
+ $newltienc{$id}{$inner} = $currltisec{'linkprot'}{$id}{$inner};
+ }
+ } else {
+ $newltisec{'linkprot'}{$id}{$inner} = $currltisec{'linkprot'}{$id}{$inner};
+ }
+ }
+ } else {
+ $newltisec{'linkprot'}{$id} = $currltisec{'linkprot'}{$id};
+ }
+ }
+ }
+ }
+ if ($proterror) {
+ $errors .= ''.$proterror.' ';
+ }
+
+ my ($putresult,%keystore);
+ if (keys(%secchanges)) {
+ my %ltienchash;
+ my %ltihash = (
+ 'ltisec' => { %newltisec }
+ );
+ $putresult = &Apache::lonnet::put_dom('configuration',\%ltihash,$dom);
+ if ($putresult eq 'ok') {
+ if ($secchanges{'private'}) {
+ my $who = &escape($env{'user.name'}.':'.$env{'user.domain'});
+ foreach my $hostid (keys(%newkeyset)) {
+ my $storehash = {
+ key => $newkeyset{$hostid},
+ who => $env{'user.name'}.':'.$env{'user.domain'},
+ };
+ $keystore{$hostid} = &Apache::lonnet::store_dom($storehash,'lti','private',
+ $dom,$hostid);
+ }
+ }
+ if (ref($lastactref) eq 'HASH') {
+ if (($secchanges{'encrypt'}) || ($secchanges{'private'})) {
+ $lastactref->{'domdefaults'} = 1;
+ }
+ }
+ if (($secchanges{'linkprot'}) && ($is_home)) {
+ my %ltienchash = (
+ 'linkprot' => { %newltienc }
+ );
+ &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom,undef,1);
+ }
+ }
+ } else {
+ return &mt('No changes made.');
+ }
+ if ($putresult eq 'ok') {
+ $resulttext = &mt('Changes made:').'';
+ foreach my $item (keys(%secchanges)) {
+ if ($item eq 'encrypt') {
+ my %encrypted = (
+ crs => {
+ on => &mt('Encryption of stored link protection secrets defined in courses enabled'),
+ off => &mt('Encryption of stored link protection secrets defined in courses disabled'),
+ },
+ dom => {
+ on => &mt('Encryption of stored link protection secrets defined in domain enabled'),
+ off => &mt('Encryption of stored link protection secrets defined in domain disabled'),
+ },
+ );
+ foreach my $type ('crs','dom') {
+ my $shown = $encrypted{$type}{'off'};
+ if (ref($newltisec{$item}) eq 'HASH') {
+ if ($newltisec{$item}{$type}) {
+ $shown = $encrypted{$type}{'on'};
+ }
+ }
+ $resulttext .= ''.$shown.' ';
+ }
+ } elsif ($item eq 'rules') {
+ my %titles = &Apache::lonlocal::texthash(
+ min => 'Minimum password length',
+ max => 'Maximum password length',
+ chars => 'Required characters',
+ );
+ foreach my $rule ('min','max') {
+ if ($newltisec{rules}{$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},$newltisec{rules}{$rule}).' ';
+ }
+ }
+ if (ref($newltisec{'rules'}{'chars'}) eq 'ARRAY') {
+ if (@{$newltisec{'rules'}{'chars'}} > 0) {
+ my %rulenames = &Apache::lonlocal::texthash(
+ uc => 'At least one upper case letter',
+ lc => 'At least one lower case letter',
+ num => 'At least one number',
+ spec => 'At least one non-alphanumeric',
+ );
+ my $needed = ''.
+ join(' ',map {$rulenames{$_} } @{$newltisec{'rules'}{'chars'}}).
+ ' ';
+ $resulttext .= ''.&mt('[_1] set to: [_2]',$titles{'chars'},$needed).' ';
+ } else {
+ $resulttext .= ''.&mt('[_1] set to none',$titles{'chars'}).' ';
+ }
+ } else {
+ $resulttext .= ''.&mt('[_1] set to none',$titles{'chars'}).' ';
+ }
+ } elsif ($item eq 'private') {
+ if (keys(%newkeyset)) {
+ foreach my $hostid (sort(keys(%newkeyset))) {
+ if ($keystore{$hostid} eq 'ok') {
+ $resulttext .= ''.&mt('Encryption key for storage of shared secrets saved for [_1]',$hostid).' ';
+ }
+ }
+ }
+ } elsif ($item eq 'linkprot') {
+ $resulttext .= $linkprotoutput;
+ }
+ }
+ $resulttext .= ' ';
+ } else {
+ $errors .= ''.&mt('Failed to save changes').' ';
+ }
+ if ($errors) {
+ $resulttext .= &mt('The following errors occurred: ').'';
+ }
+ return $resulttext;
+}
+
sub modify_autoenroll {
my ($dom,$lastactref,%domconfig) = @_;
my ($resulttext,%changes);
@@ -14075,56 +14773,7 @@ sub modify_passwords {
$updatedefaults = 1;
}
}
- foreach my $rule ('min','max','numsaved') {
- $env{'form.passwords_'.$rule} =~ s/^\s+|\s+$//g;
- my $ruleok;
- if ($rule eq 'min') {
- if ($env{'form.passwords_'.$rule} =~ /^\d+$/) {
- if ($env{'form.passwords_'.$rule} >= $Apache::lonnet::passwdmin) {
- $ruleok = 1;
- }
- }
- } elsif (($env{'form.passwords_'.$rule} =~ /^\d+$/) &&
- ($env{'form.passwords_'.$rule} ne '0')) {
- $ruleok = 1;
- }
- if ($ruleok) {
- $newvalues{$rule} = $env{'form.passwords_'.$rule};
- if (exists($current{$rule})) {
- if ($newvalues{$rule} ne $current{$rule}) {
- $changes{'rules'} = 1;
- }
- } elsif ($rule eq 'min') {
- if ($staticdefaults{$rule} ne $newvalues{$rule}) {
- $changes{'rules'} = 1;
- }
- } else {
- $changes{'rules'} = 1;
- }
- } elsif (exists($current{$rule})) {
- $changes{'rules'} = 1;
- }
- }
- my @posschars = &Apache::loncommon::get_env_multiple('form.passwords_chars');
- my @chars;
- foreach my $item (sort(@posschars)) {
- if ($item =~ /^(uc|lc|num|spec)$/) {
- push(@chars,$item);
- }
- }
- $newvalues{'chars'} = \@chars;
- unless ($changes{'rules'}) {
- if (ref($current{'chars'}) eq 'ARRAY') {
- my @diffs = &Apache::loncommon::compare_arrays($current{'chars'},\@chars);
- if (@diffs > 0) {
- $changes{'rules'} = 1;
- }
- } else {
- if (@chars > 0) {
- $changes{'rules'} = 1;
- }
- }
- }
+ &password_rule_changes('passwords',\%newvalues,\%current,\%changes);
my %crsownerchg = (
by => [],
for => [],
@@ -14384,6 +15033,71 @@ sub modify_passwords {
return $resulttext;
}
+sub password_rule_changes {
+ my ($prefix,$newvalues,$current,$changes) = @_;
+ return unless ((ref($newvalues) eq 'HASH') &&
+ (ref($current) eq 'HASH') &&
+ (ref($changes) eq 'HASH'));
+ my (@rules,%staticdefaults);
+ if ($prefix eq 'passwords') {
+ @rules = ('min','max','numsaved');
+ } elsif ($prefix eq 'secrets') {
+ @rules = ('min','max');
+ }
+ $staticdefaults{'min'} = $Apache::lonnet::passwdmin;
+ foreach my $rule (@rules) {
+ $env{'form.'.$prefix.'_'.$rule} =~ s/^\s+|\s+$//g;
+ my $ruleok;
+ if ($rule eq 'min') {
+ if ($env{'form.'.$prefix.'_'.$rule} =~ /^\d+$/) {
+ if ($env{'form.'.$prefix.'_'.$rule} >= $staticdefaults{$rule}) {
+ $ruleok = 1;
+ }
+ }
+ } elsif (($env{'form.'.$prefix.'_'.$rule} =~ /^\d+$/) &&
+ ($env{'form.'.$prefix.'_'.$rule} ne '0')) {
+ $ruleok = 1;
+ }
+ if ($ruleok) {
+ $newvalues->{$rule} = $env{'form.'.$prefix.'_'.$rule};
+ if (exists($current->{$rule})) {
+ if ($newvalues->{$rule} ne $current->{$rule}) {
+ $changes->{'rules'} = 1;
+ }
+ } elsif ($rule eq 'min') {
+ if ($staticdefaults{$rule} ne $newvalues->{$rule}) {
+ $changes->{'rules'} = 1;
+ }
+ } else {
+ $changes->{'rules'} = 1;
+ }
+ } elsif (exists($current->{$rule})) {
+ $changes->{'rules'} = 1;
+ }
+ }
+ my @posschars = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_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;
+ }
+ }
+ }
+ return;
+}
+
sub modify_usercreation {
my ($dom,%domconfig) = @_;
my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);
@@ -15698,16 +16412,58 @@ sub modify_defaults {
}
} elsif ($item eq 'portal_def') {
if ($newvalues{$item} ne '') {
- unless ($newvalues{$item} =~ /^https?\:\/\/(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])\/?$/) {
+ if ($newvalues{$item} =~ /^https?\:\/\/(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])\/?$/) {
+ foreach my $field ('email','web') {
+ if ($env{'form.'.$item.'_'.$field}) {
+ $newvalues{$item.'_'.$field} = $env{'form.'.$item.'_'.$field};
+ }
+ }
+ } else {
push(@errors,$item);
}
}
}
if (grep(/^\Q$item\E$/,@errors)) {
$newvalues{$item} = $domdefaults{$item};
+ if ($item eq 'portal_def') {
+ if ($domdefaults{$item}) {
+ foreach my $field ('email','web') {
+ if (exists($domdefaults{$item.'_'.$field})) {
+ $newvalues{$item.'_'.$field} = $domdefaults{$item.'_'.$field};
+ }
+ }
+ }
+ }
} elsif ($domdefaults{$item} ne $newvalues{$item}) {
$changes{$item} = 1;
}
+ if ($item eq 'portal_def') {
+ unless (grep(/^\Q$item\E$/,@errors)) {
+ if ($newvalues{$item} eq '') {
+ foreach my $field ('email','web') {
+ if (exists($domdefaults{$item.'_'.$field})) {
+ delete($domdefaults{$item.'_'.$field});
+ }
+ }
+ } else {
+ unless ($changes{$item}) {
+ foreach my $field ('email','web') {
+ if ($domdefaults{$item.'_'.$field} ne $newvalues{$item.'_'.$field}) {
+ $changes{$item} = 1;
+ last;
+ }
+ }
+ }
+ foreach my $field ('email','web') {
+ if ($newvalues{$item.'_'.$field}) {
+ $domdefaults{$item.'_'.$field} = $newvalues{$item.'_'.$field};
+ } elsif (exists($domdefaults{$item.'_'.$field})) {
+ delete($domdefaults{$item.'_'.$field});
+ }
+ }
+ }
+ }
+ }
$domdefaults{$item} = $newvalues{$item};
}
my %staticdefaults = (
@@ -15722,6 +16478,41 @@ sub modify_defaults {
$newvalues{$item} = $staticdefaults{$item};
}
}
+ my ($unamemaprules,$ruleorder);
+ my @possunamemaprules = &Apache::loncommon::get_env_multiple('form.unamemap_rule');
+ if (@possunamemaprules) {
+ ($unamemaprules,$ruleorder) =
+ &Apache::lonnet::inst_userrules($dom,'unamemap');
+ if ((ref($unamemaprules) eq 'HASH') && (ref($ruleorder) eq 'ARRAY')) {
+ if (@{$ruleorder} > 0) {
+ my %possrules;
+ map { $possrules{$_} = 1; } @possunamemaprules;
+ foreach my $rule (@{$ruleorder}) {
+ if ($possrules{$rule}) {
+ push(@{$newvalues{'unamemap_rule'}},$rule);
+ }
+ }
+ }
+ }
+ }
+ if (ref($domdefaults{'unamemap_rule'}) eq 'ARRAY') {
+ if (ref($newvalues{'unamemap_rule'}) eq 'ARRAY') {
+ my @rulediffs = &Apache::loncommon::compare_arrays($domdefaults{'unamemap_rule'},
+ $newvalues{'unamemap_rule'});
+ if (@rulediffs) {
+ $changes{'unamemap_rule'} = 1;
+ $domdefaults{'unamemap_rule'} = $newvalues{'unamemap_rule'};
+ }
+ } elsif (@{$domdefaults{'unamemap_rule'}} > 0) {
+ $changes{'unamemap_rule'} = 1;
+ delete($domdefaults{'unamemap_rule'});
+ }
+ } elsif (ref($newvalues{'unamemap_rule'}) eq 'ARRAY') {
+ if (@{$newvalues{'unamemap_rule'}} > 0) {
+ $changes{'unamemap_rule'} = 1;
+ $domdefaults{'unamemap_rule'} = $newvalues{'unamemap_rule'};
+ }
+ }
my %defaults_hash = (
defaults => \%newvalues,
);
@@ -15838,6 +16629,26 @@ sub modify_defaults {
$resulttext .= ''.&mt('Institutional user status types deleted').' ';
}
}
+ } elsif ($item eq 'unamemap_rule') {
+ if (ref($newvalues{'unamemap_rule'}) eq 'ARRAY') {
+ my @rulenames;
+ if (ref($unamemaprules) eq 'HASH') {
+ foreach my $rule (@{$newvalues{'unamemap_rule'}}) {
+ if (ref($unamemaprules->{$rule}) eq 'HASH') {
+ push(@rulenames,$unamemaprules->{$rule}->{'name'});
+ }
+ }
+ }
+ if (@rulenames) {
+ $resulttext .= ''.&mt('Mapping for missing usernames includes: [_1]',
+ '').
+ ' ';
+ } else {
+ $resulttext .= ''.&mt('No mapping for missing usernames via standard log-in').' ';
+ }
+ } else {
+ $resulttext .= ''.&mt('Mapping for missing usernames via standard log-in deleted').' ';
+ }
} else {
my $value = $env{'form.'.$item};
if ($value eq '') {
@@ -15853,7 +16664,20 @@ sub modify_defaults {
$value = $authnames{$shortauth{$value}};
}
$resulttext .= ''.&mt('[_1] set to "[_2]"',$title->{$item},$value).' ';
- $mailmsgtext .= "$title->{$item} set to $value\n";
+ $mailmsgtext .= "$title->{$item} set to $value\n";
+ if ($item eq 'portal_def') {
+ if ($env{'form.'.$item} ne '') {
+ foreach my $field ('email','web') {
+ $value = $env{'form.'.$item.'_'.$field};
+ if ($value) {
+ $value = &mt('Yes');
+ } else {
+ $value = &mt('No');
+ }
+ $resulttext .= ''.&mt('[_1] set to "[_2]"',$title->{$field},$value).' ';
+ }
+ }
+ }
}
}
$resulttext .= ' ';
@@ -16797,8 +17621,9 @@ sub modify_coursedefaults {
'uselcmath' => 'on',
'usejsme' => 'on',
'inline_chem' => 'on',
+ 'ltiauth' => 'off',
);
- my @toggles = ('uselcmath','usejsme','inline_chem');
+ my @toggles = ('uselcmath','usejsme','inline_chem','ltiauth');
my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
'uploadquota_community','uploadquota_textbook','mysqltables_official',
'mysqltables_unofficial','mysqltables_community','mysqltables_textbook');
@@ -17008,8 +17833,8 @@ sub modify_coursedefaults {
if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'}) ||
- ($changes{'inline_chem'})) {
- foreach my $item ('uselcmath','usejsme','inline_chem','texengine') {
+ ($changes{'inline_chem'}) || ($changes{'ltiauth'})) {
+ foreach my $item ('uselcmath','usejsme','inline_chem','texengine','ltiauth') {
if ($changes{$item}) {
$domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
}
@@ -17174,6 +17999,12 @@ sub modify_coursedefaults {
} else {
$resulttext .= ' '.&mt('By default, only course owner and coordinators may clone a course.').' ';
}
+ } elsif ($item eq 'ltiauth') {
+ if ($env{'form.'.$item} eq '1') {
+ $resulttext .= ''.&mt('LTI launch of deep-linked URL need not require re-authentication').' ';
+ } else {
+ $resulttext .= ''.&mt('LTI launch of deep-linked URL will require re-authentication').' ';
+ }
}
}
$resulttext .= '';