--- loncom/interface/courseprefs.pm 2022/02/16 15:58:28 1.104 +++ 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.104 2022/02/16 15:58:28 raeburn Exp $ +# $Id: courseprefs.pm,v 1.112 2022/07/01 01:05:04 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -601,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') { @@ -812,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') { @@ -981,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) { @@ -1477,7 +1481,7 @@ sub process_changes { } sub process_linkprot { - my ($cdom,$cnum,$values,$changes,$context) = @_; + 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})) { @@ -1544,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) { @@ -1589,6 +1593,22 @@ 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; @@ -1656,6 +1676,7 @@ sub process_linkprot { } } else { $linkprot{$itemid}{'secret'} = $current{'secret'}; + $linkprot{$itemid}{'cipher'} = $current{'cipher'}; } } elsif ($env{$secretitem} ne '') { if ($privnum && $cipher) { @@ -1672,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; } @@ -2205,6 +2229,9 @@ sub store_linkprot { if (exists($oldlinkprot->{$id}{'usable'})) { $changes->{$id}->{'usable'} = 1; } + if (exists($oldlinkprot->{$id}{'cipher'})) { + $changes->{$id}->{'cipher'} = $oldlinkprot->{$id}{'cipher'}; + } } } } @@ -2255,7 +2282,7 @@ 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})) { @@ -2271,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}.', '; } @@ -2791,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]; @@ -2815,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 } @@ -5623,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; @@ -5670,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]; @@ -5691,10 +5729,10 @@ sub print_linkprotection { ''. ''; - my ($usersty,$onclickrequser,%checkedrequser); + my ($usersty,$onclickrequser,%checkedrequser,$onclickreturnurl,%checkedreturnurl); if ($ltiauth) { $usersty = 'display:none'; - $onclickrequser = ' onclick="toggleLinkProtReqUser(this.form,'."'requser','optional','1','block','$i'".');"'; + $onclickrequser = ' onclick="toggleLinkProtExtra(this.form,'."'requser','optional','1','block','$i'".');"'; %checkedrequser = ( no => ' checked="checked"', yes => '', @@ -5708,6 +5746,15 @@ sub print_linkprotection { $usersty = 'display:inline-block'; } } + $onclickreturnurl = ' onclick="toggleLinkProtExtra(this.form,'."'returnurl','divurlparam','1','inline-block','$i'".');"'; + %checkedreturnurl = ( + no => ' checked="checked"', + yes => '', + ); + if ($values{'returnurl'} ne '') { + $checkedreturnurl{'yes'} = $checkedreturnurl{'no'}; + $checkedreturnurl{'no'} = ''; + } $datatable .= ''.$desc{'name'}. ': '. @@ -5716,15 +5763,7 @@ sub print_linkprotection { ' '."\n". (' 'x2). ''.$desc{'lifetime'}.':'; - if ($ltiauth) { - $datatable .= (' 'x2).''.$desc{'requser'}.'?'. - ' '. - ''; - } - $datatable .= '

'; + ' value="'.$values{'lifetime'}.'" size="3"'.$disabled.' />

'; if ($values{'key'} ne '') { $datatable .= ''.$desc{'key'}; if ($noedit) { @@ -5756,6 +5795,7 @@ sub print_linkprotection { } else { $datatable .= ''.&mt('Secret required').' - '.$switchmessage.''."\n"; } + $datatable .= ''; } else { if ($values{'usable'} ne '') { $datatable .= '
'. @@ -5767,18 +5807,32 @@ sub print_linkprotection { '  '; } else { $datatable .= ''.$desc{'secret'}.':'. ''. - ''. + ''. ''; } } + $datatable .= '

'. + ''.$desc{'returnurl'}.'?'. + ' '. + ''. + '   '; if ($ltiauth) { - $datatable .= + $datatable .= (' 'x2).''.$desc{'requser'}.'?'. + ' '. + ''. ''. '
'.$lt{'opti'}.''. &linkprot_options($i,$itemcount,$disabled,\%values,\%desc). @@ -5793,39 +5847,54 @@ sub print_linkprotection { $datatable .= ''."\n". ''."\n". ''.&mt('Add').''."\n". - ''; - my ($usersty,$onclickrequser,%checkedrequser); + ''; + my ($usersty,$onclickrequser,%checkedrequser,$onclickreturnurl,%checkedreturnurl); if ($ltiauth) { $usersty = 'display:none'; - $onclickrequser = ' onclick="toggleLinkProtReqUser(this.form,'."'requser','optional','1','block','add'".');"'; + $onclickrequser = ' onclick="toggleLinkProtExtra(this.form,'."'requser','optional','1','block','add'".');"'; %checkedrequser = ( no => ' checked="checked"', yes => '', ); $datatable .= '
'.$lt{'requ'}.''; } + $onclickreturnurl = ' onclick="toggleLinkProtExtra(this.form,'."'returnurl','divurlparam','1','inline-block','add'".');"'; + %checkedreturnurl = ( + no => ' checked="checked"', + yes => '', + ); $datatable .= ''.$desc{'name'}. ': '."\n". (' 'x2). ''.$desc{'version'}.': '."\n". (' 'x2). - ''.$desc{'lifetime'}.': '."\n"; - if ($ltiauth) { - $datatable .= (' 'x2).''.$desc{'requser'}.'?'. - ' '. - ''; - } - $datatable .= '

'; + ''.$desc{'lifetime'}.': '."\n". + '

'; if ($switchserver) { $datatable .= ''.&mt('Key and Secret are required').' - '.$switchmessage.''."\n"; } else { $datatable .= ''.$desc{'key'}.': '."\n". (' 'x2). ''.$desc{'secret'}.':'. - ' '."\n"; + ' '."\n"; + } + $datatable .= '

'. + ''.$desc{'returnurl'}.'?'. + ' '. + ''. + '   '; + if ($ltiauth) { + $datatable .= (' 'x2).''.$desc{'requser'}.'?'. + ' '. + ''; } if ($ltiauth) { $datatable .= '
'. @@ -5845,6 +5914,7 @@ sub linkprot_names { 'lifetime' => 'Nonce lifetime (s)', 'name' => 'Launcher Application', 'secret' => 'Secret', + 'returnurl' => 'Launcher return URL', 'requser' => 'Use identity', 'email' => 'Email address', 'sourcedid' => 'User ID', @@ -5900,7 +5970,7 @@ sub linkprot_options { $checked{'auth'} = ' checked="checked"'; } } - my $onclickuser = ' onclick="toggleLinkProtReqUser(this.form,'."'mapuser','userfield','other','inline-block','$num'".');"'; + my $onclickuser = ' onclick="toggleLinkProtExtra(this.form,'."'mapuser','userfield','other','inline-block','$num'".');"'; my $output = '
'. &mt('Source of LON-CAPA username in LTI request').': '; foreach my $option ('sourcedid','email','other') { @@ -6543,6 +6613,30 @@ sub change_clone { } } } + return; +} + +sub devalidate_remote_courseprefs { + my ($cdom,$cnum,$cachekeys) = @_; + return unless (ref($cachekeys) eq 'HASH'); + my %servers = &Apache::lonnet::internet_dom_servers($cdom); + my %thismachine; + map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); + my @posscached = ('courselti'); + if (keys(%servers)) { + foreach my $server (keys(%servers)) { + next if ($thismachine{$server}); + my @cached; + foreach my $name (@posscached) { + if ($cachekeys->{$name}) { + push(@cached,&escape($name).':'.&escape($cdom.'_'.$cnum)); + } + } + if (@cached) { + &Apache::lonnet::remote_devalidate_cache($server,\@cached); + } + } + } return; }