--- loncom/interface/domainprefs.pm 2022/02/15 04:28:01 1.406 +++ loncom/interface/domainprefs.pm 2023/06/03 19:18:11 1.425 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.406 2022/02/15 04:28:01 raeburn Exp $ +# $Id: domainprefs.pm,v 1.425 2023/06/03 19:18:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -105,7 +105,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 +167,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 +178,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 +222,27 @@ 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'],$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,11 +250,22 @@ 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'}; } } } @@ -327,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, }, @@ -357,7 +382,7 @@ sub handler { modify => \&modify_passwords, }, 'quotas' => - { text => 'Blogs, personal web pages, webDAV/quotas, portfolios', + { text => 'Blogs, personal pages/timezones, webDAV/quotas, portfolio', help => 'Domain_Configuration_Quotas', header => [{col1 => 'User affiliation', col2 => 'Available tools', @@ -579,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, }, @@ -633,12 +662,12 @@ 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', col2 => 'Settings'}, @@ -647,7 +676,7 @@ sub handler { print => \&print_lti, modify => \&modify_lti, }, - 'ipaccess' => + 'ipaccess' => {text => 'IP-based access control', help => 'Domain_Configuration_IP_Access', header => [{col1 => 'Setting', @@ -888,12 +917,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); @@ -948,7 +977,8 @@ sub print_config_box { ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') || ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') || ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') || - ($action eq 'contacts') || ($action eq 'privacy') || ($action eq 'wafproxy') || ($action eq 'lti')) { + ($action eq 'contacts') || ($action eq 'privacy') || ($action eq 'wafproxy') || + ($action eq 'lti') || ($action eq 'ltitools')) { $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal); } elsif ($action eq 'passwords') { $output .= $item->{'print'}->('top',$dom,$confname,$settings,\$rowtotal); @@ -983,8 +1013,9 @@ sub print_config_box { if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'coursecategories') || - ($action eq 'trust') || ($action eq 'contacts') || - ($action eq 'privacy') || ($action eq 'passwords') || ($action eq 'lti')) { + ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults') || + ($action eq 'privacy') || ($action eq 'passwords') || ($action eq 'lti') || + ($action eq 'ltitools')) { if ($action eq 'coursecategories') { $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); $colspan = ' colspan="2"'; @@ -1071,8 +1102,8 @@ sub print_config_box { } $rowtotal ++; } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || - ($action eq 'defaults') || ($action eq 'directorysrch') || - ($action eq 'helpsettings') || ($action eq 'wafproxy')) { + ($action eq 'directorysrch') || ($action eq 'helpsettings') || + ($action eq 'wafproxy')) { $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } elsif ($action eq 'scantron') { $output .= $item->{'print'}->($r,'bottom',$dom,$confname,$settings,\$rowtotal); @@ -1275,8 +1306,7 @@ sub print_config_box { $output .= &print_quotas($dom,$settings,\$rowtotal,$action); } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || - ($action eq 'ltitools') || ($action eq 'proctoring') || - ($action eq 'ipaccess')) { + ($action eq 'proctoring') || ($action eq 'ipaccess')) { $output .= $item->{'print'}->($dom,$settings,\$rowtotal); } } @@ -1626,13 +1656,13 @@ sub print_login { '
'.$choices{'hostid'}.' | '. ''.$choices{'samllanding'}.' | '. ''.$choices{'samloptions'}.' | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'.$domservers{$lonhost}.' | '. ''. ' | '.
- '
'. + '
| ';
@@ -2368,7 +2411,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') {
@@ -2472,9 +2515,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" ';
@@ -3413,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}));
@@ -3432,7 +3487,6 @@ sub lti_javascript {
push(@jsarray,$ordered{$item});
}
my $jstext = ' var lti = Array('."'".join("','",@jsarray)."'".');'."\n";
- my $linkprot_js = &Apache::courseprefs::linkprot_javascript();
return <<"ENDSCRIPT";
@@ -3901,16 +3836,16 @@ sub saml_javascript {
return <<"ENDSCRIPT";
@@ -5372,421 +5305,50 @@ sub radiobutton_prefs {
}
sub print_ltitools {
- my ($dom,$settings,$rowtotal) = @_;
- my $rownum = 0;
- my $css_class;
- my $itemcount = 1;
- my $maxnum = 0;
- my %ordered;
+ my ($position,$dom,$settings,$rowtotal) = @_;
+ my (%rules,%encrypt,%privkeys,%linkprot);
if (ref($settings) eq 'HASH') {
- foreach my $item (keys(%{$settings})) {
- if (ref($settings->{$item}) eq 'HASH') {
- my $num = $settings->{$item}{'order'};
- $ordered{$num} = $item;
- }
- }
- }
- my $confname = $dom.'-domainconfig';
- my $switchserver = &check_switchserver($dom,$confname);
- my $maxnum = scalar(keys(%ordered));
- my $datatable;
- my %lt = <itools_names();
- my @courseroles = ('cc','in','ta','ep','st');
- my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
- my @fields = ('fullname','firstname','lastname','email','roles','user');
- if (keys(%ordered)) {
- my @items = sort { $a <=> $b } keys(%ordered);
- for (my $i=0; $i<@items; $i++) {
- $css_class = $itemcount%2?' class="LC_odd_row"':'';
- my $item = $ordered{$items[$i]};
- my ($title,$key,$secret,$url,$lifetime,$imgsrc,%sigsel);
- if (ref($settings->{$item}) eq 'HASH') {
- $title = $settings->{$item}->{'title'};
- $url = $settings->{$item}->{'url'};
- $key = $settings->{$item}->{'key'};
- $secret = $settings->{$item}->{'secret'};
- $lifetime = $settings->{$item}->{'lifetime'};
- my $image = $settings->{$item}->{'image'};
- if ($image ne '') {
- $imgsrc = '';
- }
- if ($settings->{$item}->{'sigmethod'} eq 'HMAC-256') {
- $sigsel{'HMAC-256'} = ' selected="selected"';
- } else {
- $sigsel{'HMAC-SHA1'} = ' selected="selected"';
- }
- }
- my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_".$item."'".');"';
- $datatable .= ''
- .''.(' 'x2).
- ' | '.
- ''.
- ''.
- '';
- my (%checkedfields,%rolemaps,$userincdom);
- if (ref($settings->{$item}) eq 'HASH') {
- if (ref($settings->{$item}->{'fields'}) eq 'HASH') {
- %checkedfields = %{$settings->{$item}->{'fields'}};
- }
- $userincdom = $settings->{$item}->{'incdom'};
- if (ref($settings->{$item}->{'roles'}) eq 'HASH') {
- %rolemaps = %{$settings->{$item}->{'roles'}};
- $checkedfields{'roles'} = 1;
- }
- }
- $datatable .= ''.
- '';
- my %courseconfig;
- if (ref($settings->{$item}) eq 'HASH') {
- if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') {
- %courseconfig = %{$settings->{$item}->{'crsconf'}};
}
}
- $datatable .= ''.
- ' | '."\n".
- ''."\n".
- ' '."\n".
- ''.&mt('Add').' | '."\n".
- ''.
- ''.
- ''.
- '';
- $datatable .= ''.
- ''.
- ''."\n".
- ' | '."\n".
- ''.&mt('Encryption Key(s)').' | '.
+ ''.
+ ''.&mt('Not in use').' '.
+ $extra.
+ ''.&mt('Encryption Key(s)').' | '.
- ''.
- ''.&mt('Not in use').' '.
- $extra.
- ''; + 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?'). + ''. + (' 'x2). + ''.(' 'x2). + ''. + ' - '.$switchmessage.''. + ''; + } elsif ($key eq '') { + $datatable .= ''.&mt('Key and Secret are required').' - '.$switchmessage.''."\n"; + } else { + $datatable .= ''.&mt('Secret required').' - '.$switchmessage.''."\n"; + } + } else { + if ($usable ne '') { + $datatable .= ''. + $lt{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).''. + ''.&mt('Change?'). + ''. + (' 'x2). + ' '. + ''.&mt('New Secret').':'. + ''. + ''; + } else { + $datatable .= + ''.$lt{'secret'}.':'. + ''. + ''; + } + } + $datatable .= ' '. ''.$lt{'requser'}.':'. ' '."\n". ''."\n". @@ -6690,12 +6329,6 @@ sub print_lti { ' '."\n". ''."\n". (' 'x4). - ''.$lt{'key'}. - ': '. - (' 'x2). - ''.$lt{'secret'}.':'. - ''. - ''. ''. ''.<i_options($i,$current,$itemcount,%lt).''; $itemcount ++; @@ -6724,8 +6357,16 @@ sub print_lti { ''.$lt{'version'}.': '."\n". (' 'x2). - ''.$lt{'lifetime'}.': '."\n". - (' 'x2). + ''.$lt{'lifetime'}.': '."\n"; + if ($switchserver) { + $datatable .= ''.&mt('Key and Secret are required').' - '.$switchmessage.''."\n"; + } else { + $datatable .= ''.$lt{'key'}.': '."\n". + (' 'x2). + ''.$lt{'secret'}.':'. + ' '."\n"; + } + $datatable .= ' '. ''.$lt{'requser'}.':'. ' '."\n". ''."\n". @@ -6733,11 +6374,6 @@ sub print_lti { ''.$lt{'crsinc'}.':'. ' '."\n". ''."\n". - (' 'x4). - ''.$lt{'key'}.': '."\n". - (' 'x2). - ''.$lt{'secret'}.':'. - ' '."\n". ''.<i_options('add',undef,$itemcount,%lt). ''."\n". ''."\n"; @@ -6810,7 +6446,7 @@ sub lti_options { if (($current->{'mapuser'} ne '') && ($current->{'mapuser'} ne 'lis_person_sourcedid')) { $checked{'mapuser'}{'sourcedid'} = ''; if ($current->{'mapuser'} eq 'lis_person_contact_email_primary') { - $checked{'mapuser'}{'email'} = ' checked="checked"'; + $checked{'mapuser'}{'email'} = ' checked="checked"'; } else { $checked{'mapuser'}{'other'} = ' checked="checked"'; $userfield = $current->{'mapuser'}; @@ -6820,7 +6456,7 @@ sub lti_options { if (($current->{'mapcrs'} ne '') && ($current->{'mapcrs'} ne 'course_offering_sourcedid')) { $checked{'mapcrs'}{'course_offering_sourcedid'} = ''; if ($current->{'mapcrs'} eq 'context_id') { - $checked{'mapcrs'}{'context_id'} = ' checked="checked"'; + $checked{'mapcrs'}{'context_id'} = ' checked="checked"'; } else { $checked{'mapcrs'}{'other'} = ' checked="checked"'; $cidfield = $current->{'mapcrs'}; @@ -6848,7 +6484,7 @@ sub lti_options { $checked{'lcauth'}{$1} = ' checked="checked"'; unless (($current->{'lcauth'} eq 'lti') || ($current->{'lcauth'} eq 'internal')) { $lcauthparm = $current->{'lcauthparm'}; - $lcauthparmstyle = 'display:table-row'; + $lcauthparmstyle = 'display:table-row'; if ($current->{'lcauth'} eq 'localauth') { $lcauthparmtext = &mt('Local auth argument'); } else { @@ -6865,7 +6501,7 @@ sub lti_options { %rolemaps = %{$current->{'maproles'}}; } if ($current->{'section'} ne '') { - $checked{'crssec'}{'Y'} = ' checked="checked"'; + $checked{'crssec'}{'Y'} = ' checked="checked"'; $crssecfieldsty = 'inline-block'; if ($current->{'section'} eq 'course_section_sourcedid') { $checked{'crssecsrc'}{'sourcedid'} = ' checked="checked"'; @@ -6911,9 +6547,9 @@ sub lti_options { $checked{'crssec'}{'N'} = ' checked="checked"'; $checked{'callback'}{'N'} = ' checked="checked"'; $checked{'topmenu'}{'N'} = ' checked="checked"'; - $checked{'inlinemenu'}{'Y'} = ' checked="checked"'; + $checked{'inlinemenu'}{'Y'} = ' checked="checked"'; $checked{'menuitem'}{'grades'} = ' checked="checked"'; - $menusty = 'inline-block'; + $menusty = 'inline-block'; } my @coursetypes = ('official','unofficial','community','textbook','placement','lti'); my %coursetypetitles = &Apache::lonlocal::texthash ( @@ -6966,7 +6602,7 @@ sub lti_options { ''. ' | |||||||||||||||||||||||||||||||||
'.&mt('Available conversions').' | ||||||||||||||||||||||||||||||||||||||||||
'. + &mt('No rules set for domain in customized localenroll.pm'). + ' | '; } - $output .= ' '; + $output .= ' '; } else { if ($rem == 0) { $output .= ' | |||||||||||||||||||||||||||||||||||||||||