--- loncom/interface/courseprefs.pm	2021/08/04 19:59:10	1.93
+++ 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.93 2021/08/04 19:59:10 raeburn Exp $
+# $Id: courseprefs.pm,v 1.100 2022/02/06 21:36:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -365,11 +365,25 @@ sub handler {
     }
 
     my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
-    my %courselti=&Apache::lonnet::dump('lti',$cdom,$cnum,undef,undef,undef,1);
-    if ($courselti{'lock'}) {
-        delete($courselti{'lock'});
+    my %lti=&Apache::lonnet::dump('lti',$cdom,$cnum,undef,undef,undef,1);
+    my %ltienc = &Apache::lonnet::dump('nohist_ltienc',$cdom,$cnum,undef,undef,undef,1);
+    foreach my $id (keys(%lti)) {
+        if (ref($lti{$id}) eq 'HASH') {
+            if (ref($ltienc{$id}) eq 'HASH') {
+                $values{'linkprotection'}{$id} = { %{$lti{$id}}, %{$ltienc{$id}} };
+            } else {
+                $values{'linkprotection'}{$id} = $lti{$id};
+            }
+        }
+        unless ($phase eq 'process') {
+            if (ref($values{'linkprotection'}{$id}) eq 'HASH') {
+                delete($values{'linkprotection'}{$id}{'secret'});
+            }
+        }
+    }
+    if ($lti{'lock'}) {
+        delete($lti{'lock'});
     }
-    $values{'linkprotection'} = \%courselti;
     my @prefs_order = ('courseinfo','localization','feedback','discussion',
                        'classlists','appearance','grading','printouts',
                        'menuitems','linkprotection','spreadsheet','bridgetasks',
@@ -473,7 +487,7 @@ sub handler {
                      help => 'Course_Prefs_Display',
                      ordered => ['default_xml_style','pageseparators',
                                  'disable_receipt_display','texengine',
-                                 'tthoptions','uselcmath','usejsme'],
+                                 'tthoptions','uselcmath','usejsme','inline_chem'],
                       itemtext => {
                           default_xml_style       => 'Default XML style file',
                           pageseparators          => 'Visibly Separate Items on Pages',
@@ -482,6 +496,7 @@ sub handler {
                           tthoptions              => 'Default set of options to pass to tth/m when converting TeX',
                           uselcmath               => 'Student formula entry uses inline preview, not DragMath pop-up',
                           usejsme                 => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',
+                          inline_chem             => 'Chemical reaction response uses inline preview, not pop-up',
                                   },
                   },
         'grading' =>
@@ -595,7 +610,7 @@ sub handler {
         my $jscript = &get_jscript($cid,$cdom,$phase,$crstype,\%values,$noedit);
         my @allitems = &get_allitems(%prefs);
         &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context,
-            \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype,
+            \@prefs_order,\%prefs,\%values,$cnum,$jscript,\@allitems,$crstype,
             'coursepref',$parm_permission);
     } else {
         &Apache::lonconfigsettings::display_choices($r,$phase,$context,
@@ -648,7 +663,7 @@ sub get_allitems {
 }
 
 sub print_config_box {
-    my ($r,$cdom,$phase,$action,$item,$settings,$allitems,$crstype,$parm_permission) = @_;
+    my ($r,$cdom,$cnum,$phase,$action,$item,$settings,$allitems,$crstype,$parm_permission) = @_;
     my $ordered = $item->{'ordered'};
     my $itemtext = $item->{'itemtext'};
     my $noedit;
@@ -779,7 +794,7 @@ sub print_config_box {
     } elsif ($action eq 'menuitems') {
         $output .= &print_menuitems('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype,$noedit);
     } elsif ($action eq 'linkprotection') {
-        $output .= &print_linkprotection($cdom,$settings,\$rowtotal,$crstype,$noedit);
+        $output .= &print_linkprotection($cdom,$cnum,$settings,\$rowtotal,$crstype,$noedit);
     } elsif ($action eq 'other') {
         $output .= &print_other($cdom,$settings,$allitems,\$rowtotal,$crstype,$noedit);
     }
@@ -793,7 +808,7 @@ sub print_config_box {
 
 sub process_changes {
     my ($cdom,$cnum,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_;
-    my (%newvalues,%courselti,$errors);
+    my (%newvalues,%lti,%ltienc,$ltiauth,$errors);
     if (ref($item) eq 'HASH') {
         if (ref($changes) eq 'HASH') {
             my @ordered;
@@ -811,12 +826,12 @@ sub process_changes {
                     }
                 }
             } elsif ($action eq 'linkprotection') {
-                if (ref($values->{'linkprotection'}) eq 'HASH') {
-                    foreach my $id (keys(%{$values->{'linkprotection'}})) {
+                if (ref($values->{$action}) eq 'HASH') {
+                    foreach my $id (keys(%{$values->{$action}})) {
                         if ($id =~ /^\d+$/) {
                             push(@ordered,$id);
-                            unless (ref($values->{'linkprotection'}->{$id}) eq 'HASH') {
-                                $courselti{$id} = '';
+                            unless (ref($values->{$action}->{$id}) eq 'HASH') {
+                                $lti{$id} = '';
                             }
                         }
                     }
@@ -825,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) =
@@ -964,6 +985,7 @@ sub process_changes {
                     }
                 } elsif ($action eq 'linkprotection') {
                     my %menutitles = &ltimenu_titles();
+                    my $switchserver = &check_switchserver($cdom,$cnum);
                     my (@items,%deletions,%itemids,%haschanges);
                     if ($env{'form.linkprot_add'}) {
                         my $name = $env{'form.linkprot_name_add'};
@@ -979,41 +1001,41 @@ sub process_changes {
                                        '</span>';
                         }
                     }
-                    if (ref($values->{'linkprotection'}) eq 'HASH') {
+                    if (ref($values->{$action}) 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++) {
                             my $itemid = $env{'form.linkprot_id_'.$i};
                             $itemid =~ s/\D+//g;
                             if ($itemid) {
-                                if (ref($values->{'linkprotection'}->{$itemid}) eq 'HASH') {
+                                if (ref($values->{$action}->{$itemid}) eq 'HASH') {
                                     push(@items,$i);
                                     $itemids{$i} = $itemid;
                                     if ((@todelete > 0) && (grep(/^$i$/,@todelete))) {
-                                        $deletions{$itemid} = $values->{'linkprotection'}->{$itemid}->{'name'};
+                                        $deletions{$itemid} = $values->{$action}->{$itemid}->{'name'};
                                     }
                                 }
                             }
                         }
-
                     }
+
                     foreach my $idx (@items) {
                         my $itemid = $itemids{$idx};
                         next unless ($itemid);
                         if (exists($deletions{$itemid})) {
-                            $courselti{$itemid} = $deletions{$itemid};
+                            $lti{$itemid} = $deletions{$itemid};
                             $haschanges{$itemid} = 1;
                             next;
                         }
                         my %current;
-                        if (ref($values->{'linkprotection'}) eq 'HASH') {
-                            if (ref($values->{'linkprotection'}->{$itemid}) eq 'HASH') {
-                                foreach my $key (keys(%{$values->{'linkprotection'}->{$itemid}})) {
-                                    $current{$key} = $values->{'linkprotection'}->{$itemid}->{$key};
+                        if (ref($values->{$action}) eq 'HASH') {
+                            if (ref($values->{$action}->{$itemid}) eq 'HASH') {
+                                foreach my $key (keys(%{$values->{$action}->{$itemid}})) {
+                                    $current{$key} = $values->{$action}->{$itemid}->{$key};
                                 }
                             }
                         }
-                        foreach my $inner ('name','key','secret','lifetime','version') {
+                        foreach my $inner ('name','lifetime','version') {
                             my $formitem = 'form.linkprot_'.$inner.'_'.$idx;
                             $env{$formitem} =~ s/(`)/'/g;
                             if ($inner eq 'lifetime') {
@@ -1025,13 +1047,80 @@ sub process_changes {
                                 }
                             }
                             if ($env{$formitem} ne '') {
-                                $courselti{$itemid}{$inner} = $env{$formitem};
+                                $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;
+                            unless ($idx eq 'add') {
+                                if ($current{'key'} ne $env{$keyitem}) {
+                                    $haschanges{$itemid} = 1;
+                                }
+                            }
+                            if ($env{$keyitem} ne '') {
+                                $lti{$itemid}{'key'} = $env{$keyitem};
+                            }
+                            my $secretitem = 'form.linkprot_secret_'.$idx;
+                            $env{$secretitem} =~ s/(`)/'/g;
+                            if ($current{'usable'}) {
+                                if ($env{'form.linkprot_changesecret_'.$idx}) {
+                                    if ($env{$secretitem} ne '') {
+                                        $lti{$itemid}{'secret'} = $env{$secretitem};
+                                        $haschanges{$itemid} = 1;
+                                    }
+                                } else {
+                                    $lti{$itemid}{'secret'} = $current{'secret'};
+                                }
+                            } elsif ($env{$secretitem} ne '') {
+                                $lti{$itemid}{'secret'} = $env{$secretitem};
+                                $haschanges{$itemid} = 1;
                             }
                         }
                     }
                     if (keys(%haschanges)) {
                         foreach my $entry (keys(%haschanges)) {
-                            $changes->{$entry} = $courselti{$entry};
+                            $changes->{$entry} = $lti{$entry};
                         }
                     }
                 } else {
@@ -1163,7 +1252,9 @@ sub process_changes {
                                         $autocoowner = $domconf{'autoenroll'}{'co-owners'};
                                     }
                                 }
-                                unless ($autocoowner) {
+                                if ($autocoowner) {
+                                    $newvalues{'co-owners'} = $values->{'internal.co-owners'}; 
+                                } else {
                                     my @keepcoowners = &Apache::loncommon::get_env_multiple('form.coowners');
                                     my @pendingcoowners = &Apache::loncommon::get_env_multiple('form.pendingcoowners');
                                     my @invitecoowners =  &Apache::loncommon::get_env_multiple('form.invitecoowners');
@@ -1208,6 +1299,8 @@ sub process_changes {
                                     if ($pendingcoowners ne '') {
                                         @newpending = @pendingcoown;
                                     }
+                                } else {
+                                    @newcoown = @currcoown;
                                 }
                                 $newvalues{'pendingco-owners'} = join(',',sort(@newpending));
                                 $newvalues{'co-owners'} = join(',',sort(@newcoown));
@@ -1650,7 +1743,7 @@ sub store_changes {
         if (grep(/^\Q$item\E$/,@{$actions})) {
             $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
             if (ref($changes->{$item}) eq 'HASH') {
-                if ((keys(%{$changes->{$item}}) > 0) || ($item eq 'linkprotection')) {
+                if (keys(%{$changes->{$item}}) > 0) {
                     $output .= &mt('Changes made:').'<ul style="list-style:none;">';
                     if ($item eq 'other') {
                         foreach my $key (sort(keys(%{$changes->{$item}}))) {
@@ -1664,34 +1757,120 @@ sub store_changes {
                             }
                         }
                     } elsif ($item eq 'linkprotection') {
-                        if (&Apache::lonnet::put('lti',$changes->{'linkprotection'},$cdom,$cnum,1) eq 'ok') {
-                            my $hashid=$cdom.'_'.$cnum;
-                            &Apache::lonnet::devalidate_cache_new('courselti',$hashid);
-                            foreach my $itemid (sort { $a <=> $b } %{$changes->{'linkprotection'}}) {
-                                if (ref($changes->{'linkprotection'}->{$itemid}) eq 'HASH') {
-                                    my %values = %{$changes->{'linkprotection'}->{$itemid}};
-                                    my %desc = &linkprot_names();
-                                    my $display;
-                                    foreach my $title ('name','lifetime','version','key','secret') {
-                                        if ($title eq 'secret') {
-                                            my $length = length($values{$title});
-                                            $display .= $desc{$title}.': '.('*' x $length);
-                                        } elsif ($title eq 'version') {
-                                            if ($values{$title} eq 'LTI-1p0') {
-                                                $display .= $desc{$title}.': 1.1, ';
+                        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') {
+                                    if (exists($changes->{$item}->{$id}->{'key'})) {
+                                        $ltienc{$id}{'key'} = $changes->{$item}->{$id}->{'key'};
+                                        delete($changes->{$item}->{$id}->{'key'});
+                                    }
+                                    if (exists($changes->{$item}->{$id}->{'secret'})) {
+                                        $ltienc{$id}{'secret'} = $changes->{$item}->{$id}->{'secret'};
+                                        delete($changes->{$item}->{$id}->{'secret'});
+                                    } elsif (ref($oldlinkprot{$id}) eq 'HASH') {
+                                        if (exists($oldlinkprot{$id}{'usable'})) {
+                                            $changes->{$item}->{$id}->{'usable'} = 1;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        if (keys(%ltienc) > 0) {
+                            if (&Apache::lonnet::put('nohist_ltienc',\%ltienc,$cdom,$cnum,1) eq 'ok') {
+                                foreach my $id (keys(%ltienc)) {
+                                    if (exists($ltienc{$id}{'secret'})) {
+                                        $changes->{$item}->{$id}->{'usable'} = 1;
+                                    }
+                                }
+                            } else {
+                                $lti_save_error = 1;
+                            }
+                        }
+                        unless ($lti_save_error) {
+                            if (&Apache::lonnet::put('lti',$changes->{$item},$cdom,$cnum,1) eq 'ok') {
+                                my $hashid=$cdom.'_'.$cnum;
+                                &Apache::lonnet::devalidate_cache_new('courselti',$hashid);
+                                $chome = &Apache::lonnet::homeserver($cnum,$cdom);
+                                unless (($chome eq 'no_host') || ($chome eq '')) {
+                                    my @ids=&Apache::lonnet::current_machine_ids();
+                                    if (grep(/^\Q$chome\E$/,@ids)) {
+                                        &Apache::lonnet::devalidate_cache_new('courseltienc',$hashid);
+                                    }
+                                }
+                                foreach my $id (sort { $a <=> $b } %{$changes->{$item}}) {
+                                    if (ref($changes->{$item}->{$id}) eq 'HASH') {
+                                        my %values = %{$changes->{$item}->{$id}};
+                                        my %desc = &linkprot_names();
+                                        my $display;
+                                        foreach my $title ('name','lifetime','version','key','secret') {
+                                            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).', ';
+                                                        } else {
+                                                            $display .= $desc{$title}.': '.$ltienc{$id}{$title}.', ';
+                                                        }
+                                                    }
+                                                }
+                                            } elsif ($title eq 'version') {
+                                                if ($values{$title} eq 'LTI-1p0') {
+                                                    $display .= $desc{$title}.': 1.1, ';
+                                                }
+                                            } else {
+                                                $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').', ';
+                                                }
                                             }
-                                        } else {
-                                            $display .= $desc{$title}.': '.$values{$title}.', ';
                                         }
+                                        $display =~ s/, $//;
+                                        $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.$id.'</i>',
+                                                   "'$display'")).'</li>';
+                                    } elsif (ref($oldlinkprot{$id}) eq 'HASH') {
+                                        my $oldname = $oldlinkprot{$id}{'name'};
+                                        $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]','<i>'."$id ($oldname)".'</i>')).'</li>';
                                     }
-                                    $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.$itemid.'</i>',
-                                               "'$display'")).'</li>';
-                                } elsif (ref($oldlinkprot{$itemid}) eq 'HASH') {
-                                    my $oldname = $oldlinkprot{$itemid}{'name'};
-                                    $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]','<i>'."$itemid ($oldname)".'</i>')).'</li>';
                                 }
+                            } else {
+                                $lti_save_error = 1;
                             }
-                        } else {
+                        }
+                        unless ($lti_save_error) {
+                            my @deletions;
+                            foreach my $id (sort { $a <=> $b } keys(%{$changes->{$item}})) {
+                                unless (ref($changes->{$item}->{$id}) eq 'HASH') {
+                                    push (@deletions,$id);
+                                }
+                            }
+                            if (@deletions) {
+                                &Apache::lonnet::del('nohist_ltienc',\@deletions,$cdom,$cnum);
+                            }
+                        }
+                        if ($lti_save_error) {
                             $output .= '<li>'.
                                        '<span class="LC_error">'.
                                        &mt('An error occurred when saving changes to link protection settings, which remain unchanged.').
@@ -1852,7 +2031,8 @@ sub store_changes {
                                         $displayval = &Apache::lonlocal::locallocaltime($displayval);
                                     } elsif ($key eq 'categories') {
                                         $displayval = $env{'form.categories_display'};
-                                    } elsif (($key eq 'canuse_pdfforms') || ($key eq 'usejsme') || ($key eq 'uselcmath')) {
+                                    } elsif (($key eq 'canuse_pdfforms') || ($key eq 'usejsme') ||
+                                             ($key eq 'uselcmath') || ($key eq 'inline_chem')) {
                                         if ($changes->{$item}{$key} eq '1') {
                                             $displayval = &mt('Yes');
                                         } elsif ($changes->{$item}{$key} eq '0') {
@@ -2369,11 +2549,70 @@ function toggleAddmenucoll() {
 }
 ENDSCRIPT
     }
+    my $linkprotector_js = <<"ENDSCRIPT";
+function toggleLTI(form,num,item) {
+    var radioname = '';
+    var currdivid = '';
+    var newdivid = '';
+    if ((document.getElementById('linkprot_divcurr'+item+'_'+num)) &&
+        (document.getElementById('linkprot_divchg'+item+'_'+num))) {
+        currdivid = document.getElementById('linkprot_divcurr'+item+'_'+num);
+        newdivid = document.getElementById('linkprot_divchg'+item+'_'+num);
+        radioname = form.elements['linkprot_change'+item+'_'+num];
+        if (radioname) {
+            if (radioname.length > 0) {
+                var setvis;
+                for (var i=0; i<radioname.length; i++) {
+                    if (radioname[i].checked == true) {
+                        if (radioname[i].value == 1) {
+                            newdivid.style.display = 'inline-block';
+                            currdivid.style.display = 'none';
+                            setvis = 1;
+                        }
+                        break;
+                    }
+                }
+                if (!setvis) {
+                    newdivid.style.display = 'none';
+                    currdivid.style.display = 'inline-block';
+                }
+            }
+        }
+    }
+    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<itemname.length; i++) {
+                    if (itemname[i].checked == true) {
+                        if (itemname[i].value == valon) {
+                            extraid.style.display = styleon;
+                            setvis = 1;
+                        }
+                        break;
+                    }
+                }
+                if (!setvis) {
+                    extraid.style.display = 'none';
+                }
+            }
+        }
+    }
+    return;
+}
+ENDSCRIPT
     $jscript = '<script type="text/javascript" language="Javascript">'."\n".
                '// <![CDATA['."\n".  
                $browse_js."\n".$categorize_js."\n".$loncaparev_js."\n".
                $cloners_js."\n".$instcode_js.
-               $syllabus_js."\n".$menuitems_js."\n".'//]]>'."\n".
+               $syllabus_js."\n".$menuitems_js."\n".
+               $linkprotector_js."\n".'//]]>'."\n".
                '</script>'."\n".$stubrowse_js."\n";
     return $jscript;
 }
@@ -3804,7 +4043,7 @@ sub coowner_invitations {
         @pendingcoown = split(',',$pendingcoowners);
     }
     if (ref($currcoownref) eq 'ARRAY') {
-        @currcoown == @{$currcoownref};
+        @currcoown = @{$currcoownref};
     }
     my $disabled;
     if ($noedit) {
@@ -3868,7 +4107,7 @@ sub manage_coownership  {
         @pendingcoown = split(',',$pendingcoowners);
     }
     if (ref($currcoownref) eq 'ARRAY') {
-        @currcoown == @{$currcoownref};
+        @currcoown = @{$currcoownref};
     }
     my $disabled;
     if ($noedit) {
@@ -4076,8 +4315,8 @@ sub print_feedback {
         }
         if ($position eq 'top') {
             my $includeempty = 0;
-            $datatable .=  '</td><td align="right">'.
-                           &user_table($cdom,$item,\@sections,
+            $datatable .= '</td><td align="right">'.
+                          &user_table($cdom,$item,\@sections,
                                       $settings->{$item},\%lt,$noedit);
         } else {
             $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
@@ -4300,8 +4539,8 @@ sub print_discussion {
                           '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings,undef,undef,$noedit).
                           '</table>';
         } elsif ($item eq 'plc.users.denied') {
-            $datatable .=  '</td><td align="right">'.
-                           &user_table($cdom,$item,undef,
+            $datatable .= '</td><td align="right">'.
+                          &user_table($cdom,$item,undef,
                                       $settings->{$item},\%lt,$noedit);
         } elsif ($item eq 'pch.roles.denied') {
             $datatable .= '</td><td align="right">'.
@@ -4671,6 +4910,10 @@ sub print_appearance {
                    text => '<b>'.&mt($itemtext->{'usejsme'}).'</b>',
                    input => 'radio',
                  },
+         'inline_chem' => {
+                   text => '<b>'.&mt($itemtext->{'inline_chem'}).'</b>',
+                   input => 'radio',
+                 },
     );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'appearance',$noedit);
 }
@@ -5064,7 +5307,7 @@ sub print_menuitems {
                     my %checked;
                     my $on = ' checked="checked"';
                     foreach my $key (keys(%{$menu{$num}})) {
-                        if (($key eq 'top') || ($key eq 'inline') || ($key eq 'main')) {
+                        if (($key eq 'top') || ($key eq 'inline') || ($key eq 'foot') || ($key eq 'main')) {
                             if ($menu{$num}{$key} eq 'y') {
                                 $checked{$key} = $on;
                             }
@@ -5081,7 +5324,13 @@ sub print_menuitems {
                         foreach my $category (@order) {
                             if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) {
                                 $datatable .= '<fieldset style="vertical-align:top; display:inline-block"><legend>'.$menutitles{$category}.'</legend>'."\n";
+                                if ($category eq 'text') {
+                                    $datatable .= '<i>'.&mt('Header').'</i><br />';
+                                }
                                 foreach my $field (@{$categories{$category}}) {
+                                    if ($field eq 'disc') {
+                                        $datatable .= '<br /><i>'.&mt('Footer').'</i><br />';
+                                    }
                                     $datatable .= '<label><input type="checkbox" name="menucollections_'.$num.'" value="'.$field.'"'.$checked{$field}.$disabled.' />'.
                                                   $menufields{$field}.'</label><br />';
                                 }
@@ -5131,8 +5380,8 @@ sub menuitems_abbreviations {
 sub menuitems_categories {
     my @order = ('shown','text','links','list','inline');
     my %categories = (
-                       shown => ['top','inline','main'],
-                       text  => ['name','role','crs'],
+                       shown => ['top','inline','foot','main'],
+                       text  => ['name','role','crs','disc','fdbk'],
                        links => ['pers','logo','menu','comm','roles','help','logout'],
                        list => ['about','prefs','port','wish','anno','rss'],
                        inline => ['cont','grades','chat','people','groups','resv','syll','feeds'],
@@ -5143,7 +5392,7 @@ sub menuitems_categories {
 sub menuitems_titles {
     return &Apache::lonlocal::texthash (
         shown => 'Hierarchy',
-        text  => 'Header text',
+        text  => 'Text',
         links => 'Header links',
         list => 'Drop-down list',
         inline => 'Inline links',
@@ -5154,6 +5403,7 @@ sub menuitems_fields {
     return &Apache::lonlocal::texthash (
                top => 'Display header',
                inline => 'Display inline menu',
+               foot => 'Display footer',
                main => 'Access to main menu',
                pers => 'Personal',
                logo => 'LON-CAPA',
@@ -5165,6 +5415,8 @@ sub menuitems_fields {
                name => 'Fullname',
                crs => 'Course Title',
                role => 'Current Role',
+               disc => 'Discussion',
+               fdbk => 'Feedback',
                about => 'Information',
                prefs => 'Preferences',
                port => 'Portfolio',
@@ -5206,7 +5458,7 @@ sub menucollections_display {
         foreach my $num (@current) {
             my %checked;
             foreach my $key (keys(%{$menu{$num}})) {
-                if (($key eq 'top') || ($key eq 'inline') || ($key eq 'main')) {
+                if (($key eq 'top') || ($key eq 'inline') || ($key eq 'foot') || ($key eq 'main')) {
                     if ($menu{$num}{$key} eq 'y') {
                         $checked{$key} = 1;
                     }
@@ -5224,7 +5476,13 @@ sub menucollections_display {
                     if ((ref($categories{$category}) eq 'ARRAY') && (@{$categories{$category}} > 0)) {
                         $output .= '<fieldset style="vertical-align:top; display:inline-block">'.
                                    '<legend>'.$menutitles{$category}.'</legend>'."\n";
+                        if ($category eq 'text') {
+                            $output .= '<b>'.&mt('Header Text').'</b><br /><br />';
+                        } 
                         foreach my $field (@{$categories{$category}}) {
+                            if ($field eq 'disc') {
+                                $output .= '<br /><b>'.&mt('Footer Text').'</b><br /><br />';
+                            }
                             if ($checked{$field}) {
                                 $output .= &Apache::lonhtmlcommon::confirm_success($menufields{$field});
                             } else {
@@ -5243,7 +5501,7 @@ sub menucollections_display {
 }
 
 sub print_linkprotection {
-    my ($cdom,$settings,$rowtotal,$crstype,$noedit) = @_;
+    my ($cdom,$cnum,$settings,$rowtotal,$crstype,$noedit) = @_;
     unless (ref($settings) eq 'HASH') {
         return;
     }
@@ -5255,9 +5513,22 @@ sub print_linkprotection {
     if ($noedit) {
         $disabled = ' disabled="disabled"';
     }
-    my %lt = &linkprot_names();
+    my %desc = &linkprot_names();
+    my %lt = &Apache::lonlocal::texthash (
+       'requ'      => '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') {
         if (keys(%{$settings->{'linkprotection'}})) {
             my @current = sort { $a <=> $b } keys(%{$settings->{'linkprotection'}});
@@ -5278,24 +5549,101 @@ sub print_linkprotection {
                 $datatable .=
                     '<tr '.$css_class.'><td><span class="LC_nobreak">'.
                     '<label><input type="checkbox" name="linkprot_del" value="'.$i.'"'.$disabled.' />'.
-                    &mt('Delete?').'</label></span></td>'.
-                    '<td><span class="LC_nobreak">'.$lt{'name'}.
-                    ':<input type="text" size="15" name="linkprot_name_'.$i.'" value="'.$values{'name'}.'"'.$disabled.' /></span> '.
+                    &mt('Delete?').'</label></span></td><td>';
+                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 .= '<fieldset><legend>'.$lt{'requ'}.'</legend>';
+                    if ($values{'requser'}) { 
+                        $usersty = 'display:inline-block';
+                    }
+                }
+                $datatable .=
+                    '<span class="LC_nobreak">'.$desc{'name'}.
+                    ':<input type="text" size="15" name="linkprot_name_'.$i.'" value="'.$values{'name'}.'" autocomplete="off"'.$disabled.' /></span> '.
                     ('&nbsp;'x2).
-                    '<span class="LC_nobreak">'.$lt{'version'}.':<select name="linkprot_version_'.$i.'">'.
+                    '<span class="LC_nobreak">'.$desc{'version'}.':<select name="linkprot_version_'.$i.'"'.$disabled.'>'.
                     '<option value="LTI-1p0" '.$selected.'>1.1</option></select></span> '."\n".
                     ('&nbsp;'x2).
-                    '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" name="linkprot_lifetime_'.$i.'"'.
-                    'value="'.$values{'lifetime'}.'" size="3"'.$disabled.' /></span>'.
-                    '<br /><br />'.
-                    '<span class="LC_nobreak">'.$lt{'key'}.
-                    ':<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'"'.$disabled.' /></span> '.
-                    ('&nbsp;'x2).
-                    '<span class="LC_nobreak">'.$lt{'secret'}.':'.
-                    '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="'.$values{'secret'}.'"'.$disabled.' />'.
-                    '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
-                    '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span>'.
-                    '</td></tr>';
+                    '<span class="LC_nobreak">'.$desc{'lifetime'}.':<input type="text" name="linkprot_lifetime_'.$i.'"'.
+                    ' value="'.$values{'lifetime'}.'" size="3"'.$disabled.' /></span>';
+                if ($ltiauth) {
+                    $datatable .= ('&nbsp;'x2).'<span class="LC_nobreak">'.$desc{'requser'}.'?'.
+                                  '<label><input type="radio" name="linkprot_requser_'.$i.'" value="0"'.
+                                  $onclickrequser.$checkedrequser{'no'}.$disabled.' />'.&mt('No').'</label>&nbsp;'.
+                                  '<label><input type="radio" name="linkprot_requser_'.$i.'" value="1"'.
+                                  $onclickrequser.$checkedrequser{'yes'}.$disabled.' />'.&mt('Yes').'</label></span>'.
+                                  '<br /><br />';
+                }
+                if ($values{'key'} ne '') {
+                    $datatable .= '<span class="LC_nobreak">'.$desc{'key'};
+                    if ($noedit) {
+                        $datatable .= ': ['.&mt('not shown').']';
+                    } elsif ($switchserver) {
+                        $datatable .= ': ['.&mt('[_1] to view/edit',$switchserver).']';
+                    } else {
+                        $datatable .= ':<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' />';
+                    }
+                    $datatable .= '</span> '.('&nbsp;'x2);
+                } elsif (!$switchserver) {
+                    $datatable .= '<span class="LC_nobreak">'.$desc{'key'}.':'.
+                                  '<input type="text" size="25" name="linkprot_key_'.$i.'" value="'.$values{'key'}.'" autocomplete="off"'.$disabled.' />'.
+                                  '</span> '.('&nbsp;'x2);
+                }
+                if ($switchserver) {
+                    if ($values{'usable'} ne '') {
+                        $datatable .= '<div id="linkprot_divcurrsecret_'.$i.'" style="display:inline-block" /><span class="LC_nobreak">'.
+                                      $desc{'secret'}.': ['.&mt('not shown').'] '.('&nbsp;'x2).'</span></div>'.
+                                      '<span class="LC_nobreak">'.&mt('Change secret?').
+                                      '<label><input type="radio" value="0" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLTI(this.form,'."'$i','secret'".');" checked="checked"'.$disabled.' />'.&mt('No').'</label>'.
+                                      ('&nbsp;'x2).
+                                      '<label><input type="radio" value="1" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLTI(this.form,'."'$i','secret'".');" '.$disabled.' />'.&mt('Yes').'</label>'.('&nbsp;'x2).
+                                      '</span><div id="linkprot_divchgsecret_'.$i.'" style="display:none" />'.
+                                      '<span class="LC_nobreak"> - '.&mt("submit from course's home server: [_1].",$switchserver).'</span>'.
+                                      '</div>';
+                    } elsif ($values{'key'} eq '') {
+                        $datatable .= '<span class="LC_nobreak">'.&mt('Key and Secret are required').' - '.&mt("submit from course's home server: [_1].",$switchserver).'</span>'."\n";
+                    } else {
+                        $datatable .= '<span class="LC_nobreak">'.&mt('Secret required').' - '.&mt("submit from course's home server: [_1].",$switchserver).'</span>'."\n";
+                    }
+                } else {
+                    if ($values{'usable'} ne '') {
+                        $datatable .= '<div id="linkprot_divcurrsecret_'.$i.'" style="display:inline-block" /><span class="LC_nobreak">'.
+                                      $desc{'secret'}.': ['.&mt('not shown').'] '.('&nbsp;'x2).'</span></div>'.
+                                      '<span class="LC_nobreak">'.&mt('Change?').
+                                      '<label><input type="radio" value="0" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLTI(this.form,'."'$i','secret'".');" checked="checked"'.$disabled.' />'.&mt('No').'</label>'.
+                                      ('&nbsp;'x2).
+                                      '<label><input type="radio" value="1" name="linkprot_changesecret_'.$i.'" onclick="javascript:toggleLTI(this.form,'."'$i','secret'".');"'.$disabled.' />'.&mt('Yes').
+                                      '</label>&nbsp;&nbsp;</span><div id="linkprot_divchgsecret_'.$i.'" style="display:none" />'.
+                                      '<span class="LC_nobreak">'.&mt('New Secret').':'.
+                                      '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="off"'.$disabled.' />'.
+                                      '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'.
+                                      '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span></div>';
+                    } else {
+                        $datatable .=
+                            '<span class="LC_nobreak">'.$desc{'secret'}.':'.
+                            '<input type="password" size="20" name="linkprot_secret_'.$i.'" value="" autocomplete="off"'.$disabled.' />'.
+                            '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_'.$i.'.type='."'text'".' } else { this.form.linkprot_secret_'.$i.'.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label>'.
+                            '<input type="hidden" name="linkprot_id_'.$i.'" value="'.$num.'" /></span>';
+                    }
+                }
+                if ($ltiauth) {
+                    $datatable .= 
+                        '</fieldset>'.
+                        '<fieldset id="linkprot_optional_'.$i.'" style="'.$usersty.'"><legend>'.$lt{'opti'}.'</legend>'.
+                        &linkprot_options($i,$itemcount,$disabled,\%values,\%desc).
+                        '</fieldset>';
+                }
+                $datatable .= '</td></tr>';
                 $itemcount ++;
             }
         }
@@ -5303,34 +5651,132 @@ sub print_linkprotection {
     $css_class = $itemcount%2?' class="LC_odd_row"':'';
     $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
                   '<input type="hidden" name="linkprot_maxnum" value="'.$next.'" />'."\n".
-                  '<input type="checkbox" name="linkprot_add" value="1" />'.&mt('Add').'</span></td>'."\n".
-                  '<td>'.
-                  '<span class="LC_nobreak">'.$lt{'name'}.
-                  ':<input type="text" size="15" name="linkprot_name_add" value="" /></span> '."\n".
+                  '<input type="checkbox" name="linkprot_add" value="1"'.$disabled.' />'.&mt('Add').'</span></td>'."\n".
+                  '<td>';
+    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 .= '<fieldset><legend>'.$lt{'requ'}.'</legend>';
+    }
+    $datatable .= '<span class="LC_nobreak">'.$desc{'name'}.
+                  ':<input type="text" size="15" name="linkprot_name_add" value="" autocomplete="off"'.$disabled.' /></span> '."\n".
                   ('&nbsp;'x2).
-                  '<span class="LC_nobreak">'.$lt{'version'}.':<select name="linkprot_version_add">'.
+                  '<span class="LC_nobreak">'.$desc{'version'}.':<select name="linkprot_version_add"'.$disabled.'>'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                   ('&nbsp;'x2).
-                  '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="3" name="linkprot_lifetime_add" value="300" /></span> '."\n".
-                  '<br /><br />'.
-                  '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="linkprot_key_add" value="" /></span> '."\n".
-                  ('&nbsp;'x2).
-                  '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="linkprot_secret_add" value="" />'.
-                  '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_add.type='."'text'".' } else { this.form.linkprot_secret_add.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
-                  '</td></tr>';
+                  '<span class="LC_nobreak">'.$desc{'lifetime'}.':<input type="text" size="3" name="linkprot_lifetime_add" value="300"'.$disabled.' /></span> '."\n";
+    if ($ltiauth) {
+        $datatable .= ('&nbsp;'x2).'<span class="LC_nobreak">'.$desc{'requser'}.'?'.
+                      '<label><input type="radio" name="linkprot_requser_add" value="0"'.
+                      $onclickrequser.$checkedrequser{'no'}.$disabled.' />'.&mt('No').'</label>&nbsp;'.
+                      '<label><input type="radio" name="linkprot_requser_add" value="1"'.
+                      $onclickrequser.$checkedrequser{'yes'}.$disabled.' />'.&mt('Yes').'</label></span>';
+    }
+    $datatable .= '<br /><br />';
+    if ($switchserver) {
+        $datatable .= '<span class="LC_nobreak">'.&mt('Key and Secret are required').' - '.&mt("submit from course's home server: [_1].",$switchserver).'</span>'."\n";
+    } else {
+        $datatable .= '<span class="LC_nobreak">'.$desc{'key'}.':<input type="text" size="25" name="linkprot_key_add" value="" autocomplete="off"'.$disabled.' /></span> '."\n".
+                      ('&nbsp;'x2).
+                      '<span class="LC_nobreak">'.$desc{'secret'}.':<input type="password" size="20" name="linkprot_secret_add" value="" autocomplete="off"'.$disabled.' />'.
+                      '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.linkprot_secret_add.type='."'text'".' } else { this.form.linkprot_secret_add.type='."'password'".' }"'.$disabled.' />'.&mt('Visible input').'</label></span> '."\n";
+    }
+    if ($ltiauth) {
+        $datatable .= '</fieldset>'.
+                      '<fieldset id="linkprot_optional_add" style="'.$usersty.'"><legend>'.$lt{'opti'}.'</legend>'.
+                      &linkprot_options('add',$itemcount,$disabled,{},\%desc).
+                     '</fieldset>';
+    }
+    $datatable .= '</td></tr>';
     $$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 {
+    my ($cdom,$cnum) = @_;
+    my ($allowed,$switchserver);
+    my $home = &Apache::lonnet::homeserver($cnum,$cdom);
+    unless ($home eq 'no_host') {
+        my @ids=&Apache::lonnet::current_machine_ids();
+        foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
+        if (!$allowed) {
+            $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&amp;role='.
+                          &HTML::Entities::encode($env{'request.role'},'\'<>"&').
+                          '&amp;destinationurl=/adm/courseprefs">'.&mt('Switch Server').'</a>';
+        }
+    }
+    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 = '<div class="LC_floatleft"><span class="LC_nobreak">'.
+                 &mt('Source of LON-CAPA username in LTI request').':&nbsp;';
+    foreach my $option ('sourcedid','email','other') {
+        $output .= '<label><input type="radio" name="linkprot_mapuser_'.$num.'" value="'.$option.'"'.
+                   $checked{$option}.$onclickuser.$disabled.' />'.$lt{$option}.'</label>'.
+                   ($option eq 'other' ? '' : ('&nbsp;'x2) );
+    }
+    $output .= '</span></div>'.
+               '<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="linkprot_userfield_'.$num.'">'.
+               '<input type="text" name="linkprot_customuser_'.$num.'" '.
+               'value="'.$userfield.'"'.$disabled.' /></div>';
+    $output .= '<br />'.
+               '<div class="LC_floatleft"><span class="LC_nobreak">'.
+               &mt('Action when username is not for an enrolled student').':&nbsp;';
+    foreach my $option ('reject','auth') {
+        $output .= '<label><input type="radio" name="linkprot_notstudent_'.$num.'" value="'.$option.'"'.
+                   $checked{$option}.$disabled.' />'.$lt{$option}.'</label>'.
+                   ($option eq 'auth' ? '' : ('&nbsp;'x2) );
+    }
+    $output .= '</span></div>';
+    return $output;
 }
 
 sub print_other {
@@ -5536,7 +5982,7 @@ sub make_item_rows {
                                                        $settings->{$item},$disabled);
             } elsif ($items->{$item}{input} eq 'radio') {
                 my ($unsetdefault,$valueyes,$valueno);
-                if (($item eq 'usejsme') || ($item eq 'uselcmath')) {
+                if (($item eq 'usejsme') || ($item eq 'uselcmath') || ($item eq 'inline_chem')) {
                      my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                      unless ($domdefs{$item} eq '0') {
                          $unsetdefault = 1;