--- loncom/interface/courseprefs.pm 2022/02/01 23:13:19 1.99 +++ loncom/interface/courseprefs.pm 2022/02/06 21:36:59 1.100 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set configuration settings for a course # -# $Id: courseprefs.pm,v 1.99 2022/02/01 23:13:19 raeburn Exp $ +# $Id: courseprefs.pm,v 1.100 2022/02/06 21:36:59 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -808,7 +808,7 @@ sub print_config_box { sub process_changes { my ($cdom,$cnum,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_; - my (%newvalues,%lti,%ltienc,$errors); + my (%newvalues,%lti,%ltienc,$ltiauth,$errors); if (ref($item) eq 'HASH') { if (ref($changes) eq 'HASH') { my @ordered; @@ -840,6 +840,12 @@ sub process_changes { if (($env{'form.linkprot_add'}) && ($env{'form.linkprot_maxnum'} =~ /^\d+$/)) { push(@ordered,$env{'form.linkprot_maxnum'}); } + if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { + $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; + } else { + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + $ltiauth = $domdefs{'crsltiauth'}; + } } elsif (ref($item->{'ordered'}) eq 'ARRAY') { if ($action eq 'courseinfo') { my ($can_toggle_cat,$can_categorize) = @@ -1044,6 +1050,46 @@ sub process_changes { $lti{$itemid}{$inner} = $env{$formitem}; } } + if ($ltiauth) { + my $reqitem = 'form.linkprot_requser_'.$idx; + $env{$reqitem} =~ s/(`)/'/g; + unless ($idx eq 'add') { + if ($current{'requser'} ne $env{$reqitem}) { + $haschanges{$itemid} = 1; + } + } + if ($env{$reqitem} ne '') { + $lti{$itemid}{'requser'} = $env{$reqitem}; + foreach my $inner ('mapuser','notstudent') { + my $formitem = 'form.linkprot_'.$inner.'_'.$idx; + $env{$formitem} =~ s/(`)/'/g; + if ($inner eq 'mapuser') { + if ($env{$formitem} eq 'other') { + my $mapuser = $env{'form.linkprot_customuser_'.$idx}; + $mapuser =~ s/(`)/'/g; + $mapuser =~ s/^\s+|\s+$//g; + if ($mapuser ne '') { + $lti{$itemid}{$inner} = $mapuser; + } else { + delete($lti{$itemid}{'requser'}); + last; + } + } elsif ($env{$formitem} eq 'sourcedid') { + $lti{$itemid}{$inner} = 'lis_person_sourcedid'; + } elsif ($env{$formitem} eq 'email') { + $lti{$itemid}{$inner} = 'lis_person_contact_email_primary'; + } + } else { + $lti{$itemid}{$inner} = $env{$formitem}; + } + unless ($idx eq 'add') { + if ($current{$inner} ne $lti{$itemid}{$inner}) { + $haschanges{$itemid} = 1; + } + } + } + } + } unless ($switchserver) { my $keyitem = 'form.linkprot_key_'.$idx; $env{$keyitem} =~ s/(`)/'/g; @@ -1711,7 +1757,13 @@ sub store_changes { } } } elsif ($item eq 'linkprotection') { - my (%ltienc,$lti_save_error); + my ($ltiauth,%ltienc,$lti_save_error); + if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { + $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; + } else { + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + $ltiauth = $domdefs{'crsltiauth'}; + } if (ref($changes->{$item}) eq 'HASH') { foreach my $id (sort { $a <=> $b } keys(%{$changes->{$item}})) { if (ref($changes->{$item}->{$id}) eq 'HASH') { @@ -1748,7 +1800,7 @@ sub store_changes { $chome = &Apache::lonnet::homeserver($cnum,$cdom); unless (($chome eq 'no_host') || ($chome eq '')) { my @ids=&Apache::lonnet::current_machine_ids(); - unless (grep(/^\Q$chome\E$/,@ids)) { + if (grep(/^\Q$chome\E$/,@ids)) { &Apache::lonnet::devalidate_cache_new('courseltienc',$hashid); } } @@ -1763,7 +1815,7 @@ sub store_changes { if (exists($ltienc{$id}{$title})) { if ($title eq 'secret') { my $length = length($ltienc{$id}{$title}); - $display .= $desc{$title}.': '.('*' x $length); + $display .= $desc{$title}.': '.('*' x $length).', '; } else { $display .= $desc{$title}.': '.$ltienc{$id}{$title}.', '; } @@ -1777,6 +1829,24 @@ sub store_changes { $display .= $desc{$title}.': '.$values{$title}.', '; } } + if ($ltiauth) { + if (($values{'requser'}) && ($values{'mapuser'} ne '')) { + if ($values{'mapuser'} eq 'lis_person_contact_email_primary') { + $display .= &mt('Source of username: Email address [_1]', + '(lis_person_contact_email_primary)').', '; + } elsif ($values{'mapuser'} eq 'lis_person_sourcedid') { + $display .= &mt('Source of username: User ID [_1]', + '(lis_person_sourcedid)').', '; + } else { + $display .= &mt('Source of username: [_1]',$values{'mapuser'}).', '; + } + if ($values{'notstudent'} eq 'auth') { + $display .= &mt('Display LON-CAPA login page if no match').', '; + } elsif ($values{'notstudent'} eq 'reject') { + $display .= &mt('Discontinue launch if no match').', '; + } + } + } $display =~ s/, $//; $output .= '
  • '.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',''.$id.'', "'$display'")).'
  • '; @@ -2511,6 +2581,31 @@ function toggleLTI(form,num,item) { } return; } + +function toggleLTIReqUser(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]; + if (itemname) { + if (itemname.length > 0) { + var setvis; + for (var i=0; i 'Required settings', + 'opti' => 'Optional settings', + ); my $itemcount = 0; + my $ltiauth; + if (exists($env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'})) { + $ltiauth = $env{'course.'.$env{'request.course.id'}.'.internal.ltiauth'}; + } else { + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + $ltiauth = $domdefs{'crsltiauth'}; + } my $switchserver = &check_switchserver($cdom,$cnum); if (ref($settings->{'linkprotection'}) eq 'HASH') { @@ -5443,18 +5549,43 @@ sub print_linkprotection { $datatable .= ''. ''. - ''.$lt{'name'}. + &mt('Delete?').''; + my ($usersty,$onclickrequser,%checkedrequser); + if ($ltiauth) { + $usersty = 'display:none'; + $onclickrequser = ' onclick="toggleLTIReqUser(this.form,'."'requser','optional','1','block','$i'".');"'; + %checkedrequser = ( + no => ' checked="checked"', + yes => '', + ); + if ($values{'requser'}) { + $checkedrequser{'yes'} = $checkedrequser{'no'}; + $checkedrequser{'no'} = ''; + } + $datatable .= '
    '.$lt{'requ'}.''; + if ($values{'requser'}) { + $usersty = 'display:inline-block'; + } + } + $datatable .= + ''.$desc{'name'}. ': '. (' 'x2). - ''.$lt{'version'}.':'. ' '."\n". (' 'x2). - ''.$lt{'lifetime'}.':'. - '

    '; + ''.$desc{'lifetime'}.':'; + if ($ltiauth) { + $datatable .= (' 'x2).''.$desc{'requser'}.'?'. + ' '. + ''. + '

    '; + } if ($values{'key'} ne '') { - $datatable .= ''.$lt{'key'}; + $datatable .= ''.$desc{'key'}; if ($noedit) { $datatable .= ': ['.&mt('not shown').']'; } elsif ($switchserver) { @@ -5464,14 +5595,14 @@ sub print_linkprotection { } $datatable .= ' '.(' 'x2); } elsif (!$switchserver) { - $datatable .= ''.$lt{'key'}.':'. + $datatable .= ''.$desc{'key'}.':'. ''. ' '.(' 'x2); } if ($switchserver) { if ($values{'usable'} ne '') { $datatable .= '
    '. - $lt{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).'
    '. + $desc{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).'
    '. ''.&mt('Change secret?'). ''. (' 'x2). @@ -5487,7 +5618,7 @@ sub print_linkprotection { } else { if ($values{'usable'} ne '') { $datatable .= '
    '. - $lt{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).'
    '. + $desc{'secret'}.': ['.&mt('not shown').'] '.(' 'x2).'
    '. ''.&mt('Change?'). ''. (' 'x2). @@ -5499,12 +5630,19 @@ sub print_linkprotection { ''; } else { $datatable .= - ''.$lt{'secret'}.':'. + ''.$desc{'secret'}.':'. ''. ''. ''; } } + if ($ltiauth) { + $datatable .= + '
    '. + '
    '.$lt{'opti'}.''. + &linkprot_options($i,$itemcount,$disabled,\%values,\%desc). + '
    '; + } $datatable .= ''; $itemcount ++; } @@ -5514,37 +5652,65 @@ sub print_linkprotection { $datatable .= ''."\n". ''."\n". ''.&mt('Add').''."\n". - ''. - ''.$lt{'name'}. + ''; + my ($usersty,$onclickrequser,%checkedrequser); + if ($ltiauth) { + $usersty = 'display:none'; + $onclickrequser = ' onclick="toggleLTIReqUser(this.form,'."'requser','optional','1','block','add'".');"'; + %checkedrequser = ( + no => ' checked="checked"', + yes => '', + ); + $datatable .= '
    '.$lt{'requ'}.''; + } + $datatable .= ''.$desc{'name'}. ': '."\n". (' 'x2). - ''.$lt{'version'}.':'. ' '."\n". (' 'x2). - ''.$lt{'lifetime'}.': '."\n". - '

    '; + ''.$desc{'lifetime'}.': '."\n"; + if ($ltiauth) { + $datatable .= (' 'x2).''.$desc{'requser'}.'?'. + ' '. + ''; + } + $datatable .= '

    '; if ($switchserver) { $datatable .= ''.&mt('Key and Secret are required').' - '.&mt("submit from course's home server: [_1].",$switchserver).''."\n"; } else { - $datatable .= ''.$lt{'key'}.': '."\n". + $datatable .= ''.$desc{'key'}.': '."\n". (' 'x2). - ''.$lt{'secret'}.':'. + ''.$desc{'secret'}.':'. ' '."\n"; } + if ($ltiauth) { + $datatable .= '
    '. + '
    '.$lt{'opti'}.''. + &linkprot_options('add',$itemcount,$disabled,{},\%desc). + '
    '; + } $datatable .= ''; $$rowtotal ++; return $datatable;; } sub linkprot_names { - my %lt = &Apache::lonlocal::texthash( + return &Apache::lonlocal::texthash( 'version' => 'LTI Version', 'key' => 'Key', 'lifetime' => 'Nonce lifetime (s)', - 'name' => 'Launcher Application Name', + 'name' => 'Launcher Application', 'secret' => 'Secret', + 'requser' => 'Use identity', + 'email' => 'Email address', + 'sourcedid' => 'User ID', + 'other' => 'Other', + 'auth' => 'Display LON-CAPA login page', + 'reject' => 'Discontinue launch process', ); - return %lt; } sub check_switchserver { @@ -5563,6 +5729,56 @@ sub check_switchserver { return $switchserver; } +sub linkprot_options { + my ($num,$itemcount,$disabled,$current,$desc) = @_; + my %lt; + if (ref($desc) eq 'HASH') { + %lt = %{$desc}; + } + my $userfieldsty = 'none'; + my (%checked,$userfield); + $checked{'sourcedid'} = ' checked="checked"'; + $checked{'reject'} = ' checked="checked"'; + if (ref($current) eq 'HASH') { + if (($current->{'mapuser'} ne '') && ($current->{'mapuser'} ne 'lis_person_sourcedid')) { + $checked{'sourcedid'} = ''; + if ($current->{'mapuser'} eq 'lis_person_contact_email_primary') { + $checked{'email'} = ' checked="checked"'; + } else { + $checked{'other'} = ' checked="checked"'; + $userfield = $current->{'mapuser'}; + $userfieldsty = 'inline-block'; + } + } + if (($current->{'notstudent'} ne '') && ($current->{'notstudent'} ne 'reject')) { + $checked{'reject'} = ''; + $checked{'auth'} = ' checked="checked"'; + } + } + my $onclickuser = ' onclick="toggleLTIReqUser(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') { + $output .= ''. + ($option eq 'other' ? '' : (' 'x2) ); + } + $output .= '
    '. + '
    '. + '
    '; + $output .= '
    '. + '
    '. + &mt('Action when username is not for an enrolled student').': '; + foreach my $option ('reject','auth') { + $output .= ''. + ($option eq 'auth' ? '' : (' 'x2) ); + } + $output .= '
    '; + return $output; +} + sub print_other { my ($cdom,$settings,$allitems,$rowtotal,$crstype,$noedit) = @_; unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {