[LON-CAPA-cvs] cvs: loncom /auth lonauth.pm lonlogin.pm migrateuser.pm switchserver.pm /interface domainprefs.pm /lti ltiauth.pm

raeburn raeburn at source.lon-capa.org
Wed Dec 26 15:10:29 EST 2018


raeburn		Wed Dec 26 20:10:29 2018 EDT

  Modified files:              
    /loncom/auth	lonauth.pm lonlogin.pm migrateuser.pm switchserver.pm 
    /loncom/interface	domainprefs.pm 
    /loncom/lti	ltiauth.pm 
  Log:
  - Bug 6400 Deep-linking
    - URLs like /adm/lti/tiny/domain/uniqueID can be used to restrict use of
      deep links to access from another LTI-enabled application (no user data
      passed in this context).
  
  
-------------- next part --------------
Index: loncom/auth/lonauth.pm
diff -u loncom/auth/lonauth.pm:1.155 loncom/auth/lonauth.pm:1.156
--- loncom/auth/lonauth.pm:1.155	Sat Nov 10 10:53:01 2018
+++ loncom/auth/lonauth.pm	Wed Dec 26 20:10:21 2018
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # User Authentication Module
 #
-# $Id: lonauth.pm,v 1.155 2018/11/10 10:53:01 raeburn Exp $
+# $Id: lonauth.pm,v 1.156 2018/12/26 20:10:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -304,6 +304,13 @@
             $retry .= (($retry=~/\?/)?'&':'?').'firsturl='.$firsturl;
         }
     }
+    if (exists($form->{linkprot})) {
+        my $ltoken = &Apache::lonnet::tmpput({linkprot => $form->{'linkprot'}},
+                                             $r->dir_config('lonHostID'));
+        if ($ltoken) {
+            $retry .= (($retry =~ /\?/) ? '&' : '?').'ltoken='.$ltoken;
+        }
+    }
     my $end_page = &Apache::loncommon::end_page();
     &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;
@@ -438,7 +445,7 @@
         return OK;
     }
 
-    my ($key,$firsturl,$rolestr,$symbstr,$iptokenstr)=split(/&/,$tmpinfo);
+    my ($key,$firsturl,$rolestr,$symbstr,$iptokenstr,$linkprotstr)=split(/&/,$tmpinfo);
     if ($rolestr) {
         $rolestr = &unescape($rolestr);
     }
@@ -448,6 +455,9 @@
     if ($iptokenstr) {
         $iptokenstr = &unescape($iptokenstr);
     }
+    if ($linkprotstr) {
+        $linkprotstr = &unescape($linkprotstr);
+    }
     if ($firsturl =~ m{^/tiny/$match_domain/\w+$}) {
         $form{'firsturl'} = $firsturl;
     }
@@ -460,6 +470,9 @@
     if ($iptokenstr =~ /^iptoken=/) {
         (undef,$form{'iptoken'}) = split('=',$iptokenstr);
     }
+    if ($linkprotstr =~ /^linkprot=/) {
+        (undef,$form{'linkprot'}) = split('=',$linkprotstr);
+    }
 
     my $upass = $ENV{HTTPS} ? $form{'upass0'} 
         : &Apache::loncommon::des_decrypt($key,$form{'upass0'});
@@ -632,7 +645,7 @@
                      \%form);
             my $switchto = '/adm/switchserver?otherserver='.$otherserver;
             if (($firsturl) && ($firsturl ne '/adm/switchserver') && ($firsturl ne '/adm/roles')) {
-                $switchto .= '&origurl='.$firsturl;
+                $switchto .= '&origurl='.$firsturl; #should escape
             }
             if ($form{'role'}) {
                 $switchto .= '&role='.$form{'role'};
@@ -640,6 +653,9 @@
             if ($form{'symb'}) {
                 $switchto .= '&symb='.$form{'symb'};
             }
+            if ($form{'linkprot'}) {
+                $env{'request.linkprot'} = $form{'linkprot'};
+            }
             $r->internal_redirect($switchto);
         } else {
             $r->print(&noswitch());
@@ -653,7 +669,7 @@
                          \%form);
                 my $switchto = '/adm/switchserver?otherserver='.$otherserver;
                 if (($firsturl) && ($firsturl ne '/adm/switchserver') && ($firsturl ne '/adm/roles')) {
-                    $switchto .= '&origurl='.$firsturl;
+                    $switchto .= '&origurl='.$firsturl; #should escape
                 }
                 if ($form{'role'}) {
                     $switchto .= '&role='.$form{'role'};
@@ -661,6 +677,9 @@
                 if ($form{'symb'}) {
                     $switchto .= '&symb='.$form{'symb'};
                 }
+                if ($form{'linkprot'}) {
+                    $env{'request.linkprot'} = $form{'linkprot'};
+                }
                 $r->internal_redirect($switchto);
             } else {
                 $r->print(&noswitch());
@@ -690,6 +709,9 @@
             if ($unloaded) {
                 &success($r,$form{'uname'},$form{'udom'},$authhost,'noredirect',
                          undef,\%form);
+                if ($form{'linkprot'}) {
+                    $env{'request.linkprot'} = $form{'linkprot'};
+                }
                 $r->internal_redirect('/adm/switchserver?otherserver='.$unloaded.'&origurl='.$firsturl);
                 return OK;
             }
@@ -697,7 +719,15 @@
         if (($is_balancer) && ($hosthere)) {
             $form{'noloadbalance'} = $hosthere;
         }
-        &success($r,$form{'uname'},$form{'udom'},$authhost,$firsturl,undef,
+        my $extra_env;
+        if ($form{'linkprot'}) {
+            my ($linkprotector,$uri) = split(/:/,$form{'linkprot'},2);
+            if ($linkprotector) {
+                $extra_env = {'user.linkprotector' => $linkprotector,
+                              'user.linkproturi'   => $uri,};
+            }
+        }
+        &success($r,$form{'uname'},$form{'udom'},$authhost,$firsturl,$extra_env,
                  \%form);
         return OK;
     }
@@ -744,6 +774,7 @@
                 my $protocol = $Apache::lonnet::protocol{$login_host};
                 $protocol = 'http' if ($protocol ne 'https');
                 my $newurl = $protocol.'://'.$hostname.'/adm/createaccount';
+#FIXME Should preserve where user was going and linkprot by setting ltoken at $login_host
                 $r->print(&Apache::loncommon::start_page('Create a user account in LON-CAPA').
                           '<h3>'.&mt('Account creation').'</h3>'.
                           &mt('You do not currently have a LON-CAPA account at this institution.').'<br />'.
@@ -760,6 +791,9 @@
         } else {
             &success($r,$form->{'uname'},$udom,$authhost,'noredirect',undef,
                      $form);
+            if ($form->{'linkprot'}) {
+                $env{'request.linkprot'} = $form->{'linkprot'};
+            }
             my ($otherserver) = &Apache::lonnet::choose_server($udom);
             $r->internal_redirect('/adm/switchserver?otherserver='.$otherserver);
         }
Index: loncom/auth/lonlogin.pm
diff -u loncom/auth/lonlogin.pm:1.176 loncom/auth/lonlogin.pm:1.177
--- loncom/auth/lonlogin.pm:1.176	Wed Dec  5 03:29:05 2018
+++ loncom/auth/lonlogin.pm	Wed Dec 26 20:10:21 2018
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Login Screen
 #
-# $Id: lonlogin.pm,v 1.176 2018/12/05 03:29:05 raeburn Exp $
+# $Id: lonlogin.pm,v 1.177 2018/12/26 20:10:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -47,7 +47,7 @@
 	(join('&',$ENV{'QUERY_STRING'},$env{'request.querystring'},
 	      $ENV{'REDIRECT_QUERY_STRING'}),
 	 ['interface','username','domain','firsturl','localpath','localres',
-	  'token','role','symb','iptoken','btoken']);
+	  'token','role','symb','iptoken','btoken','ltoken']);
     if (!defined($env{'form.firsturl'})) {
         &Apache::lonacc::get_posted_cgi($r,['firsturl']);
     }
@@ -124,6 +124,14 @@
             my %info = (
                          balcookie => $lonhost.':'.$balancer_cookie,
                        );
+            if ($env{'form.ltoken'}) {
+                my %link_info = &Apache::lonnet::tmpget($env{'form.ltoken'});
+                if ($link_info{'linkprot'}) {
+                    $info{'linkprot'} = $link_info{'linkprot'};
+                }
+                &Apache::lonnet::tmpdel($env{'form.ltoken'});
+                delete($env{'form.ltoken'});
+            }
             my $balancer_token = &Apache::lonnet::tmpput(\%info,$found_server);
             if ($balancer_token) {
                 $dest .=  (($dest=~/\?/)?'&;':'?') . 'btoken='.$balancer_token;
@@ -143,10 +151,15 @@
 # it a balancer cookie for an active session on this server.
 #
 
-    my $balcookie;
+    my ($balcookie,$linkprot);
     if ($env{'form.btoken'}) {
         my %info = &Apache::lonnet::tmpget($env{'form.btoken'});
         $balcookie = $info{'balcookie'};
+        if ($balcookie) {
+            if ($info{'linkprot'}) {
+                $linkprot = $info{'linkprot'};
+            }
+        }    
         &Apache::lonnet::tmpdel($env{'form.btoken'});
         delete($env{'form.btoken'});
     }
@@ -179,6 +192,37 @@
         if ($env{'form.firsturl'} ne '') {
             $dest = $env{'form.firsturl'};
         }
+        if (($env{'form.ltoken'}) || ($linkprot)) {
+            unless ($linkprot) {
+                my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
+                $linkprot = $info{'linkprot'};
+                my $delete = &Apache::lonnet::tmpdel($env{'form.ltoken'});
+                delete($env{'form.ltoken'});
+            }
+            if ($linkprot) {
+                my ($linkprotector,$deeplink) = split(/:/,$linkprot,2);
+                if ($env{'user.linkprotector'}) {
+                    my @protectors = split(/,/,$env{'user.linkprotector'});
+                    unless (grep(/^\Q$linkprotector\E$/, at protectors)) {
+                        push(@protectors,$linkprotector);
+                        @protectors = sort { $a <=> $b } @protectors;
+                        &Apache::lonnet::appenv({'user.linkprotector' => join(',', at protectors)});
+                    }
+                } else {
+                    &Apache::lonnet::appenv({'user.linkprotector' => $linkprotector });
+                }
+                if ($env{'user.linkproturi'}) {
+                    my @proturis = split(/,/,$env{'user.linkproturi'});
+                    unless(grep(/^\Q$deeplink\E$/, at proturis)) {
+                        push(@proturis,$deeplink);
+                        @proturis = sort @proturis;
+                        &Apache::lonnet::appenv({'user.linkproturi' => join(',', at proturis)});
+                    }
+                } else {
+                    &Apache::lonnet::appenv({'user.linkproturi' => $deeplink});
+                }
+            }
+        }
 	$r->print(
                   $start_page
                  .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
@@ -219,7 +263,7 @@
     my $defdom = $domain;
     if ($lonhost ne '') {
         unless ($sessiondata{'sessionserver'}) {
-            my $redirect = &check_loginvia($domain,$lonhost,$lonidsdir,$balcookie);
+            my $redirect = &check_loginvia($domain,$lonhost,$lonidsdir,$balcookie,$linkprot);
             if ($redirect) {
                 $r->print($redirect);
                 return OK;
@@ -319,6 +363,17 @@
         }
         $tokenextras .= '&iptoken='.&escape($env{'form.iptoken'});
     }
+    if ($env{'form.ltoken'}) {
+        my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
+        &Apache::lonnet::tmpdel($env{'form.ltoken'});
+        delete($env{'form.ltoken'});
+        if ($info{'linkprot'}) {
+            if (!$tokenextras) {
+                $tokenextras = '&&&';
+            }
+            $tokenextras .= '&linkprot='.&escape($info{'linkprot'});
+        }
+    }
     my $logtoken=Apache::lonnet::reply(
        'tmpput:'.$ukey.$lkey.'&'.$firsturl.$tokenextras,
        $lonhost);
@@ -727,7 +782,7 @@
 }
 
 sub check_loginvia {
-    my ($domain,$lonhost,$lonidsdir,$balcookie) = @_;
+    my ($domain,$lonhost,$lonidsdir,$balcookie,$linkprot) = @_;
     if ($domain eq '' || $lonhost eq '' || $lonidsdir eq '') {
         return;
     }
@@ -787,7 +842,7 @@
                             }
                         }
                     }
-                    $output = &redirect_page($newhost,$path);
+                    $output = &redirect_page($newhost,$path,$linkprot);
                 }
             }
         }
@@ -796,7 +851,7 @@
 }
 
 sub redirect_page {
-    my ($desthost,$path) = @_;
+    my ($desthost,$path,$linkprot) = @_;
     my $protocol = $Apache::lonnet::protocol{$desthost};
     $protocol = 'http' if ($protocol ne 'https');
     unless ($path =~ m{^/}) {
@@ -806,6 +861,12 @@
     if ($env{'form.firsturl'} ne '') {
         $url .='?firsturl='.$env{'form.firsturl'};
     }
+    if ($linkprot) {
+        my $ltoken = &Apache::lonnet::tmpput({linkprot => $linkprot},$desthost);
+        if ($ltoken) {
+            $url .= (($url =~ /\?/) ? '&' : '?').'ltoken='.$ltoken;
+        }
+    }
     my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,
                                                     {'redirect' => [0,$url],});
     my $end_page   = &Apache::loncommon::end_page();
Index: loncom/auth/migrateuser.pm
diff -u loncom/auth/migrateuser.pm:1.41 loncom/auth/migrateuser.pm:1.42
--- loncom/auth/migrateuser.pm:1.41	Fri Dec  7 23:33:55 2018
+++ loncom/auth/migrateuser.pm	Wed Dec 26 20:10:21 2018
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Starts a user off based of an existing token.
 #
-# $Id: migrateuser.pm,v 1.41 2018/12/07 23:33:55 raeburn Exp $
+# $Id: migrateuser.pm,v 1.42 2018/12/26 20:10:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -672,6 +672,29 @@
 	if ($handle) {
 	    &Apache::lonnet::transfer_profile_to_env($r->dir_config('lonIDsDir'),
 						     $handle);
+            if ($data{'linkprot'} ne '') {
+                my ($linkprotector,$deeplink) = split(/:/,$data{'linkprot'},2);
+                if ($env{'user.linkprotector'}) {
+                    my @protectors = split(/,/,$env{'user.linkprotector'});
+                    unless (grep(/^\Q$linkprotector\E$/, at protectors)) {
+                        push(@protectors,$linkprotector);
+                        @protectors = sort { $a <=> $b } @protectors;
+                        &Apache::lonnet::appenv({'user.linkprotector' => join(',', at protectors)});
+                    }
+                } else {
+                    &Apache::lonnet::appenv({'user.linkprotector' => $linkprotector });
+                }   
+                if ($env{'user.linkproturi'}) {
+                    my @proturis = split(/,/,$env{'user.linkproturi'});
+                    unless(grep(/^\Q$deeplink\E$/, at proturis)) {
+                        push(@proturis,$deeplink);
+                        @proturis = sort @proturis;
+                        &Apache::lonnet::appenv({'user.linkproturi' => join(',', at proturis)});
+                    }
+                } else {
+                    &Apache::lonnet::appenv({'user.linkproturi' => $deeplink});
+                }
+            }
             if ($data{'lti.login'}) {
                 my $needslogout;
                 if ($env{'request.lti.login'}) {
@@ -765,6 +788,18 @@
                         $desturl .= (($desturl =~/\?/)?'&':'?').'navmap=1';
                     }
                 }
+                if ($data{'linkprot'}) {
+                    my ($linkprotector,$linkuri) = split(/:/,$data{'linkprot'},2);
+                    if ($linkprotector) {
+                        if (ref($extra_env) eq 'HASH') {
+                            $extra_env->{'user.linkprotector'} = $linkprotector;
+                            $extra_env->{'user.linkproturi'} = $linkuri;
+                        } else {
+                            $extra_env = {'user.linkprotector' => $linkprotector,
+                                          'user.linkproturi' => $linkuri,};
+                        }
+                    }
+                }
             }
             my $skipcritical;
             if (($data{'lti.login'}) && ($data{'lti.reqcrs'}) &&
Index: loncom/auth/switchserver.pm
diff -u loncom/auth/switchserver.pm:1.46 loncom/auth/switchserver.pm:1.47
--- loncom/auth/switchserver.pm:1.46	Sat Dec  8 15:16:03 2018
+++ loncom/auth/switchserver.pm	Wed Dec 26 20:10:21 2018
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Switch Servers Handler
 #
-# $Id: switchserver.pm,v 1.46 2018/12/08 15:16:03 raeburn Exp $
+# $Id: switchserver.pm,v 1.47 2018/12/26 20:10:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -280,6 +280,9 @@
     if ($env{'request.sso.reloginserver'}) {
         $info{'sso.reloginserver'} = $env{'request.sso.reloginserver'};
     }
+    if ($env{'request.linkprot'}) {
+        $info{'linkprot'} = $env{'request.linkprot'};
+    }
     if ($env{'request.lti.login'}) {
         $info{'lti.login'} = $env{'request.lti.login'};
     }
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.344 loncom/interface/domainprefs.pm:1.345
--- loncom/interface/domainprefs.pm:1.344	Sat Dec  8 15:03:25 2018
+++ loncom/interface/domainprefs.pm	Wed Dec 26 20:10:24 2018
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.344 2018/12/08 15:03:25 raeburn Exp $
+# $Id: domainprefs.pm,v 1.345 2018/12/26 20:10:24 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2836,7 +2836,31 @@
 // <![CDATA[
 
 function toggleLTI(form,setting,item) {
-    if ((setting == 'user') || (setting == 'crs') || (setting == 'passback')) {
+    if (setting == 'requser') {
+        var fieldsets = document.getElementsByClassName('ltioption_'+item);
+        if (fieldsets.length) {
+            var radioname = 'lti_'+setting+'_'+item;
+            var num = form.elements[radioname].length;
+            if (num) {
+                var setvis = '';
+                for (var i=0; i<num; i++) {
+                    if (form.elements[radioname][i].checked) {
+                        if (form.elements[radioname][i].value == '1') {
+                           setvis = 1;
+                           break;
+                        }
+                    }
+                }
+                for (var j=0; j<fieldsets.length; j++) { 
+                    if (setvis) {
+                        fieldsets[j].style.display = 'block';
+                    } else {
+                        fieldsets[j].style.display = 'none';
+                    }
+                }
+            }
+        }
+    } else if ((setting == 'user') || (setting == 'crs') || (setting == 'passback')) {
         var radioname = '';
         var divid = '';
         if (setting == 'user') {
@@ -4767,14 +4791,24 @@
         for (my $i=0; $i<@items; $i++) {
             $css_class = $itemcount%2?' class="LC_odd_row"':'';
             my $item = $ordered{$items[$i]};
-            my ($key,$secret,$lifetime,$consumer,$current);
+            my ($key,$secret,$lifetime,$consumer,$requser,$current);
             if (ref($settings->{$item}) eq 'HASH') {
                 $key = $settings->{$item}->{'key'};
                 $secret = $settings->{$item}->{'secret'};
                 $lifetime = $settings->{$item}->{'lifetime'};
                 $consumer = $settings->{$item}->{'consumer'};
+                $requser = $settings->{$item}->{'requser'};
                 $current = $settings->{$item};
             }
+            my $onclickrequser = ' onclick="toggleLTI(this.form,'."'requser','$i'".');"';
+            my %checkedrequser = (
+                                   yes => ' checked="checked"',
+                                   no  => '',
+                                 );
+            if (!$requser) {
+                $checkedrequser{'no'} = $checkedrequser{'yes'};
+                $checkedrequser{'yes'} = '';
+            } 
             my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'lti_pos_".$item."'".');"';
             $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                          .'<select name="lti_pos_'.$item.'"'.$chgstr.'>';
@@ -4792,13 +4826,17 @@
                 '<td colspan="2">'.
                 '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                 '<span class="LC_nobreak">'.$lt{'consumer'}.
-                ':<input type="text" size="20" name="lti_consumer_'.$i.'" value="'.$consumer.'" /></span> '.
+                ':<input type="text" size="15" name="lti_consumer_'.$i.'" value="'.$consumer.'" /></span> '.
                 (' 'x2).
                 '<span class="LC_nobreak">'.$lt{'version'}.':<select name="lti_version_'.$i.'">'.
                 '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
                 (' 'x2).
                 '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" name="lti_lifetime_'.$i.'"'.
-                'value="'.$lifetime.'" size="5" /></span>'.
+                'value="'.$lifetime.'" size="3" /></span>'.
+                (' 'x2).
+                 '<span class="LC_nobreak">'.$lt{'requser'}.':'.
+                 '<label><input type="radio" name="lti_requser_'.$i.'" value="1"'.$onclickrequser.$checkedrequser{yes}.' />'.&mt('Yes').'</label> '."\n".
+                 '<label><input type="radio" name="lti_requser_'.$i.'" value="0"'.$onclickrequser.$checkedrequser{no}.' />'.&mt('No').'</label></span>'."\n".
                 '<br /><br />'.
                 '<span class="LC_nobreak">'.$lt{'key'}.
                 ':<input type="text" size="25" name="lti_key_'.$i.'" value="'.$key.'" /></span> '.
@@ -4829,12 +4867,16 @@
                   '<td colspan="2">'.
                   '<fieldset><legend>'.&mt('Required settings').'</legend>'.
                   '<span class="LC_nobreak">'.$lt{'consumer'}.
-                  ':<input type="text" size="20" name="lti_consumer_add" value="" /></span> '."\n".
+                  ':<input type="text" size="15" name="lti_consumer_add" value="" /></span> '."\n".
                   (' 'x2).
                   '<span class="LC_nobreak">'.$lt{'version'}.':<select name="lti_version_add">'.
                   '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
                   (' 'x2).
-                  '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="lti_lifetime_add" value="300" /></span> '."\n".
+                  '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="3" name="lti_lifetime_add" value="300" /></span> '."\n".
+                  (' 'x2).
+                  '<span class="LC_nobreak">'.$lt{'requser'}.':'.
+                  '<label><input type="radio" name="lti_requser_add" value="1" onclick="toggleLTI(this.form,'."'requser','add'".');" checked="checked" />'.&mt('Yes').'</label> '."\n".
+                  '<label><input type="radio" name="lti_requser_add" value="0" onclick="toggleLTI(this.form,'."'requser','add'".');" />'.&mt('No').'</label></span>'."\n".
                   '<br /><br />'.
                   '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="lti_key_add" value="" /></span> '."\n".
                   (' 'x2).
@@ -4853,15 +4895,16 @@
                                           'url'       => 'URL',
                                           'key'       => 'Key',
                                           'lifetime'  => 'Nonce lifetime (s)',
-                                          'consumer'  => 'LTI Consumer', 
+                                          'consumer'  => 'Consumer',
                                           'secret'    => 'Secret',
+                                          'requser'   => "User's identity sent",
                                           'email'     => 'Email address',
                                           'sourcedid' => 'User ID',
                                           'other'     => 'Other',
                                           'passback'  => 'Can return grades to Consumer:',
                                           'roster'    => 'Can retrieve roster from Consumer:',
                                           'topmenu'   => 'Display LON-CAPA page header',
-                                          'inlinemenu'=> 'Display LON-CAPA inline menu', 
+                                          'inlinemenu'=> 'Display LON-CAPA inline menu',
                                         );
     return %lt;
 }
@@ -4887,6 +4930,7 @@
     my $crssecfieldsty = 'none';
     my $secsrcfieldsty = 'none';
     my $passbacksty = 'none';
+    my $optionsty = 'block';
     my $lcauthparm;
     my $lcauthparmstyle = 'display:none';
     my $lcauthparmtext;
@@ -4895,6 +4939,9 @@
     my %menutitles = &ltimenu_titles();
 
     if (ref($current) eq 'HASH') {
+        if (!$current->{'requser'}) {
+            $optionsty = 'none';
+        }
         if (($current->{'mapuser'} ne '') && ($current->{'mapuser'} ne 'lis_person_sourcedid')) {
             $checked{'mapuser'}{'sourcedid'} = '';
             if ($current->{'mapuser'} eq 'lis_person_contact_email_primary') {
@@ -4920,7 +4967,7 @@
                 $checked{'mapcrstype'}{$type} = ' checked="checked"';
             }
         }
-        if ($current->{'makecrs'}) { 
+        if ($current->{'makecrs'}) {
             $checked{'makecrs'}{'Y'} = '  checked="checked"';
         }
         if (ref($current->{'makeuser'}) eq 'ARRAY') {
@@ -5017,7 +5064,7 @@
     my $onclicksecsrc = ' onclick="toggleLTI(this.form,'."'secsrc','$num'".')"';
     my $onclicklcauth = ' onclick="toggleLTI(this.form,'."'lcauth','$num'".')"';
     my $onclickmenu = ' onclick="toggleLTI(this.form,'."'lcmenu','$num'".');"';
-    my $output = '<fieldset><legend>'.&mt('Mapping users').'</legend>'.
+    my $output = '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping users').'</legend>'.
                  '<div class="LC_floatleft"><span class="LC_nobreak">'.&mt('LON-CAPA username').': ';
     foreach my $option ('sourcedid','email','other') {
         $output .= '<label><input type="radio" name="lti_mapuser_'.$num.'" value="'.$option.'"'.
@@ -5028,7 +5075,7 @@
                '<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="lti_userfield_'.$num.'">'.
                '<input type="text" name="lti_customuser_'.$num.'" '.
                'value="'.$userfield.'" /></div></fieldset>'. 
-               '<fieldset><legend>'.&mt('Mapping course roles').'</legend><table><tr>';
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping course roles').'</legend><table><tr>';
     foreach my $ltirole (@lticourseroles) {
         my ($selected,$selectnone);
         if ($rolemaps{$ltirole} eq '') {
@@ -5052,13 +5099,13 @@
         $output .= '</select></td>';
     }
     $output .= '</tr></table></fieldset>'.
-               '<fieldset><legend>'.&mt('Roles which may create user accounts').'</legend>';
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Roles which may create user accounts').'</legend>';
     foreach my $ltirole (@ltiroles) {
         $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="lti_makeuser_'.$num.'" value="'.$ltirole.'"'.
                    $checked{'makeuser'}{$ltirole}.' />'.$ltirole.'</label> </span> ';     
     }
     $output .= '</fieldset>'.
-               '<fieldset><legend>'.&mt('New user accounts created for LTI users').'</legend>'.
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('New user accounts created for LTI users').'</legend>'.
                '<table>'.
                &modifiable_userdata_row('lti','instdata_'.$num,$current,$numinrow,$itemcount).
                '</table>'.
@@ -5081,7 +5128,7 @@
                '<span id="lti_lcauth_parmtext_'.$num.'">'.$lcauthparmtext.'</span>'.
                '<input type="text" name="lti_lcauthparm_'.$num.'" value="" /></span></td></tr>'.
                '</table></fieldset>'.
-               '<fieldset><legend>'.&mt('Mapping courses').'</legend>'.
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Mapping courses').'</legend>'.
                '<div class="LC_floatleft"><span class="LC_nobreak">'.
                &mt('Unique course identifier').': ';
     foreach my $option ('course_offering_sourcedid','context_id','other') {
@@ -5099,20 +5146,20 @@
                    (' 'x2);
     }
     $output .= '</span></fieldset>'.
-               '<fieldset><legend>'.&mt('Creating courses').'</legend>'.
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Creating courses').'</legend>'.
                '<span class="LC_nobreak">'.&mt('Course created (if absent) on Instructor access').': '.
                '<label><input type="radio" name="lti_makecrs_'.$num.'" value="0"'.
                $checked{'makecrs'}{'N'}.' />'.&mt('No').'</label>'.(' 'x2).
                '<label><input type="radio" name="lti_makecrs_'.$num.'" value="1"'.
                $checked{'makecrs'}{'Y'}.' />'.&mt('Yes').'</label></span>'.
                '</fieldset>'.
-               '<fieldset><legend>'.&mt('Roles which may self-enroll').'</legend>';
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Roles which may self-enroll').'</legend>';
     foreach my $lticrsrole (@lticourseroles) {
         $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="lti_selfenroll_'.$num.'" value="'.$lticrsrole.'"'.
                    $checked{'selfenroll'}{$lticrsrole}.' />'.$lticrsrole.'</label> </span> ';
     }
     $output .= '</fieldset>'.
-               '<fieldset><legend>'.&mt('Course options').'</legend>'.
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Course options').'</legend>'.
                '<div class="LC_floatleft"><span class="LC_nobreak">'.&mt('Assign users to sections').': '.
                '<label><input type="radio" name="lti_crssec_'.$num.'" value="0"'.
                $checked{'crssec'}{'N'}.$onclicksec.' />'.&mt('No').'</label>'.(' 'x2).
@@ -5164,7 +5211,7 @@
                &mt('Outcomes Service (1.1)').'</label>'.(' 'x2).
                '<label><input type="radio" name="lti_passbackformat_'.$num.'" value="1.0"'.$pb1p0chk.'/>'.
                &mt('Outcomes Extension (1.0)').'</label></span></div></fieldset>'.
-               '<fieldset><legend>'.&mt('Course defaults (Course Coordinator can override)').'</legend>'.
+               '<fieldset class="ltioption_'.$num.'" style="display:'.$optionsty.'"><legend>'.&mt('Course defaults (Course Coordinator can override)').'</legend>'.
                '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{'topmenu'}.': '.
                '<label><input type="radio" name="lti_topmenu_'.$num.'" value="0"'.
                $checked{'topmenu'}{'N'}.$onclickmenu.' />'.&mt('No').'</label>'.(' 'x2).
@@ -11776,7 +11823,7 @@
         if ($position ne '') {
             $allpos[$position] = $itemid;
         }
-        foreach my $item ('consumer','key','secret','lifetime') {
+        foreach my $item ('consumer','key','secret','lifetime','requser') {
             my $formitem = 'form.lti_'.$item.'_'.$idx;
             $env{$formitem} =~ s/(`)/'/g;
             if ($item eq 'lifetime') {
@@ -11798,177 +11845,179 @@
         if ($env{'form.lti_version_'.$idx} eq 'LTI-1p0') {
             $confhash{$itemid}{'version'} = $env{'form.lti_version_'.$idx};
         }
-        if ($env{'form.lti_mapuser_'.$idx} eq 'sourcedid') {
-            $confhash{$itemid}{'mapuser'} = 'lis_person_sourcedid'; 
-        } elsif ($env{'form.lti_mapuser_'.$idx} eq 'email') {
-            $confhash{$itemid}{'mapuser'} = 'lis_person_contact_email_primary';
-        } elsif ($env{'form.lti_mapuser_'.$idx} eq 'other') {
-            my $mapuser = $env{'form.lti_customuser_'.$idx};
-            $mapuser =~ s/(`)/'/g;
-            $mapuser =~ s/^\s+|\s+$//g; 
-            $confhash{$itemid}{'mapuser'} = $mapuser; 
-        }
-        foreach my $ltirole (@lticourseroles) {
-            my $possrole = $env{'form.lti_maprole_'.$ltirole.'_'.$idx};
-            if (grep(/^\Q$possrole\E$/, at courseroles)) {
-                $confhash{$itemid}{'maproles'}{$ltirole} = $possrole;
-            }
-        }
-        my @possmakeuser = &Apache::loncommon::get_env_multiple('form.lti_makeuser_'.$idx);
-        my @makeuser;
-        foreach my $ltirole (sort(@possmakeuser)) {
-            if ($posslti{$ltirole}) {
-                push(@makeuser,$ltirole);
-            }
-        }
-        $confhash{$itemid}{'makeuser'} = \@makeuser;
-        if (@makeuser) {
-            my $lcauth = $env{'form.lti_lcauth_'.$idx};
-            if ($lcauth =~ /^(internal|krb4|krb5|localauth)$/) {
-                $confhash{$itemid}{'lcauth'} = $lcauth;
-                if ($lcauth ne 'internal') {
-                    my $lcauthparm = $env{'form.lti_lcauthparm_'.$idx};
-                    $lcauthparm =~ s/^(\s+|\s+)$//g;
-                    $lcauthparm =~ s/`//g;
-                    if ($lcauthparm ne '') {
-                        $confhash{$itemid}{'lcauthparm'} = $lcauthparm;
+        if ($confhash{$itemid}{'requser'}) {
+            if ($env{'form.lti_mapuser_'.$idx} eq 'sourcedid') {
+                $confhash{$itemid}{'mapuser'} = 'lis_person_sourcedid'; 
+            } elsif ($env{'form.lti_mapuser_'.$idx} eq 'email') {
+                $confhash{$itemid}{'mapuser'} = 'lis_person_contact_email_primary';
+            } elsif ($env{'form.lti_mapuser_'.$idx} eq 'other') {
+                my $mapuser = $env{'form.lti_customuser_'.$idx};
+                $mapuser =~ s/(`)/'/g;
+                $mapuser =~ s/^\s+|\s+$//g; 
+                $confhash{$itemid}{'mapuser'} = $mapuser; 
+            }
+            foreach my $ltirole (@lticourseroles) {
+                my $possrole = $env{'form.lti_maprole_'.$ltirole.'_'.$idx};
+                if (grep(/^\Q$possrole\E$/, at courseroles)) {
+                    $confhash{$itemid}{'maproles'}{$ltirole} = $possrole;
+                }
+            }
+            my @possmakeuser = &Apache::loncommon::get_env_multiple('form.lti_makeuser_'.$idx);
+            my @makeuser;
+            foreach my $ltirole (sort(@possmakeuser)) {
+                if ($posslti{$ltirole}) {
+                    push(@makeuser,$ltirole);
+                }
+            }
+            $confhash{$itemid}{'makeuser'} = \@makeuser;
+            if (@makeuser) {
+                my $lcauth = $env{'form.lti_lcauth_'.$idx};
+                if ($lcauth =~ /^(internal|krb4|krb5|localauth)$/) {
+                    $confhash{$itemid}{'lcauth'} = $lcauth;
+                    if ($lcauth ne 'internal') {
+                        my $lcauthparm = $env{'form.lti_lcauthparm_'.$idx};
+                        $lcauthparm =~ s/^(\s+|\s+)$//g;
+                        $lcauthparm =~ s/`//g;
+                        if ($lcauthparm ne '') {
+                            $confhash{$itemid}{'lcauthparm'} = $lcauthparm;
+                        }
                     }
+                } else {
+                    $confhash{$itemid}{'lcauth'} = 'lti';
                 }
-            } else {
-                $confhash{$itemid}{'lcauth'} = 'lti';
             }
-        }
-        my @possinstdata =  &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
-        if (@possinstdata) {
-            foreach my $field (@possinstdata) {
-                if (exists($fieldtitles{$field})) {
-                    push(@{$confhash{$itemid}{'instdata'}});
+            my @possinstdata =  &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
+            if (@possinstdata) {
+                foreach my $field (@possinstdata) {
+                    if (exists($fieldtitles{$field})) {
+                        push(@{$confhash{$itemid}{'instdata'}});
+                    }
                 }
             }
-        }
-        if (($env{'form.lti_mapcrs_'.$idx} eq 'course_offering_sourcedid') ||
-            ($env{'form.lti_mapcrs_'.$idx} eq 'context_id'))  {
-            $confhash{$itemid}{'mapcrs'} = $env{'form.lti_mapcrs_'.$idx};
-        } elsif ($env{'form.lti_mapcrs_'.$idx} eq 'other') {
-            my $mapcrs = $env{'form.lti_mapcrsfield_'.$idx}; 
-            $mapcrs =~ s/(`)/'/g;
-            $mapcrs =~ s/^\s+|\s+$//g;
-            $confhash{$itemid}{'mapcrs'} = $mapcrs;
-        }
-        my @posstypes = &Apache::loncommon::get_env_multiple('form.lti_mapcrstype_'.$idx);
-        my @crstypes;
-        foreach my $type (sort(@posstypes)) {
-            if ($posscrstype{$type}) {
-                push(@crstypes,$type);
-            }
-        }
-        $confhash{$itemid}{'mapcrstype'} = \@crstypes;
-        if ($env{'form.lti_makecrs_'.$idx}) {
-            $confhash{$itemid}{'makecrs'} = 1;
-        }
-        my @possenroll = &Apache::loncommon::get_env_multiple('form.lti_selfenroll_'.$idx);
-        my @selfenroll;
-        foreach my $type (sort(@possenroll)) {
-            if ($posslticrs{$type}) {
-                push(@selfenroll,$type);
+            if (($env{'form.lti_mapcrs_'.$idx} eq 'course_offering_sourcedid') ||
+                ($env{'form.lti_mapcrs_'.$idx} eq 'context_id'))  {
+                $confhash{$itemid}{'mapcrs'} = $env{'form.lti_mapcrs_'.$idx};
+            } elsif ($env{'form.lti_mapcrs_'.$idx} eq 'other') {
+                my $mapcrs = $env{'form.lti_mapcrsfield_'.$idx}; 
+                $mapcrs =~ s/(`)/'/g;
+                $mapcrs =~ s/^\s+|\s+$//g;
+                $confhash{$itemid}{'mapcrs'} = $mapcrs;
             }
-        }
-        $confhash{$itemid}{'selfenroll'} = \@selfenroll;
-        if ($env{'form.lti_crssec_'.$idx}) {
-            if ($env{'form.lti_crssecsrc_'.$idx} eq 'course_section_sourcedid') {
-                $confhash{$itemid}{'section'} = $env{'form.lti_crssecsrc_'.$idx};
-            } elsif ($env{'form.lti_crssecsrc_'.$idx} eq 'other') {
-                my $section = $env{'form.lti_customsection_'.$idx};
-                $section =~ s/(`)/'/g;
-                $section =~ s/^\s+|\s+$//g;
-                if ($section ne '') {
-                    $confhash{$itemid}{'section'} = $section;
+            my @posstypes = &Apache::loncommon::get_env_multiple('form.lti_mapcrstype_'.$idx);
+            my @crstypes;
+            foreach my $type (sort(@posstypes)) {
+                if ($posscrstype{$type}) {
+                    push(@crstypes,$type);
                 }
             }
-        }
-        foreach my $field ('passback','roster','topmenu','inlinemenu') {
-            if ($env{'form.lti_'.$field.'_'.$idx}) {
-                $confhash{$itemid}{$field} = 1;
+            $confhash{$itemid}{'mapcrstype'} = \@crstypes;
+            if ($env{'form.lti_makecrs_'.$idx}) {
+                $confhash{$itemid}{'makecrs'} = 1;
             }
-        }
-        if ($env{'form.lti_passback_'.$idx}) {
-            if ($env{'form.lti_passbackformat_'.$idx} eq '1.0') {
-                $confhash{$itemid}{'passbackformat'} = '1.0';
-            } else {
-                $confhash{$itemid}{'passbackformat'} = '1.1';
+            my @possenroll = &Apache::loncommon::get_env_multiple('form.lti_selfenroll_'.$idx);
+            my @selfenroll;
+            foreach my $type (sort(@possenroll)) {
+                if ($posslticrs{$type}) {
+                    push(@selfenroll,$type);
+                }
             }
-        }
-        if ($env{'form.lti_topmenu_'.$idx} || $env{'form.lti_inlinemenu_'.$idx}) {
-            $confhash{$itemid}{lcmenu} = [];
-            my @possmenu = &Apache::loncommon::get_env_multiple('form.lti_menuitem_'.$idx);
-            foreach my $field (@possmenu) {
-                if (exists($menutitles{$field})) {
-                    if ($field eq 'grades') {
-                        next unless ($env{'form.lti_inlinemenu_'.$idx});
+            $confhash{$itemid}{'selfenroll'} = \@selfenroll;
+            if ($env{'form.lti_crssec_'.$idx}) {
+                if ($env{'form.lti_crssecsrc_'.$idx} eq 'course_section_sourcedid') {
+                    $confhash{$itemid}{'section'} = $env{'form.lti_crssecsrc_'.$idx};
+                } elsif ($env{'form.lti_crssecsrc_'.$idx} eq 'other') {
+                    my $section = $env{'form.lti_customsection_'.$idx};
+                    $section =~ s/(`)/'/g;
+                    $section =~ s/^\s+|\s+$//g;
+                    if ($section ne '') {
+                        $confhash{$itemid}{'section'} = $section;
                     }
-                    push(@{$confhash{$itemid}{lcmenu}},$field);
                 }
             }
-        }
-        unless (($idx eq 'add') || ($changes{$itemid})) {
-            foreach my $field ('mapuser','mapcrs','makecrs','section','passback','roster','lcauth','lcauthparm','topmenu','inlinemenu') {
-                if ($domconfig{$action}{$itemid}{$field} ne $confhash{$itemid}{$field}) {
-                    $changes{$itemid} = 1;
+            foreach my $field ('passback','roster','topmenu','inlinemenu') {
+                if ($env{'form.lti_'.$field.'_'.$idx}) {
+                    $confhash{$itemid}{$field} = 1;
                 }
             }
-            unless ($changes{$itemid}) {
-                if ($domconfig{$action}{$itemid}{'passback'} eq $confhash{$itemid}{'passback'}) {
-                    if ($domconfig{$action}{$itemid}{'passbackformat'} ne $confhash{$itemid}{'passbackformat'}) {
-                        $changes{$itemid} = 1;
+            if ($env{'form.lti_passback_'.$idx}) {
+                if ($env{'form.lti_passbackformat_'.$idx} eq '1.0') {
+                    $confhash{$itemid}{'passbackformat'} = '1.0';
+                } else {
+                    $confhash{$itemid}{'passbackformat'} = '1.1';
+                }
+            }
+            if ($env{'form.lti_topmenu_'.$idx} || $env{'form.lti_inlinemenu_'.$idx}) {
+                $confhash{$itemid}{lcmenu} = [];
+                my @possmenu = &Apache::loncommon::get_env_multiple('form.lti_menuitem_'.$idx);
+                foreach my $field (@possmenu) {
+                    if (exists($menutitles{$field})) {
+                        if ($field eq 'grades') {
+                            next unless ($env{'form.lti_inlinemenu_'.$idx});
+                        }
+                        push(@{$confhash{$itemid}{lcmenu}},$field);
                     }
                 }
             }
-            foreach my $field ('makeuser','mapcrstype','selfenroll','instdata','lcmenu') {
+            unless (($idx eq 'add') || ($changes{$itemid})) {
+                foreach my $field ('mapuser','mapcrs','makecrs','section','passback','roster','lcauth','lcauthparm','topmenu','inlinemenu') {
+                    if ($domconfig{$action}{$itemid}{$field} ne $confhash{$itemid}{$field}) {
+                        $changes{$itemid} = 1;
+                    }
+                }
                 unless ($changes{$itemid}) {
-                    if (ref($domconfig{$action}{$itemid}{$field}) eq 'ARRAY') {
-                        if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
-                            my @diffs = &Apache::loncommon::compare_arrays($domconfig{$action}{$itemid}{$field},
-                                                                           $confhash{$itemid}{$field});
-                            if (@diffs) {
-                                $changes{$itemid} = 1;
-                            }
-                        } elsif (@{$domconfig{$action}{$itemid}{$field}} > 0) {
+                    if ($domconfig{$action}{$itemid}{'passback'} eq $confhash{$itemid}{'passback'}) {
+                        if ($domconfig{$action}{$itemid}{'passbackformat'} ne $confhash{$itemid}{'passbackformat'}) {
                             $changes{$itemid} = 1;
                         }
-                    } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
-                        if (@{$confhash{$itemid}{$field}} > 0) {
-                            $changes{$itemid} = 1;
-                        }
-                    } 
+                    }
                 }
-            }
-            unless ($changes{$itemid}) {
-                if (ref($domconfig{$action}{$itemid}{'maproles'}) eq 'HASH') {
-                    if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
-                        foreach my $ltirole (keys(%{$domconfig{$action}{$itemid}{'maproles'}})) {
-                            if ($domconfig{$action}{$itemid}{'maproles'}{$ltirole} ne 
-                                $confhash{$itemid}{'maproles'}{$ltirole}) {
+                foreach my $field ('makeuser','mapcrstype','selfenroll','instdata','lcmenu') {
+                    unless ($changes{$itemid}) {
+                        if (ref($domconfig{$action}{$itemid}{$field}) eq 'ARRAY') {
+                            if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+                                my @diffs = &Apache::loncommon::compare_arrays($domconfig{$action}{$itemid}{$field},
+                                                                               $confhash{$itemid}{$field});
+                                if (@diffs) {
+                                    $changes{$itemid} = 1;
+                                }
+                            } elsif (@{$domconfig{$action}{$itemid}{$field}} > 0) {
+                                $changes{$itemid} = 1;
+                            }
+                        } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
+                            if (@{$confhash{$itemid}{$field}} > 0) {
                                 $changes{$itemid} = 1;
-                                last;
                             }
                         }
-                        unless ($changes{$itemid}) {
-                            foreach my $ltirole (keys(%{$confhash{$itemid}{'maproles'}})) {
-                                if ($confhash{$itemid}{'maproles'}{$ltirole} ne 
-                                    $domconfig{$action}{$itemid}{'maproles'}{$ltirole}) {
+                    }
+                }
+                unless ($changes{$itemid}) {
+                    if (ref($domconfig{$action}{$itemid}{'maproles'}) eq 'HASH') {
+                        if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+                            foreach my $ltirole (keys(%{$domconfig{$action}{$itemid}{'maproles'}})) {
+                                if ($domconfig{$action}{$itemid}{'maproles'}{$ltirole} ne 
+                                    $confhash{$itemid}{'maproles'}{$ltirole}) {
                                     $changes{$itemid} = 1;
                                     last;
                                 }
                             }
-                        }
-                    } elsif (keys(%{$domconfig{$action}{$itemid}{'maproles'}}) > 0) {
-                        $changes{$itemid} = 1;
-                    }
-                } elsif (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
-                    unless ($changes{$itemid}) {
-                        if (keys(%{$confhash{$itemid}{'maproles'}}) > 0) {
+                            unless ($changes{$itemid}) {
+                                foreach my $ltirole (keys(%{$confhash{$itemid}{'maproles'}})) {
+                                    if ($confhash{$itemid}{'maproles'}{$ltirole} ne 
+                                        $domconfig{$action}{$itemid}{'maproles'}{$ltirole}) {
+                                        $changes{$itemid} = 1;
+                                        last;
+                                    }
+                                }
+                            }
+                        } elsif (keys(%{$domconfig{$action}{$itemid}{'maproles'}}) > 0) {
                             $changes{$itemid} = 1;
                         }
+                    } elsif (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+                        unless ($changes{$itemid}) {
+                            if (keys(%{$confhash{$itemid}{'maproles'}}) > 0) {
+                                $changes{$itemid} = 1;
+                            }
+                        }
                     }
                 }
             }
@@ -12041,122 +12090,124 @@
                         my $num = length($encconfig{$itemid}{'secret'});
                         $resulttext .= ('*'x$num).'</li>';
                     }
-                    if ($confhash{$itemid}{'mapuser'}) {
-                        my $shownmapuser;
-                        if ($confhash{$itemid}{'mapuser'} eq 'lis_person_sourcedid') {
-                            $shownmapuser = $lt{'sourcedid'}.' (lis_person_sourcedid)';
-                        } elsif ($confhash{$itemid}{'mapuser'} eq 'lis_person_contact_email_primary') {
-                            $shownmapuser = $lt{'email'}.' (lis_person_contact_email_primary)';
-                        } else {
-                            $shownmapuser = &mt('Other').' ('.$confhash{$itemid}{'mapuser'}.')';
-                        } 
-                        $resulttext .= '<li>'.&mt('LON-CAPA username').': '.$shownmapuser.'</li>';
-                    }
-                    if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
-                        my $rolemaps;
-                        foreach my $role (@ltiroles) {
-                            if ($confhash{$itemid}{'maproles'}{$role}) {
-                                $rolemaps .= (' 'x2).$role.'='.
-                                             &Apache::lonnet::plaintext($confhash{$itemid}{'maproles'}{$role},
-                                                                        'Course').',';
+                    if ($confhash{$itemid}{'requser'}) {
+                        if ($confhash{$itemid}{'mapuser'}) {
+                            my $shownmapuser;
+                            if ($confhash{$itemid}{'mapuser'} eq 'lis_person_sourcedid') {
+                                $shownmapuser = $lt{'sourcedid'}.' (lis_person_sourcedid)';
+                            } elsif ($confhash{$itemid}{'mapuser'} eq 'lis_person_contact_email_primary') {
+                                $shownmapuser = $lt{'email'}.' (lis_person_contact_email_primary)';
+                            } else {
+                                $shownmapuser = &mt('Other').' ('.$confhash{$itemid}{'mapuser'}.')';
                             }
+                            $resulttext .= '<li>'.&mt('LON-CAPA username').': '.$shownmapuser.'</li>';
                         }
-                        if ($rolemaps) {
-                            $rolemaps =~ s/,$//;
-                            $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
-                        }
-                    }
-                    if (ref($confhash{$itemid}{'makeuser'}) eq 'ARRAY') {
-                        if (@{$confhash{$itemid}{'makeuser'}} > 0) { 
-                            $resulttext .= '<li>'.&mt('Following roles may create user accounts: [_1]',
-                                                      join(', ',@{$confhash{$itemid}{'makeuser'}})).'<br />';
-                            if ($confhash{$itemid}{'lcauth'} eq 'lti') {
-                                $resulttext .= &mt('New users will only be able to authenticate via LTI').'</li>';
-                            } else {
-                                $resulttext .= &mt('New users will be assigned LON-CAPA authentication: [_1]',
-                                                   $confhash{$itemid}{'lcauth'});
-                                if ($confhash{$itemid}{'lcauth'} eq 'internal') {
-                                    $resulttext .= '; '.&mt('a randomly generated password will be created');
-                                } elsif ($confhash{$itemid}{'lcauth'} eq 'localauth') {
-                                    if ($confhash{$itemid}{'lcauthparm'} ne '') {
-                                        $resulttext .= ' '.&mt('with argument: [_1]',$confhash{$itemid}{'lcauthparm'});
-                                    }
+                        if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
+                            my $rolemaps;
+                            foreach my $role (@ltiroles) {
+                                if ($confhash{$itemid}{'maproles'}{$role}) {
+                                    $rolemaps .= (' 'x2).$role.'='.
+                                                 &Apache::lonnet::plaintext($confhash{$itemid}{'maproles'}{$role},
+                                                                            'Course').',';
+                                }
+                            }
+                            if ($rolemaps) {
+                                $rolemaps =~ s/,$//;
+                                $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
+                            }
+                        }
+                        if (ref($confhash{$itemid}{'makeuser'}) eq 'ARRAY') {
+                            if (@{$confhash{$itemid}{'makeuser'}} > 0) { 
+                                $resulttext .= '<li>'.&mt('Following roles may create user accounts: [_1]',
+                                                          join(', ',@{$confhash{$itemid}{'makeuser'}})).'<br />';
+                                if ($confhash{$itemid}{'lcauth'} eq 'lti') {
+                                    $resulttext .= &mt('New users will only be able to authenticate via LTI').'</li>';
                                 } else {
-                                    $resulttext .= '; '.&mt('Kerberos domain: [_1]',$confhash{$itemid}{'lcauthparm'});
+                                    $resulttext .= &mt('New users will be assigned LON-CAPA authentication: [_1]',
+                                                       $confhash{$itemid}{'lcauth'});
+                                    if ($confhash{$itemid}{'lcauth'} eq 'internal') {
+                                        $resulttext .= '; '.&mt('a randomly generated password will be created');
+                                    } elsif ($confhash{$itemid}{'lcauth'} eq 'localauth') {
+                                        if ($confhash{$itemid}{'lcauthparm'} ne '') {
+                                            $resulttext .= ' '.&mt('with argument: [_1]',$confhash{$itemid}{'lcauthparm'});
+                                        }
+                                    } else {
+                                        $resulttext .= '; '.&mt('Kerberos domain: [_1]',$confhash{$itemid}{'lcauthparm'});
+                                    }
                                 }
+                                $resulttext .= '</li>';
+                            } else {
+                                $resulttext .= '<li>'.&mt('User account creation not permitted.').'</li>';
                             }
-                            $resulttext .= '</li>';
-                        } else {
-                            $resulttext .= '<li>'.&mt('User account creation not permitted.').'</li>';
                         }
-                    }
-                    if (ref($confhash{$itemid}{'instdata'}) eq 'ARRAY') {
-                        if (@{$confhash{$itemid}{'instdata'}} > 0) {
-                            $resulttext .= '<li>'.&mt('Institutional data will be used when creating a new user for: [_1]',
-                                                      join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'</li>';
-                        } else {
-                            $resulttext .= '<li>'.&mt('No institutional data used when creating a new user.').'</li>';
+                        if (ref($confhash{$itemid}{'instdata'}) eq 'ARRAY') {
+                            if (@{$confhash{$itemid}{'instdata'}} > 0) {
+                                $resulttext .= '<li>'.&mt('Institutional data will be used when creating a new user for: [_1]',
+                                                          join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'</li>';
+                            } else {
+                                $resulttext .= '<li>'.&mt('No institutional data used when creating a new user.').'</li>';
+                            }
                         }
-                    }
-                    if ($confhash{$itemid}{'mapcrs'}) {
-                        $resulttext .= '<li>'.&mt('Unique course identifier').': '.$confhash{$itemid}{'mapcrs'}.'</li>';
-                    }
-                    if (ref($confhash{$itemid}{'mapcrstype'}) eq 'ARRAY') {
-                        if (@{$confhash{$itemid}{'mapcrstype'}} > 0) {
-                            $resulttext .= '<li>'.&mt('Mapping for the following LON-CAPA course types: [_1]',
-                                           join(', ',map { $coursetypetitles{$_}; } @coursetypes)).
-                                           '</li>';
-                        } else {
-                            $resulttext .= '<li>'.&mt('No mapping to LON-CAPA courses').'</li>';
+                        if ($confhash{$itemid}{'mapcrs'}) {
+                            $resulttext .= '<li>'.&mt('Unique course identifier').': '.$confhash{$itemid}{'mapcrs'}.'</li>';
                         }
-                    }
-                    if ($confhash{$itemid}{'makecrs'}) {
-                        $resulttext .= '<li>'.&mt('Instructor may create course (if absent).').'</li>';
-                    } else {
-                        $resulttext .= '<li>'.&mt('Instructor may not create course (if absent).').'</li>';
-                    }
-                    if (ref($confhash{$itemid}{'selfenroll'}) eq 'ARRAY') {
-                        if (@{$confhash{$itemid}{'selfenroll'}} > 0) {
-                            $resulttext .= '<li>'.&mt('Self-enrollment for following roles: [_1]',
-                                                      join(', ',@{$confhash{$itemid}{'selfenroll'}})).
-                                           '</li>';
+                        if (ref($confhash{$itemid}{'mapcrstype'}) eq 'ARRAY') {
+                            if (@{$confhash{$itemid}{'mapcrstype'}} > 0) {
+                                $resulttext .= '<li>'.&mt('Mapping for the following LON-CAPA course types: [_1]',
+                                               join(', ',map { $coursetypetitles{$_}; } @coursetypes)).
+                                               '</li>';
+                            } else {
+                                $resulttext .= '<li>'.&mt('No mapping to LON-CAPA courses').'</li>';
+                            }
+                        }
+                        if ($confhash{$itemid}{'makecrs'}) {
+                            $resulttext .= '<li>'.&mt('Instructor may create course (if absent).').'</li>';
                         } else {
-                            $resulttext .= '<li>'.&mt('Self-enrollment not permitted').'</li>';
+                            $resulttext .= '<li>'.&mt('Instructor may not create course (if absent).').'</li>';
                         }
-                    }
-                    if ($confhash{$itemid}{'section'}) {
-                        if ($confhash{$itemid}{'section'} eq 'course_section_sourcedid') {
-                            $resulttext .= '<li>'.&mt('User section from standard field:').
-                                                 ' (course_section_sourcedid)'.'</li>';  
+                        if (ref($confhash{$itemid}{'selfenroll'}) eq 'ARRAY') {
+                            if (@{$confhash{$itemid}{'selfenroll'}} > 0) {
+                                $resulttext .= '<li>'.&mt('Self-enrollment for following roles: [_1]',
+                                                          join(', ',@{$confhash{$itemid}{'selfenroll'}})).
+                                               '</li>';
+                            } else {
+                                $resulttext .= '<li>'.&mt('Self-enrollment not permitted').'</li>';
+                            }
+                        }
+                        if ($confhash{$itemid}{'section'}) {
+                            if ($confhash{$itemid}{'section'} eq 'course_section_sourcedid') {
+                                $resulttext .= '<li>'.&mt('User section from standard field:').
+                                                     ' (course_section_sourcedid)'.'</li>';  
+                            } else {
+                                $resulttext .= '<li>'.&mt('User section from:').' '.
+                                                      $confhash{$itemid}{'section'}.'</li>';
+                            }
                         } else {
-                            $resulttext .= '<li>'.&mt('User section from:').' '.
-                                                  $confhash{$itemid}{'section'}.'</li>';
+                            $resulttext .= '<li>'.&mt('No section assignment').'</li>';
                         }
-                    } else {
-                        $resulttext .= '<li>'.&mt('No section assignment').'</li>';
-                    }
-                    foreach my $item ('passback','roster','topmenu','inlinemenu') {
-                        $resulttext .= '<li>'.$lt{$item}.': ';
-                        if ($confhash{$itemid}{$item}) {
-                            $resulttext .= &mt('Yes');
-                            if ($item eq 'passback') {
-                                if ($confhash{$itemid}{'passbackformat'} eq '1.0') {
-                                    $resulttext .= ' ('.&mt('Outcomes Extension (1.0)').')';
-                                } elsif ($confhash{$itemid}{'passbackformat'} eq '1.1') {
-                                    $resulttext .= ' ('.&mt('Outcomes Service (1.1)').')';
+                        foreach my $item ('passback','roster','topmenu','inlinemenu') {
+                            $resulttext .= '<li>'.$lt{$item}.': ';
+                            if ($confhash{$itemid}{$item}) {
+                                $resulttext .= &mt('Yes');
+                                if ($item eq 'passback') {
+                                    if ($confhash{$itemid}{'passbackformat'} eq '1.0') {
+                                        $resulttext .= ' ('.&mt('Outcomes Extension (1.0)').')';
+                                    } elsif ($confhash{$itemid}{'passbackformat'} eq '1.1') {
+                                        $resulttext .= ' ('.&mt('Outcomes Service (1.1)').')';
+                                    }
                                 }
+                            } else {
+                                $resulttext .= &mt('No');
                             }
-                        } else {
-                            $resulttext .= &mt('No');
+                            $resulttext .= '</li>';
                         }
-                        $resulttext .= '</li>';
-                    }
-                    if (ref($confhash{$itemid}{'lcmenu'}) eq 'ARRAY') {
-                        if (@{$confhash{$itemid}{'lcmenu'}} > 0) {
-                            $resulttext .= '<li>'.&mt('Menu items:').' '.
-                                           join(', ', map { $menutitles{$_}; } (@{$confhash{$itemid}{'lcmenu'}})).'</li>'; 
-                        } else {
-                            $resulttext .= '<li>'.&mt('No menu items displayed in header or online menu').'</li>'; 
+                        if (ref($confhash{$itemid}{'lcmenu'}) eq 'ARRAY') {
+                            if (@{$confhash{$itemid}{'lcmenu'}} > 0) {
+                                $resulttext .= '<li>'.&mt('Menu items:').' '.
+                                               join(', ', map { $menutitles{$_}; } (@{$confhash{$itemid}{'lcmenu'}})).'</li>'; 
+                            } else {
+                                $resulttext .= '<li>'.&mt('No menu items displayed in header or online menu').'</li>'; 
+                            }
                         }
                     }
                     $resulttext .= '</ul></li>';
Index: loncom/lti/ltiauth.pm
diff -u loncom/lti/ltiauth.pm:1.16 loncom/lti/ltiauth.pm:1.17
--- loncom/lti/ltiauth.pm:1.16	Tue Aug 14 21:03:39 2018
+++ loncom/lti/ltiauth.pm	Wed Dec 26 20:10:29 2018
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Basic LTI Authentication Module
 #
-# $Id: ltiauth.pm,v 1.16 2018/08/14 21:03:39 raeburn Exp $
+# $Id: ltiauth.pm,v 1.17 2018/12/26 20:10:29 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -339,6 +339,30 @@
     }
 
 #
+# Determine if a username is required from the domain
+# configuration for the specific LTI Consumer
+#
+
+    if (!$lti{$itemid}{'requser'}) {
+        if ($tail =~ m{^/tiny/($match_domain)/(\w+)$}) {
+            foreach my $key (%{$params}) {
+                delete($env{'form.'.$key});
+            }
+            my $ltoken = &Apache::lonnet::tmpput({'linkprot' => $itemid.':'.$tail},
+                                                   $lonhost);
+            if ($ltoken) {
+                $r->internal_redirect($tail.'?ltoken='.$ltoken);
+                $r->set_handlers('PerlHandler'=> undef);
+            } else {
+                &invalid_request($r,9);    
+            }
+        } else {
+            &invalid_request($r,10);
+        }
+        return OK;
+    }
+
+#
 # Determine if source of username matches requirement from the 
 # domain configuration for the specific LTI Consumer.
 # 
@@ -394,7 +418,7 @@
             if ($consumers{$sourcecrs} =~ /^$match_courseid$/) {
                 my $crshome = &Apache::lonnet::homeserver($consumers{$sourcecrs},$cdom);
                 if ($crshome =~ /(con_lost|no_host|no_such_host)/) {
-                    &invalid_request($r,9);
+                    &invalid_request($r,11);
                     return OK;
                 } else {
                     $posscnum = $consumers{$sourcecrs};
@@ -406,7 +430,7 @@
     if ($urlcnum ne '') {
         if ($posscnum ne '') {
             if ($posscnum ne $urlcnum) {
-                &invalid_request($r,10);
+                &invalid_request($r,12);
                 return OK;
             } else {
                 $cnum = $posscnum;
@@ -414,7 +438,7 @@
         } else {
             my $crshome = &Apache::lonnet::homeserver($urlcnum,$cdom);
             if ($crshome =~ /(con_lost|no_host|no_such_host)/) {
-                &invalid_request($r,11);
+                &invalid_request($r,13);
                 return OK;
             } else {
                 $cnum = $urlcnum;
@@ -479,7 +503,7 @@
                                                     $domdesc,\%data,\%alerts,\%rulematch,
                                                     \%inst_results,\%curr_rules,%got_rules);
                 if ($result eq 'notallowed') {
-                    &invalid_request($r,12);
+                    &invalid_request($r,14);
                 } elsif ($result eq 'ok') {
                     if (($ltiroles[0] eq 'Instructor') && ($lcroles[0] eq 'cc') && ($lti{$itemid}{'mapcrs'}) &&
                         ($lti{$itemid}{'makecrs'})) {
@@ -488,16 +512,16 @@
                         }
                     }
                 } else {
-                    &invalid_request($r,13);
+                    &invalid_request($r,15);
                     return OK;
                 }
             } else {
-                &invalid_request($r,14);
+                &invalid_request($r,16);
                 return OK;
             }
         }
     } else {
-        &invalid_request($r,15);
+        &invalid_request($r,17);
         return OK;
     }
 
@@ -519,10 +543,10 @@
                              $symb,$cdom,$cnum,$params,\@ltiroles,$lti{$itemid},\@lcroles,
                              $reqcrs,$sourcecrs);
             } else {
-                &invalid_request($r,16);
+                &invalid_request($r,18);
             }
         } else {
-            &invalid_request($r,17);
+            &invalid_request($r,19);
         }
         return OK;
     }
@@ -608,7 +632,7 @@
             }
         }
         if ($reqrole eq '') {
-            &invalid_request($r,18);
+            &invalid_request($r,20);
             return OK;
         } else {
             unless (%crsenv) {
@@ -618,10 +642,10 @@
             my $default_enrollment_end_date   = $crsenv{'default_enrollment_end_date'};
             my $now = time;
             if ($default_enrollment_end_date && $default_enrollment_end_date <= $now) {
-                &invalid_request($r,19);
+                &invalid_request($r,21);
                 return OK;
             } elsif ($default_enrollment_start_date && $default_enrollment_start_date >$now) {
-                &invalid_request($r,20);
+                &invalid_request($r,22);
                 return OK;
             } else {
                 $selfenrollrole = $reqrole.'./'.$cdom.'/'.$cnum;


More information about the LON-CAPA-cvs mailing list