--- loncom/interface/courseprefs.pm 2022/02/15 04:28:01 1.102 +++ loncom/interface/courseprefs.pm 2022/07/01 01:05:04 1.112 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set configuration settings for a course # -# $Id: courseprefs.pm,v 1.102 2022/02/15 04:28:01 raeburn Exp $ +# $Id: courseprefs.pm,v 1.112 2022/07/01 01:05:04 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -224,6 +224,7 @@ use Apache::lonparmset; use Apache::courseclassifier; use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); +use Crypt::CBC; my $registered_cleanup; my $modified_courses; @@ -600,10 +601,14 @@ sub handler { ); if (($phase eq 'process') && ($parm_permission->{'process'})) { my @allitems = &get_allitems(%prefs); - &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context, - \@prefs_order,\%prefs,\%values, - $cnum,undef,\@allitems, - 'coursepref',$parm_permission); + my $result = &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context, + \@prefs_order,\%prefs,\%values, + $cnum,undef,\@allitems, + 'coursepref',$parm_permission); + if ((ref($result) eq 'HASH') && (keys(%{$result}))) { + $r->rflush(); + &devalidate_remote_courseprefs($cdom,$cnum,$result); + } } elsif (($phase eq 'display') && ($parm_permission->{'display'})) { my $noedit; if (ref($parm_permission) eq 'HASH') { @@ -811,7 +816,7 @@ sub print_config_box { } sub process_changes { - my ($cdom,$cnum,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_; + my ($cdom,$cnum,$action,$values,$item,$changes,$allitems,$disallowed,$crstype,$lastactref) = @_; my (%newvalues,$errors); if (ref($item) eq 'HASH') { if (ref($changes) eq 'HASH') { @@ -980,7 +985,7 @@ sub process_changes { } } elsif ($action eq 'linkprot') { if (ref($values) eq 'HASH') { - $errors = &process_linkprot($cdom,$cnum,$values->{$action},$changes,'course'); + $errors = &process_linkprot($cdom,$cnum,$values->{$action},$changes,'course',$lastactref); } } else { foreach my $entry (@ordered) { @@ -1476,8 +1481,8 @@ sub process_changes { } sub process_linkprot { - my ($cdom,$cnum,$values,$changes,$context) = @_; - my ($dest,$ltiauth,$errors,%linkprot); + my ($cdom,$cnum,$values,$changes,$context,$lastactref) = @_; + my ($home,$dest,$ltiauth,$privkey,$privnum,$cipher,$errors,%linkprot); if (ref($values) eq 'HASH') { foreach my $id (keys(%{$values})) { if ($id =~ /^\d+$/) { @@ -1487,6 +1492,31 @@ sub process_linkprot { } } } + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + my @ids=&Apache::lonnet::current_machine_ids(); + if ($context eq 'domain') { + $home = &Apache::lonnet::domain($cdom,'primary'); + } else { + $home = &Apache::lonnet::homeserver($cnum,$cdom); + } + if ((($context eq 'domain') && ($domdefs{'linkprotenc_dom'})) || + (($context eq 'course') && ($domdefs{'linkprotenc_crs'}))) { + unless (($home eq 'no_host') || ($home eq '')) { + if (grep(/^\Q$home\E$/,@ids)) { + if (ref($domdefs{'privhosts'}) eq 'ARRAY') { + if (grep(/^\Q$home\E$/,@{$domdefs{'privhosts'}})) { + my %privhash = &Apache::lonnet::restore_dom('lti','private',$cdom,$home,1); + $privkey = $privhash{'key'}; + $privnum = $privhash{'version'}; + if (($privnum) && ($privkey ne '')) { + $cipher = Crypt::CBC->new({'key' => $privkey, + 'cipher' => 'DES'}); + } + } + } + } + } + } if ($context eq 'domain') { $dest = '/adm/domainprefs'; $ltiauth = 1; @@ -1518,7 +1548,7 @@ sub process_linkprot { if (ref($values) eq 'HASH') { my @todelete = &Apache::loncommon::get_env_multiple('form.linkprot_del'); my $maxnum = $env{'form.linkprot_maxnum'}; - for (my $i=0; $i<=$maxnum; $i++) { + for (my $i=0; $i<$maxnum; $i++) { my $itemid = $env{'form.linkprot_id_'.$i}; $itemid =~ s/\D+//g; if ($itemid) { @@ -1563,11 +1593,28 @@ sub process_linkprot { $linkprot{$itemid}{$inner} = $env{$formitem}; } } + my $urlitem = 'form.linkprot_returnurl_'.$idx; + my $urlparamname = 'form.linkprot_urlparam_'.$idx; + if ($env{$urlitem} == 1) { + $env{$urlparamname} =~ s/(`)/'/g; + } elsif (exists($env{$urlparamname})) { + $env{$urlparamname} = ''; + } + unless ($idx eq 'add') { + if ((!$current{'returnurl'} && ($env{$urlparamname} ne '')) || + ($current{'returnurl'} && ($env{$urlparamname} eq ''))) { + $haschanges{$itemid} = 1; + } + } + if ($env{$urlparamname} ne '') { + $linkprot{$itemid}{'returnurl'} = $env{$urlparamname}; + } if ($ltiauth) { my $reqitem = 'form.linkprot_requser_'.$idx; $env{$reqitem} =~ s/(`)/'/g; unless ($idx eq 'add') { - if ($current{'requser'} ne $env{$reqitem}) { + if ((!$current{'requser'} && $env{$reqitem}) || + ($current{'requser'} && !$env{$reqitem})) { $haschanges{$itemid} = 1; } } @@ -1619,14 +1666,25 @@ sub process_linkprot { if ($current{'usable'}) { if ($env{'form.linkprot_changesecret_'.$idx}) { if ($env{$secretitem} ne '') { - $linkprot{$itemid}{'secret'} = $env{$secretitem}; + if ($privnum && $cipher) { + $linkprot{$itemid}{'secret'} = $cipher->encrypt_hex($env{$secretitem}); + $linkprot{$itemid}{'cipher'} = $privnum; + } else { + $linkprot{$itemid}{'secret'} = $env{$secretitem}; + } $haschanges{$itemid} = 1; } } else { $linkprot{$itemid}{'secret'} = $current{'secret'}; + $linkprot{$itemid}{'cipher'} = $current{'cipher'}; } } elsif ($env{$secretitem} ne '') { - $linkprot{$itemid}{'secret'} = $env{$secretitem}; + if ($privnum && $cipher) { + $linkprot{$itemid}{'secret'} = $cipher->encrypt_hex($env{$secretitem}); + $linkprot{$itemid}{'cipher'} = $privnum; + } else { + $linkprot{$itemid}{'secret'} = $env{$secretitem}; + } $haschanges{$itemid} = 1; } } @@ -1635,6 +1693,9 @@ sub process_linkprot { foreach my $entry (keys(%haschanges)) { $changes->{$entry} = $linkprot{$entry}; } + if (ref($lastactref) eq 'HASH') { + $lastactref->{'courselti'} = 1; + } } return $errors; } @@ -2141,10 +2202,12 @@ sub store_changes { sub store_linkprot { my ($cdom,$cnum,$context,$changes,$oldlinkprot) = @_; - my ($ltiauth,$lti_save_error,$output,$error,%ltienc,@deletions); + my ($ltiauth,$home,$lti_save_error,$output,$error,%ltienc,@deletions); if ($context eq 'domain') { $ltiauth = 1; + $home = &Apache::lonnet::domain($cdom,'primary'); } else { + $home = &Apache::lonnet::homeserver($cnum,$cdom); if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; } else { @@ -2166,11 +2229,13 @@ sub store_linkprot { if (exists($oldlinkprot->{$id}{'usable'})) { $changes->{$id}->{'usable'} = 1; } + if (exists($oldlinkprot->{$id}{'cipher'})) { + $changes->{$id}->{'cipher'} = $oldlinkprot->{$id}{'cipher'}; + } } } } } - my $chome = &Apache::lonnet::homeserver($cnum,$cdom); my @ids=&Apache::lonnet::current_machine_ids(); if (keys(%ltienc) > 0) { if ($context eq 'domain') { @@ -2180,7 +2245,7 @@ sub store_linkprot { } } } else { - unless (($chome eq 'no_host') || ($chome eq '')) { + unless (($home eq 'no_host') || ($home eq '')) { my $allowed; foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } if ($allowed) { @@ -2202,8 +2267,8 @@ sub store_linkprot { if (&Apache::lonnet::put('lti',$changes,$cdom,$cnum,1) eq 'ok') { my $hashid=$cdom.'_'.$cnum; &Apache::lonnet::devalidate_cache_new('courselti',$hashid); - unless (($chome eq 'no_host') || ($chome eq '')) { - if (grep(/^\Q$chome\E$/,@ids)) { + unless (($home eq 'no_host') || ($home eq '')) { + if (grep(/^\Q$home\E$/,@ids)) { &Apache::lonnet::devalidate_cache_new('courseltienc',$hashid); } } @@ -2217,13 +2282,13 @@ sub store_linkprot { my %values = %{$changes->{$id}}; my %desc = &linkprot_names(); my $display; - foreach my $title ('name','lifetime','version','key','secret') { + foreach my $title ('name','lifetime','version','key','secret','returnurl') { if (($title eq 'key') || ($title eq 'secret')) { if (ref($ltienc{$id}) eq 'HASH') { if (exists($ltienc{$id}{$title})) { if ($title eq 'secret') { my $length = length($ltienc{$id}{$title}); - $display .= $desc{$title}.': '.('*' x $length).', '; + $display .= $desc{$title}.': ['.&mt('not shown').'], '; } else { $display .= $desc{$title}.': '.$ltienc{$id}{$title}.', '; } @@ -2233,6 +2298,10 @@ sub store_linkprot { if ($values{$title} eq 'LTI-1p0') { $display .= $desc{$title}.': 1.1, '; } + } elsif ($title eq 'returnurl') { + if ($values{$title}) { + $display .= &mt('Return URL parameter').': '.$values{$title}.', '; + } } else { $display .= $desc{$title}.': '.$values{$title}.', '; } @@ -2753,7 +2822,7 @@ function toggleLinkProt(form,num,item) { return; } -function toggleLinkProtReqUser(form,item,extra,valon,styleon,num) { +function toggleLinkProtExtra(form,item,extra,valon,styleon,num) { if (document.getElementById('linkprot_'+extra+'_'+num)) { var extraid = document.getElementById('linkprot_'+extra+'_'+num); var itemname = form.elements['linkprot_'+item+'_'+num]; @@ -2777,6 +2846,16 @@ function toggleLinkProtReqUser(form,item } return; } + +function uncheckLinkProtMakeVis(item,num) { + if (document.getElementById('linkprot_'+item+'_'+num)) { + var currtype = document.getElementById('linkprot_'+item+'_'+num).type; + if (currtype.toLowerCase() == 'checkbox') { + document.getElementById('linkprot_'+item+'_'+num).checked = false; + } + } + return; +} ENDSCRIPT } @@ -5585,9 +5664,6 @@ sub menucollections_display { sub print_linkprotection { my ($cdom,$cnum,$settings,$rowtotal,$crstype,$noedit,$context) = @_; - unless (ref($settings) eq 'HASH') { - return; - } my %linkprotection; my $count = 0; @@ -5632,7 +5708,7 @@ sub print_linkprotection { } } - if (ref($settings->{'linkprot'}) eq 'HASH') { + if ((ref($settings) eq 'HASH') && (ref($settings->{'linkprot'}) eq 'HASH')) { if (keys(%{$settings->{'linkprot'}})) { my @current = sort { $a <=> $b } keys(%{$settings->{'linkprot'}}); $next += $current[-1]; @@ -5653,10 +5729,10 @@ sub print_linkprotection { '