--- loncom/interface/domainprefs.pm 2022/02/14 02:48:46 1.405 +++ loncom/interface/domainprefs.pm 2023/11/07 11:50:56 1.431 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.405 2022/02/14 02:48:46 raeburn Exp $ +# $Id: domainprefs.pm,v 1.431 2023/11/07 11:50:56 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -95,8 +95,7 @@ about default quota sizes for portfolio institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), but is now also used to manage availability of user tools: i.e., blogs, aboutme page, and portfolios, and the course request tool, -used by course owners to request creation of a course, and to display/store -default quota sizes for Authoring Spaces. +used by course owners to request creation of a course. Outputs: 1 @@ -105,7 +104,7 @@ $datatable - HTML containing form eleme In the case of course requests, radio buttons are displayed for each institutional affiliate type (and also default, and _LC_adv) for each of the course types (official, unofficial, community, textbook, placement, and lti). -In each case the radio buttons allow the selection of one of four values: +In each case the radio buttons allow the selection of one of four values: 0, approval, validate, autolimit=N (where N is blank, or a positive integer). which have the following effects: @@ -167,6 +166,7 @@ use Apache::lonmsg(); use Apache::lonconfigsettings; use Apache::lonuserutils(); use Apache::loncoursequeueadmin(); +use Apache::courseprefs(); use LONCAPA qw(:DEFAULT :match); use LONCAPA::Enrollment; use LONCAPA::lonauthcgi(); @@ -177,6 +177,7 @@ use DateTime::TimeZone; use DateTime::Locale; use Time::HiRes qw( sleep ); use Net::CIDR; +use Crypt::CBC; my $registered_cleanup; my $modified_urls; @@ -220,17 +221,28 @@ sub handler { 'serverstatuses','requestcourses','helpsettings', 'coursedefaults','usersessions','loadbalancing', 'requestauthor','selfenrollment','inststatus', - 'ltitools','ssl','trust','lti','ltisec','privacy','passwords', - 'proctoring','wafproxy','ipaccess'],$dom); + 'ltitools','toolsec','ssl','trust','lti','ltisec', + 'privacy','passwords','proctoring','wafproxy', + 'ipaccess','authordefaults'],$dom); my %encconfig = &Apache::lonnet::get_dom('encconfig',['ltitools','lti','proctoring','linkprot'],$dom,undef,1); + my ($checked_is_home,$is_home); if (ref($domconfig{'ltitools'}) eq 'HASH') { if (ref($encconfig{'ltitools'}) eq 'HASH') { + my $home = &Apache::lonnet::domain($dom,'primary'); + unless (($home eq 'no_host') || ($home eq '')) { + my @ids=&Apache::lonnet::current_machine_ids(); + if (grep(/^\Q$home\E$/,@ids)) { + $is_home = 1; + } + } + $checked_is_home = 1; foreach my $id (keys(%{$domconfig{'ltitools'}})) { if ((ref($domconfig{'ltitools'}{$id}) eq 'HASH') && (ref($encconfig{'ltitools'}{$id}) eq 'HASH')) { - foreach my $item ('key','secret') { - $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item}; + $domconfig{'ltitools'}{$id}{'key'} = $encconfig{'ltitools'}{$id}{'key'}; + if (($is_home) && ($phase eq 'process')) { + $domconfig{'ltitools'}{$id}{'secret'} = $encconfig{'ltitools'}{$id}{'secret'}; } } } @@ -238,24 +250,38 @@ sub handler { } if (ref($domconfig{'lti'}) eq 'HASH') { if (ref($encconfig{'lti'}) eq 'HASH') { + unless ($checked_is_home) { + my $home = &Apache::lonnet::domain($dom,'primary'); + unless (($home eq 'no_host') || ($home eq '')) { + my @ids=&Apache::lonnet::current_machine_ids(); + if (grep(/^\Q$home\E$/,@ids)) { + $is_home = 1; + } + } + $checked_is_home = 1; + } foreach my $id (keys(%{$domconfig{'lti'}})) { if ((ref($domconfig{'lti'}{$id}) eq 'HASH') && (ref($encconfig{'lti'}{$id}) eq 'HASH')) { - foreach my $item ('key','secret') { - $domconfig{'lti'}{$id}{$item} = $encconfig{'lti'}{$id}{$item}; + $domconfig{'lti'}{$id}{'key'} = $encconfig{'lti'}{$id}{'key'}; + if (($is_home) && ($phase eq 'process')) { + $domconfig{'lti'}{$id}{'secret'} = $encconfig{'lti'}{$id}{'secret'}; } } } } } if (ref($domconfig{'ltisec'}) eq 'HASH') { - if (ref($domconfig{'ltisec'}{'prot'}) eq 'HASH') { + if (ref($domconfig{'ltisec'}{'linkprot'}) eq 'HASH') { if (ref($encconfig{'linkprot'}) eq 'HASH') { - foreach my $id (keys(%{$domconfig{'ltisec'}{'prot'}})) { - if ((ref($domconfig{'ltisec'}{'prot'}{$id}) eq 'HASH') && + foreach my $id (keys(%{$domconfig{'ltisec'}{'linkprot'}})) { + unless ($id =~ /^\d+$/) { + delete($domconfig{'ltisec'}{'linkprot'}{$id}); + } + if ((ref($domconfig{'ltisec'}{'linkprot'}{$id}) eq 'HASH') && (ref($encconfig{'linkprot'}{$id}) eq 'HASH')) { foreach my $item ('key','secret') { - $domconfig{'ltisec'}{'prot'}{$id}{$item} = $encconfig{'linkprot'}{$id}{$item}; + $domconfig{'ltisec'}{'linkprot'}{$id}{$item} = $encconfig{'linkprot'}{$id}{$item}; } } } @@ -279,8 +305,8 @@ sub handler { 'contacts','privacy','usercreation','selfcreation', 'usermodification','scantron','requestcourses','requestauthor', 'coursecategories','serverstatuses','helpsettings','coursedefaults', - 'ltitools','proctoring','selfenrollment','usersessions','ssl', - 'trust','lti'); + 'authordefaults','ltitools','proctoring','selfenrollment', + 'usersessions','ssl','trust','lti'); my %existing; if (ref($domconfig{'loadbalancing'}) eq 'HASH') { %existing = %{$domconfig{'loadbalancing'}}; @@ -324,7 +350,9 @@ sub handler { header => [{col1 => 'Setting', col2 => 'Value'}, {col1 => 'Institutional user types', - col2 => 'Name displayed'}], + col2 => 'Name displayed'}, + {col1 => 'Mapping for missing usernames via standard log-in', + col2 => 'Rules in use'}], print => \&print_defaults, modify => \&modify_defaults, }, @@ -354,11 +382,11 @@ sub handler { modify => \&modify_passwords, }, 'quotas' => - { text => 'Blogs, personal web pages, webDAV/quotas, portfolios', + { text => 'Blogs, personal pages/timezones, portfolio/quotas', help => 'Domain_Configuration_Quotas', header => [{col1 => 'User affiliation', col2 => 'Available tools', - col3 => 'Quotas, MB; (Authoring requires role)',}], + col3 => 'Portfilo quota (MB)',}], print => \&print_quotas, modify => \&modify_quotas, }, @@ -540,7 +568,7 @@ sub handler { modify => \&modify_selfenrollment, }, 'privacy' => - {text => 'Availability of User Information', + {text => 'Role assignments and user privacy', help => 'Domain_Configuration_User_Privacy', header => [{col1 => 'Role assigned in different domain', col2 => 'Approval options'}, @@ -576,11 +604,15 @@ sub handler { print => \&print_loadbalancing, modify => \&modify_loadbalancing, }, - 'ltitools' => + 'ltitools' => {text => 'External Tools (LTI)', help => 'Domain_Configuration_LTI_Tools', - header => [{col1 => 'Setting', - col2 => 'Value',}], + header => [{col1 => 'Encryption of shared secrets', + col2 => 'Settings'}, + {col1 => 'Rules for shared secrets', + col2 => 'Settings'}, + {col1 => 'Providers', + col2 => 'Settings',}], print => \&print_ltitools, modify => \&modify_ltitools, }, @@ -630,21 +662,21 @@ sub handler { print => \&print_trust, modify => \&modify_trust, }, - 'lti' => + 'lti' => {text => 'LTI Link Protection and LTI Consumers', help => 'Domain_Configuration_LTI_Provider', header => [{col1 => 'Encryption of shared secrets', col2 => 'Settings'}, - {col1 => 'Rules for shared secrets', + {col1 => 'Rules for shared secrets', col2 => 'Settings'}, - {col1 => 'Link Protectors (domain)', + {col1 => 'Link Protectors', col2 => 'Settings'}, {col1 => 'Consumers', col2 => 'Settings'},], print => \&print_lti, modify => \&modify_lti, }, - 'ipaccess' => + 'ipaccess' => {text => 'IP-based access control', help => 'Domain_Configuration_IP_Access', header => [{col1 => 'Setting', @@ -652,6 +684,16 @@ sub handler { print => \&print_ipaccess, modify => \&modify_ipaccess, }, + 'authordefaults' => + {text => 'Authoring Space defaults', + help => 'Domain_Configuration_Author_Defaults', + header => [{col1 => 'Defaults which can be overridden by Author', + col2 => 'Settings',}, + {col1 => 'Defaults which can be overridden by a Dom. Coord.', + col2 => 'Settings',},], + print => \&print_authordefaults, + modify => \&modify_authordefaults, + }, ); if (keys(%servers) > 1) { $prefs{'login'} = { text => 'Log-in page options', @@ -850,13 +892,15 @@ sub process_changes { } elsif ($action eq 'lti') { $output = &modify_lti($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'privacy') { - $output = &modify_privacy($dom,%domconfig); + $output = &modify_privacy($dom,$lastactref,%domconfig); } elsif ($action eq 'passwords') { $output = &modify_passwords($r,$dom,$confname,$lastactref,%domconfig); } elsif ($action eq 'wafproxy') { $output = &modify_wafproxy($dom,$action,$lastactref,%domconfig); } elsif ($action eq 'ipaccess') { $output = &modify_ipaccess($dom,$lastactref,%domconfig); + } elsif ($action eq 'authordefaults') { + $output = &modify_authordefaults($dom,$lastactref,%domconfig); } return $output; } @@ -885,12 +929,12 @@ sub print_config_box { &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); $output = - &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, + &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, \@templateroles); } elsif ($action eq 'ltitools') { - $output .= <itools_javascript($settings); + $output .= &Apache::lonconfigsettings::ltitools_javascript($settings); } elsif ($action eq 'lti') { - $output .= &passwords_javascript('secrets')."\n". + $output .= &passwords_javascript('ltisecrets')."\n". <i_javascript($dom,$settings); } elsif ($action eq 'proctoring') { $output .= &proctoring_javascript($settings); @@ -904,6 +948,8 @@ sub print_config_box { $output .= &saml_javascript(); } elsif ($action eq 'ipaccess') { $output .= &ipaccess_javascript($settings); + } elsif ($action eq 'authordefaults') { + $output .= &authordefaults_javascript(); } $output .= '
'.$choices{'hostid'}.' | '. ''.$choices{'samllanding'}.' | '. ''.$choices{'samloptions'}.' | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'.$domservers{$lonhost}.' | '. ''. ' | '.
- '
'. + '
| ';
@@ -2351,7 +2411,7 @@ sub print_quotas {
} else {
$context = $action;
}
- my ($datatable,$defaultquota,$authorquota,@usertools,@options,%validations);
+ my ($datatable,$defaultquota,@usertools,@options,%validations);
my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
my $typecount = 0;
my ($css_class,%titles);
@@ -2365,12 +2425,12 @@ sub print_quotas {
@options = ('norequest','approval','automatic');
%titles = &authorrequest_titles();
} else {
- @usertools = ('aboutme','blog','webdav','portfolio');
+ @usertools = ('aboutme','blog','portfolio','portaccess','timezone');
%titles = &tool_titles();
}
if (ref($types) eq 'ARRAY') {
foreach my $type (@{$types}) {
- my ($currdefquota,$currauthorquota);
+ my $currdefquota;
unless (($context eq 'requestcourses') ||
($context eq 'requestauthor')) {
if (ref($settings) eq 'HASH') {
@@ -2379,9 +2439,6 @@ sub print_quotas {
} else {
$currdefquota = $settings->{$type};
}
- if (ref($settings->{authorquota}) eq 'HASH') {
- $currauthorquota = $settings->{authorquota}->{$type};
- }
}
}
if (defined($usertypes->{$type})) {
@@ -2469,9 +2526,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" ';
@@ -2496,13 +2556,9 @@ sub print_quotas {
($context eq 'requestauthor')) {
$datatable .=
''.
- ''.&mt('Portfolio').': '.
+ ''.
''.(' ' x 2).
- ''.&mt('Authoring').': '.
- ' | ';
}
$datatable .= '';
@@ -2511,16 +2567,12 @@ sub print_quotas {
}
unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
$defaultquota = '20';
- $authorquota = '500';
if (ref($settings) eq 'HASH') {
if (ref($settings->{'defaultquota'}) eq 'HASH') {
$defaultquota = $settings->{'defaultquota'}->{'default'};
} elsif (defined($settings->{'default'})) {
$defaultquota = $settings->{'default'};
}
- if (ref($settings->{'authorquota'}) eq 'HASH') {
- $authorquota = $settings->{'authorquota'}->{'default'};
- }
}
}
$typecount ++;
@@ -2632,12 +2684,9 @@ sub print_quotas {
$datatable .= '';
unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
$datatable .= ''.
- ''.&mt('Portfolio').': '.
+ ''.
''.(' ' x2).
- ''.&mt('Authoring').': '.
- ' | ';
+ $defaultquota.'" size="5" />';
}
$datatable .= '';
$typecount ++;
@@ -3410,8 +3459,17 @@ ENDSCRIPT
sub lti_javascript {
my ($dom,$settings) = @_;
my $togglejs = <i_toggle_js($dom);
+ my $linkprot_js = &Apache::courseprefs::linkprot_javascript();
unless (ref($settings) eq 'HASH') {
- return $togglejs;
+ return $togglejs.'
+
+';
}
my (%ordered,$total,%jstext);
$total = scalar(keys(%{$settings}));
@@ -3473,6 +3531,9 @@ $jstext
}
return;
}
+
+$linkprot_js
+
// ]]>
@@ -3492,7 +3553,6 @@ sub lti_toggle_js {
my %servers = &Apache::lonnet::get_servers($dom,'library');
my $primary = &Apache::lonnet::domain($dom,'primary');
my $course_servers = "'".join("','",keys(%servers))."'";
-
return <<"ENDSCRIPT";
@@ -3894,16 +3836,16 @@ sub saml_javascript {
return <<"ENDSCRIPT";
+
+ENDSCRIPT
+}
+
sub print_autoenroll {
my ($dom,$settings,$rowtotal) = @_;
my $autorun = &Apache::lonnet::auto_run(undef,$dom),
@@ -4671,7 +4646,7 @@ sub print_contacts {
map {$excluded{$_} = 1; } @{$lonstatus{'excluded'}};
}
}
- foreach my $item ('errorthreshold','errorsysmail') {
+ foreach my $item ('errorthreshold','errorsysmail') {
$css_class = $rownum%2?' class="LC_odd_row"':'';
$datatable .= ''.
@@ -4753,7 +4728,7 @@ sub print_contacts {
$includeloc{'override_'.$key} = '';
$includestr{'override_'.$key} = '';
if ($settings->{'overrides'}{$key}{'include'} ne '') {
- ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =
+ ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =
split(/:/,$settings->{'overrides'}{$key}{'include'},2);
$includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});
}
@@ -4765,7 +4740,6 @@ sub print_contacts {
my $optionsprefix = 'LC_options_helpdesk_';
my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";
-
$datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
$numinrow,$othertitle,'overrides',
\$rownum,$onclicktypes,$customclass);
@@ -4832,7 +4806,7 @@ sub overridden_helpdesk {
}
my $title;
if (ref($short_titles) eq 'HASH') {
- $title = $short_titles->{$item};
+ $title = $short_titles->{$item};
}
$output .= ' '.
(' 'x2).
''.$lt{'lifetime'}.':'.
- (' 'x2).
+ 'value="'.$lifetime.'" size="3" /> | '; + if ($key ne '') { + $datatable .= ''.$lt{'key'}; + if ($switchserver) { + $datatable .= ': ['.&mt('[_1] to view/edit',$switchserver).']'; + } else { + $datatable .= ':'; + } + $datatable .= ' '.(' 'x2); + } elsif (!$switchserver) { + $datatable .= ''.$lt{'key'}.':'. + ''. + ' '.(' 'x2); + } + if ($switchserver) { + if ($usable ne '') { + $datatable .= ''. + $lt{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).''. + ''.&mt('Change secret?'). + ' '. ''.$lt{'requser'}.':'. ' '."\n"; + if ($switchserver) { + $datatable .= ''.&mt('Key and Secret are required').' - '.$switchmessage.''."\n"; + } else { + $datatable .= ''.$lt{'key'}.': '."\n". + (' 'x2). + ''.$lt{'secret'}.':'. + ' '. ''.$lt{'requser'}.':'. ' | |||||||||||||||||||||||||||||
'. + $choices{'coursequota'}. + ' | '. + ''.
+ '
| ||||||||||||||||||||||||||||||||||
'. + $choices{'domexttool'}. + ' | '. + ''.
+ '
| ||||||||||||||||||||||||||||||||||
'. + $choices{'exttool'}. + ' | '. + ''.
+ '
| ||||||||||||||||||||||||||||||||||
'. + ''.$titles{'copyright'}. + ' | '. + &selectbox('copyright',$currrights{'copyright'},'', + \&Apache::loncommon::copyrightdescription, + (grep !/^priv|custom$/,(&Apache::loncommon::copyrightids))). + ' | ||||||||||||||||||||||||||||||||||
'. + ''.$titles{'sourceavail'}. + ' | '. + &selectbox('sourceavail',$currrights{'sourceavail'},'', + \&Apache::loncommon::source_copyrightdescription, + (&Apache::loncommon::source_copyrightids)). + ' | ||||||||||||||||||||||||||||||||||
'.$titles{'editors'}.' | '."\n". + ''."\n".
+ '';
+ foreach my $editor (@editors) {
+ my $checked;
+ if (grep(/^\Q$editor\E$/,@{$curreditors})) {
+ $checked = ' checked="checked"';
+ }
+ $datatable .= ' | '."\n".'||||||||||||||||||||||||||||||||||
'.$titles{'webdav_LC_adv'}.' '. + $titles{'webdav_LC_adv_over'}. + ' | '.
+ '';
+ foreach my $option ('none','off','on') {
+ my ($text,$val,$checked);
+ if ($option eq 'none') {
+ $text = $titles{'none'};
+ $val = '';
+ $checked = $checkedno;
+ } elsif ($option eq 'off') {
+ $text = $titles{'overoff'};
+ $val = 0;
+ $checked = $checkedoff;
+ } elsif ($option eq 'on') {
+ $text = $titles{'overon'};
+ $val = 1;
+ $checked = $checkedon;
+ }
+ $datatable .= ' | ||||||||||||||||||||||||||||||||||
'.$titles{'notify'}.' | '. + ''; + if ((@instdoms > 1) || (keys(%by_location) > 0)) { + my %curr; + if (ref($settings) eq 'HASH') { + if ($settings->{'notify'} ne '') { + map {$curr{$_}=1;} split(/,/,$settings->{'notify'}); + } + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox', + 'privacy_notify',%curr); + if ($numdc > 0) { + $datatable .= $table; + } else { + $datatable .= &mt('There are no active Domain Coordinators'); + } + } else { + $datatable .= &mt('Nothing to set here, as there are no other domains'); + } + $datatable .=' | ||||||||||||||||||||||||||||||||||
$description | \n". + "$description | \n". ''.
'
|
'."\n".
+ ' '."\n". + ''."\n". + ' | ';
+ } else {
+ my $check = ' ';
+ if (ref($settings) eq 'HASH') {
+ if (ref($settings->{$context}) eq 'ARRAY') {
+ 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 'webdav') {
+ if ($settings->{$context}->{$types->[$i]}) {
+ $check = ' checked="checked" ';
+ }
+ }
+ } elsif ($context eq 'statustocreate') {
$check = ' checked="checked" ';
}
- } elsif ($context eq 'statustocreate') {
- $check = ' checked="checked" ';
}
+ $output .= ''.
+ ' | ';
}
- $output .= ''.
- ' | ';
}
}
$rem = @{$types}%($numinrow);
@@ -12122,7 +12187,7 @@ sub insttypes_row {
} else {
$output .= ''; } - $output .= ' '; + $output .= ' '; } else { if ($rem == 0) { $output .= ' |
';
}
- my $defcheck = ' ';
- if (ref($settings) eq 'HASH') {
- if (ref($settings->{$context}) eq 'ARRAY') {
- if (grep(/^default$/,@{$settings->{$context}})) {
+ if ($context eq 'authorquota') {
+ my $currquota = 500;
+ if ((ref($settings) eq 'HASH') && (ref($settings->{$context}) eq 'HASH')) {
+ if ($settings->{$context}{'default'} =~ /^\d+$/) {
+ $currquota = $settings->{$context}{'default'};
+ }
+ }
+ $output .= ' '."\n". + ''."\n". + ' |
'.&mt('The following errors occurred: ').'
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.