[LON-CAPA-cvs] cvs: doc /loncapafiles loncapafiles.lpml loncom loncapa_apache.conf lontrans.pm loncom/auth lonacc.pm lonauth.pm lonlinkexit.pm lonlogin.pm lonshibauth.pm migrateuser.pm switchserver.pm loncom/interface loncommon.pm lonhtmlcommon.pm lonmenu.pm lontiny.pm loncom/lti ltiauth.pm

raeburn raeburn at source.lon-capa.org
Thu Jun 30 17:04:15 EDT 2022


raeburn		Thu Jun 30 21:04:15 2022 EDT

  Added files:                 
    /loncom/auth	lonlinkexit.pm 

  Modified files:              
    /loncom/auth	lonacc.pm lonauth.pm lonlogin.pm lonshibauth.pm 
                	migrateuser.pm switchserver.pm 
    /loncom/interface	lontiny.pm loncommon.pm lonmenu.pm 
                     	lonhtmlcommon.pm 
    /loncom/lti	ltiauth.pm 
    /loncom	lontrans.pm loncapa_apache.conf 
    /doc/loncapafiles	loncapafiles.lpml 
  Log:
  - Bug 6907
    "Exit Tool" button available to logout a session launched via deep link 
    and escape iframe and redirect (for LTI-protected link).
  
  
-------------- next part --------------
Index: loncom/auth/lonacc.pm
diff -u loncom/auth/lonacc.pm:1.204 loncom/auth/lonacc.pm:1.205
--- loncom/auth/lonacc.pm:1.204	Mon Jun 20 15:07:21 2022
+++ loncom/auth/lonacc.pm	Thu Jun 30 21:04:13 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Cookie Based Access Handler
 #
-# $Id: lonacc.pm,v 1.204 2022/06/20 15:07:21 raeburn Exp $
+# $Id: lonacc.pm,v 1.205 2022/06/30 21:04:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -333,7 +333,7 @@
         }
     }
 
-    my ($linkprot,$linkprotuser,$linkkey,$deeplinkurl);
+    my ($linkprot,$linkprotuser,$linkprotexit,$linkkey,$deeplinkurl);
 
 #
 # If Shibboleth auth is in use, and a dual SSO and non-SSO login page
@@ -372,6 +372,7 @@
         if ($info{'linkprot'}) {
             $linkprot = $info{'linkprot'};
             $linkprotuser = $info{'linkprotuser'};
+            $linkprotexit = $info{'linkprotexit'};
         } elsif ($info{'linkkey'} ne '') {
             $linkkey = $info{'linkkey'};
         }
@@ -397,6 +398,7 @@
             if ($form{'linkprot'}) {
                 $linkprot = $form{'linkprot'};
                 $linkprotuser = $form{'linkprotuser'};
+                $linkprotexit = $form{'linkprotexit'};
             } elsif ($form{'linkkey'} ne '') {
                 $linkkey = $form{'linkkey'};
             }
@@ -425,6 +427,7 @@
             if ($form{'linkprot'}) {
                 $linkprot = $form{'linkprot'};
                 $linkprotuser = $form{'linkprotuser'};
+                $linkprotexit = $form{'linkprotexit'};
             } elsif ($form{'linkkey'} ne '') {
                 $linkkey = $form{'linkkey'};
             }
@@ -432,8 +435,13 @@
     } elsif ($form{'ltoken'}) {
         my %link_info = &Apache::lonnet::tmpget($form{'ltoken'});
         $linkprot = $link_info{'linkprot'};
-        if (($linkprot) && ($link_info{'linkprotuser'} ne '')) {
-            $linkprotuser = $link_info{'linkprotuser'};    
+        if ($linkprot) {
+            if ($link_info{'linkprotuser'} ne '') {
+                $linkprotuser = $link_info{'linkprotuser'};
+            }
+            if ($link_info{'linkprotexit'} ne '') {
+                $linkprotexit = $link_info{'linkprotexit'};
+            }
         }
         my $delete = &Apache::lonnet::tmpdel($form{'ltoken'});
         delete($form{'ltoken'});
@@ -455,6 +463,7 @@
                            origurl => $deeplinkurl,
                            linkprot => $linkprot,
                            linkprotuser => $linkprotuser,
+                           linkprotexit => $linkprotexit,
                        );
             my $token = &Apache::lonnet::tmpput(\%data,$r->dir_config('lonHostID'),'link');
             unless (($token eq 'con_lost') || ($token eq 'refused') || ($token =~ /^error:/) ||
@@ -521,6 +530,9 @@
                     if ($linkprotuser ne '') {
                         $env{'request.linkprotuser'} = $linkprotuser;
                     }
+                    if ($linkprotexit ne '') {
+                        $env{'request.linkprotexit'} = $linkprotexit;
+                    }
                 } elsif ($linkkey ne '') {
                     $env{'request.linkkey'} = $linkkey;
                 }
@@ -566,6 +578,12 @@
             if ($info{'deeplink.login'}) {
                 if ($linkprot) {
                     $info{'linkprot'} = $linkprot;
+                    if ($linkprotuser ne '') {
+                        $info{'linkprotuser'} = $linkprotuser;
+                    }
+                    if ($linkprotexit ne '') {
+                        $info{'linkprotexit'} = $linkprotexit;
+                    }
                 } elsif ($linkkey ne '') {
                     $info{'linkkey'} = $linkkey;
                 }
@@ -785,6 +803,7 @@
                                 origurl => $requrl,
                                 linkprot => $info{'linkprot'},
                                 linkprotuser => $info{'linkprotuser'},
+                                linkprotexit => $info{'linkprotexit'},
                             );
                         } elsif ($info{'ltoken'} ne '') {
                             my %ltoken_info = &Apache::lonnet::tmpget($info{'ltoken'});
@@ -794,6 +813,7 @@
                                     origurl => $requrl,
                                     linkprot => $ltoken_info{'linkprot'},
                                     linkprotuser => $ltoken_info{'linkprotuser'},
+                                    linkprotexit => $ltoken_info{'linkprotexit'},
                                 );
                             }
                         }
Index: loncom/auth/lonauth.pm
diff -u loncom/auth/lonauth.pm:1.175 loncom/auth/lonauth.pm:1.176
--- loncom/auth/lonauth.pm:1.175	Sun Jun 26 04:03:47 2022
+++ loncom/auth/lonauth.pm	Thu Jun 30 21:04:13 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # User Authentication Module
 #
-# $Id: lonauth.pm,v 1.175 2022/06/26 04:03:47 raeburn Exp $
+# $Id: lonauth.pm,v 1.176 2022/06/30 21:04:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -188,8 +188,10 @@
         my %info;
         if ($env{'request.linkprot'}) {
             $info{'linkprot'} = $env{'request.linkprot'};
-            if ($form->{'linkprotuser'}) {
-                $info{'linkprotuser'} = $form->{'linkprotuser'};
+            foreach my $item ('linkprotuser','linkprotexit') {
+                if ($form->{$item}) {
+                    $info{$item} = $form->{$item};
+                }
             }
             $args = {'only_body' => 1,};
         } elsif ($env{'request.linkkey'} ne '') {
@@ -371,8 +373,10 @@
             my %info = (
                          'linkprot' => $form->{'linkprot'},
                        );
-            if ($form->{linkprotuser} ne '') {
-                $info{'linkprotuser'} = $form->{linkprotuser};
+            foreach my $item ('linkprotuser','linkprotexit') {
+                if ($form->{$item} ne '') {
+                    $info{$item} = $form->{$item};
+                }
             }
             my $ltoken = &Apache::lonnet::tmpput(\%info,
                                                  $r->dir_config('lonHostID'),'retry');
@@ -815,8 +819,10 @@
             }
             if ($form{'linkprot'}) {
                 $env{'request.linkprot'} = $form{'linkprot'};
-                if ($form{'linkprotuser'}) {
-                    $env{'request.linkprotuser'} = $form{'linkprotuser'};
+                foreach my $item ('linkprotuser','linkprotexit') {
+                    if ($form{$item}) {
+                        $env{'request.'.$item} = $form{$item};
+                    }
                 }
             } elsif ($form{'linkkey'} ne '') {
                 $env{'request.linkkey'} = $form{'linkkey'};
@@ -849,8 +855,10 @@
                 }
                 if ($form{'linkprot'}) {
                     $env{'request.linkprot'} = $form{'linkprot'};
-                    if ($form{'linkprotuser'}) {
-                        $env{'request.linkprotuser'} = $form{'linkprotuser'};
+                    foreach my $item ('linkprotuser','linkprotexit') {
+                        if ($form{$item}) {
+                            $env{'request.'.$item} = $form{$item};
+                        }
                     }
                 } elsif ($form{'linkkey'} ne '') {
                     $env{'request.linkkey'} = $form{'linkkey'};
@@ -935,6 +943,9 @@
                 } else {
                     $extra_env = {'request.linkprot' => $form{'linkprot'}};
                 }
+                if ($form{'linkprotexit'}) {
+                    $extra_env->{'request.linkprotexit'} = $form{'linkprotexit'};
+                }
             } elsif ($form{'linkkey'} ne '') {
                 if (ref($extra_env) eq 'HASH') {
                     %{$extra_env} = ( %{$extra_env}, 'request.linkkey' => $form{'linkkey'} );
@@ -1023,7 +1034,7 @@
     my ($form,$lonhost,$querystr) = @_;
     if (ref($form) eq 'HASH') {
         my ($firsturl,$token,$extras, at names);
-        @names = ('role','symb','linkprotuser','linkprot','linkkey','iptoken');
+        @names = ('role','symb','linkprotuser','linkprotexit','linkprot','linkkey','iptoken');
         foreach my $name (@names) {
             if ($form->{$name} ne '') {
                 $extras .= '&'.$name.'='.&escape($form->{$name});
Index: loncom/auth/lonlogin.pm
diff -u loncom/auth/lonlogin.pm:1.200 loncom/auth/lonlogin.pm:1.201
--- loncom/auth/lonlogin.pm:1.200	Sun Jun 26 04:03:47 2022
+++ loncom/auth/lonlogin.pm	Thu Jun 30 21:04:13 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Login Screen
 #
-# $Id: lonlogin.pm,v 1.200 2022/06/26 04:03:47 raeburn Exp $
+# $Id: lonlogin.pm,v 1.201 2022/06/30 21:04:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -68,8 +68,10 @@
             $env{'form.ltoken'} = $info{'ltoken'};
         } elsif ($info{'linkprot'}) {
             $env{'form.linkprot'} = $info{'linkprot'};
-            if ($info{'linkprotuser'} ne '') {
-                $env{'form.linkprotuser'} = $info{'linkprotuser'};
+            foreach my $item ('linkprotuser','linkprotexit') {
+                if ($info{$item} ne '') {
+                    $env{'form.'.$item} = $info{$item};
+                }
             }
         } elsif ($info{'linkkey'} ne '') {
             $env{'form.linkkey'} = $info{'linkkey'};
@@ -184,8 +186,10 @@
                     $link_info{'ltoken'} = $env{'form.ltoken'};
                 } elsif ($env{'form.linkprot'}) {
                     $link_info{'linkprot'} = $env{'form.linkprot'};
-                    if ($env{'form.linkprotuser'} ne '') {
-                        $link_info{'linkprotuser'} = $env{'form.linkprotuser'};
+                    foreach my $item ('linkprotuser','linkprotexit') {
+                        if ($env{'form.'.$item} ne '') {
+                            $link_info{$item} = $env{'form.'.$item};
+                        }
                     }
                 } elsif ($env{'form.linkkey'} ne '') {
                     $link_info{'linkkey'} = $env{'form.linkkey'};
@@ -255,16 +259,20 @@
             $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
         }
         if (($env{'form.ltoken'}) || ($env{'form.linkprot'})) {
-            my ($linkprot,$linkprotuser);
+            my ($linkprot,$linkprotuser,$linkprotexit);
             if ($env{'form.ltoken'}) {
                 my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
                 $linkprot = $info{'linkprot'};
                 if ($info{'linkprotuser'} ne '') {
                     $linkprotuser = $info{'linkprotuser'};
-                } 
+                }
+                if ($info{'linkprotexit'} ne '') {
+                    $linkprotexit = $info{'linkprotexit'};
+                }
             } else {
                 $linkprot = $env{'form.linkprot'};
                 $linkprotuser = $env{'form.linkprotuser'};
+                $linkprotexit = $env{'form.linkprotexit'};
             }
             if ($linkprot) {
                 my ($linkprotector,$deeplink) = split(/:/,$linkprot,2);
@@ -275,6 +283,7 @@
                                           origurl => $deeplink,
                                           linkprot => $linkprot,
                                           linkprotuser => $linkprotuser,
+                                          linkprotexit => $linkprotexit,
                                        );    
                     if ($env{'form.ltoken'}) {
                         my $delete = &Apache::lonnet::tmpdel($env{'form.ltoken'});
@@ -455,7 +464,7 @@
 
 # -------------------------------------------------------- Store away log token
     my ($tokenextras,$tokentype,$linkprot_for_login);
-    my @names = ('role','symb','iptoken','ltoken','linkprotuser','linkprot','linkkey');
+    my @names = ('role','symb','iptoken','ltoken','linkprotuser','linkprotexit','linkprot','linkkey');
     foreach my $name (@names) {
         if ($env{'form.'.$name} ne '') {
             if ($name eq 'ltoken') {
@@ -463,8 +472,10 @@
                 if ($info{'linkprot'}) {
                     $linkprot_for_login = $info{'linkprot'};
                     $tokenextras .= '&linkprot='.&escape($info{'linkprot'});
-                    if ($info{'linkprotuser'}) {
-                        $tokenextras .= '&linkprotuser='.&escape($info{'linkprotuser'});
+                    foreach my $item ('linkprotuser','linkprotexit') {
+                        if ($info{$item}) {
+                            $tokenextras .= '&'.$item.'='.&escape($info{$item});
+                        }
                     }
                     $tokentype = 'link';
                     last;
@@ -1166,8 +1177,10 @@
                 $args->{'only_body'} = 1;
             } elsif ($env{'form.linkprot'}) {
                 $link_info{'linkprot'} = $env{'form.linkprot'};
-                if ($env{'form.linkprotuser'}) {
-                    $link_info{'linkprotuser'} = $env{'form.linkprotuser'};
+                foreach my $item ('linkprotuser','linkprotexit') {
+                    if ($env{'form.'.$item}) {
+                        $link_info{$item} = $env{'form.'.$item};
+                    }
                 }
                 $args->{'only_body'} = 1;
             } elsif ($env{'form.linkkey'} ne '') {
Index: loncom/auth/lonshibauth.pm
diff -u loncom/auth/lonshibauth.pm:1.15 loncom/auth/lonshibauth.pm:1.16
--- loncom/auth/lonshibauth.pm:1.15	Sat Jun 18 02:10:18 2022
+++ loncom/auth/lonshibauth.pm	Thu Jun 30 21:04:13 2022
@@ -2,7 +2,7 @@
 # Redirect Single Sign On authentication to designated URL: 
 # /adm/sso, by default.
 #
-# $Id: lonshibauth.pm,v 1.15 2022/06/18 02:10:18 raeburn Exp $
+# $Id: lonshibauth.pm,v 1.16 2022/06/30 21:04:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -306,8 +306,10 @@
                 &Apache::lonnet::tmpdel($env{'form.ltoken'});
                 if ($info{'linkprot'}) {
                     $extras .= '&linkprot='.&escape($info{'linkprot'});
-                    if ($info{'linkprotuser'} ne '') {
-                        $extras .= '&linkprotuser='.&escape($info{'linkprotuser'});
+                    foreach my $item ('linkprotuser','linkprotexit') {
+                        if ($info{$item} ne '') {
+                            $extras .= '&'.$item.'='.&escape($info{$item});
+                        }
                     }
                     last;
                 }
Index: loncom/auth/migrateuser.pm
diff -u loncom/auth/migrateuser.pm:1.62 loncom/auth/migrateuser.pm:1.63
--- loncom/auth/migrateuser.pm:1.62	Sun Jun 26 04:03:47 2022
+++ loncom/auth/migrateuser.pm	Thu Jun 30 21:04:13 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Starts a user off based of an existing token.
 #
-# $Id: migrateuser.pm,v 1.62 2022/06/26 04:03:47 raeburn Exp $
+# $Id: migrateuser.pm,v 1.63 2022/06/30 21:04:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -285,7 +285,7 @@
                     'username'        => $dataref->{'username'},
                     'sessionserver'   => $lonhost,
                   );
-        my @names = ('origurl','symb','role','linkprotuser','linkprot','linkkey');
+        my @names = ('origurl','symb','role','linkprotuser','linkprotexit','linkprot','linkkey');
         foreach my $name (@names) {
             if ($dataref->{$name} ne '') {
                 $info{$name} = $dataref->{$name};
@@ -902,8 +902,10 @@
                     my %info;
                     if ($env{'request.linkprot'}) {
                         $info{'linkprot'} = $env{'request.linkprot'};
-                        if ($data{'linkprotuser'}) {
-                            $info{'linkprotuser'} = $data{'linkprotuser'};
+                        foreach my $item ('linkprotuser','linkprotexit') {
+                            if ($data{$item}) {
+                                $info{$item} = $data{$item};
+                            }
                         }
                     } elsif ($env{'request.linkkey'} ne '') {
                         $info{'linkkey'} = $env{'request.linkkey'};
@@ -957,8 +959,10 @@
                                           'request.linkprot' => $data{'linkprot'}};
                         }
                     }
-                    if ($data{'linkprotuser'} ne '') {
-                        $form{'linkprotuser'} = $data{'linkprotuser'};
+                    foreach my $item ('linkprotuser','linkprotexit') {
+                        if ($data{$item} ne '') {
+                            $form{$item} = $data{$item};
+                        }
                     }
                 } elsif ($data{'linkkey'} ne '') {
                     if (ref($extra_env) eq 'HASH') {
@@ -1057,8 +1061,10 @@
             }
             if ($data{'linkprot'}) {
                 $extra_env->{'request.linkprot'} = $data{'linkprot'};
-                if ($data{'linkprotuser'}) {
-                    $form{'request.linkprotuser'} = $data{'linkprotuser'};
+                foreach my $item ('linkprotuser','linkprotexit') {
+                    if ($data{$item}) {
+                        $form{'request.'.$item} = $data{$item};
+                    }
                 }
             } elsif ($data{'linkkey'} ne '') {
                 $extra_env->{'request.linkkey'} = $data{'linkkey'};
Index: loncom/auth/switchserver.pm
diff -u loncom/auth/switchserver.pm:1.60 loncom/auth/switchserver.pm:1.61
--- loncom/auth/switchserver.pm:1.60	Sat Jun 18 02:10:18 2022
+++ loncom/auth/switchserver.pm	Thu Jun 30 21:04:13 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Switch Servers Handler
 #
-# $Id: switchserver.pm,v 1.60 2022/06/18 02:10:18 raeburn Exp $
+# $Id: switchserver.pm,v 1.61 2022/06/30 21:04:13 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -312,8 +312,10 @@
     }
     if ($env{'request.linkprot'}) {
         $info{'linkprot'} = $env{'request.linkprot'};
-        if ($env{'request.linkprotuser'}) {
-            $info{'linkprotuser'} = $env{'request.linkprotuser'};
+        foreach my $item ('linkprotuser','linkprotexit') {
+            if ($env{'request.'.$item}) {
+                $info{$item} = $env{'request.'.$item};
+            }
         }
     } elsif ($env{'request.linkkey'} ne '') {
         $info{'linkkey'} = $env{'request.linkkey'};
Index: loncom/interface/lontiny.pm
diff -u loncom/interface/lontiny.pm:1.11 loncom/interface/lontiny.pm:1.12
--- loncom/interface/lontiny.pm:1.11	Sun Jun 26 04:03:48 2022
+++ loncom/interface/lontiny.pm	Thu Jun 30 21:04:14 2022
@@ -2,7 +2,7 @@
 # Extract domain, courseID, and symb from a shortened URL,
 # and switch role to a role in designated course.
 #
-# $Id: lontiny.pm,v 1.11 2022/06/26 04:03:48 raeburn Exp $
+# $Id: lontiny.pm,v 1.12 2022/06/30 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -68,7 +68,7 @@
                         my $chome = &Apache::lonnet::homeserver($cnum,$cdom);
                         if ($chome ne 'no_host') {
                             &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['ttoken']);
-                            my ($linkprot,$linkprotuser,$ltoken);
+                            my ($linkprot,$linkprotuser,$linkprotexit,$ltoken);
                             if ($env{'form.ttoken'}) {
                                 my %link_info = &Apache::lonnet::tmpget($env{'form.ttoken'});
                                 if ($link_info{'origurl'} eq $r->uri) {
@@ -77,11 +77,15 @@
                                         my %ltoken_info = &Apache::lonnet::tmpget($link_info{'ltoken'});
                                         $linkprot = $ltoken_info{'linkprot'};
                                         $linkprotuser = $ltoken_info{'linkprotuser'};
+                                        $linkprotexit = $ltoken_info{'linkprotexit'};
                                     } elsif ($link_info{'linkprot'}) {
                                         $linkprot = $link_info{'linkprot'};
                                         if ($link_info{'linkprotuser'}) {
                                             $linkprotuser = $link_info{'linkprotuser'};
                                         }
+                                        if ($link_info{'linkprotexit'}) {
+                                            $linkprotexit = $link_info{'linkprotexit'};
+                                        }
                                     }
                                 }
                             }
@@ -233,7 +237,7 @@
                                     }
                                 }
                                 if (@allposs == 0) {
-                                    &show_roles($r,\%crsenv,\%active,'','',\%future,\%expired,$linkprot,$linkprotuser,$ltoken);
+                                    &show_roles($r,\%crsenv,\%active,'','',\%future,\%expired,$linkprot,$linkprotuser,$linkprotexit,$ltoken);
                                 } elsif (@allposs == 1) {
                                     my $newrole = "$allposs[0]./$cdom/$cnum";
                                     $newrole = "$allposs[0]./$cdom/$cnum";
@@ -462,7 +466,7 @@
 }
 
 sub show_roles {
-    my ($r,$crsenv,$possroles,$hassection,$hascustom,$futureroles,$expiredroles,$linkprot,$linkprotuser,$ltoken) = @_;
+    my ($r,$crsenv,$possroles,$hassection,$hascustom,$futureroles,$expiredroles,$linkprot,$linkprotuser,$linkprotexit,$ltoken) = @_;
     my ($crsdesc,$crstype,$cdom,$cnum,$header,$title,$preamble,$datatable,$js,$args);
     if (ref($crsenv) eq 'HASH') {
         $crsdesc = $crsenv->{'description'};
@@ -602,6 +606,7 @@
                     my %data = (
                                 origurl => $r->uri,
                                 linkprot => $linkprot,
+                                linkprotexit => $linkprotexit,
                     );
                     my $token =
                         &Apache::lonnet::tmpput(\%data,$r->dir_config('lonHostID'),'retry');
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1384 loncom/interface/loncommon.pm:1.1385
--- loncom/interface/loncommon.pm:1.1384	Sat Jun 11 14:51:49 2022
+++ loncom/interface/loncommon.pm	Thu Jun 30 21:04:14 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1384 2022/06/11 14:51:49 raeburn Exp $
+# $Id: loncommon.pm,v 1.1385 2022/06/30 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -6377,6 +6377,21 @@
             context, this will contain a reference to hash of items
             to be included in the page header and/or inline menu.
 
+=item * $menucoll, optional argument, if specific menu collection is in
+            effect, either set as the default for the course, or set for
+            the deeplink paramater for $env{'request.deeplink.login'}
+            then $menucoll will be the number of that collection. 
+
+=item * $menuref, optional argument, reference to a hash, containing the
+            menu options included for the menu in effect, based on the
+            configuration for the numbered menu collection in use.  
+
+=item * $showncrumbsref, reference to a scalar. Calls to lonmenu::innerregister
+            within &bodytag() can result in calls to lonhtmlcommon::breadcrumbs(),
+            if so, $showncrumbsref is set there to 1, and will propagate back
+            via &bodytag() to &start_page(), to prevent lonhtmlcommon::breadcrumbs()
+            being called a second time.
+
 =back
 
 Returns: A uniform header for LON-CAPA web pages.  
@@ -6389,7 +6404,7 @@
 sub bodytag {
     my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
         $no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,
-        $ltimenu,$menucoll,$menuref)=@_;
+        $ltimenu,$menucoll,$menuref,$showncrumbsref)=@_;
 
     my $public;
     if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
@@ -6570,12 +6585,12 @@
             $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
             if ($env{'request.state'} eq 'construct') {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,
-                                $args->{'bread_crumbs'},'','',$hostname,$ltiscope,$ltiuri);
+                                $args->{'bread_crumbs'},'','',$hostname,
+                                $ltiscope,$ltiuri,$showncrumbsref);
             } elsif ($forcereg) {
                 $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef,
-                                                            $args->{'group'},
-                                                            $args->{'hide_buttons'},
-                                                            $hostname,$ltiscope,$ltiuri);
+                                $args->{'group'},$args->{'hide_buttons'},
+                                $hostname,$ltiscope,$ltiuri,$showncrumbsref);
             } else {
                 $bodytag .= 
                     &Apache::lonmenu::prepare_functions($env{'request.noversionuri'},
@@ -9338,6 +9353,7 @@
         }
     }
 
+    my $showncrumbs;
     if (! exists($args->{'skip_phases'}{'body'}) ) {
 	if ($args->{'frameset'}) {
 	    my $attr_string = &make_attr_string($args->{'force_register'},
@@ -9350,7 +9366,8 @@
                          $args->{'only_body'},      $args->{'domain'},
                          $args->{'force_register'}, $args->{'no_nav_bar'},
                          $args->{'bgcolor'},        $args,
-                         \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll,\%menu);
+                         \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll,
+                         \%menu,\$showncrumbs);
         }
     }
 
@@ -9372,6 +9389,7 @@
 
     #Breadcrumbs
     if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {
+        unless ($showncrumbs) {
 		&Apache::lonhtmlcommon::clear_breadcrumbs();
 		#if any br links exists, add them to the breadcrumbs
 		if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') {         
@@ -9394,12 +9412,20 @@
                 } else {
                     undef($menulink);
                 }
+                my $linkprotout;
+                if ($env{'request.deeplink.login'}) {
+                    my $linkprotout = &Apache::lonmenu::linkprot_exit();
+                    if ($linkprotout) {
+                        &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout);
+                    }
+                }
 		#if bread_crumbs_component exists show it as headline else show only the breadcrumbs
 		if(exists($args->{'bread_crumbs_component'})){
 			$result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink);
                 } else {
 			$result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink);
 		}
+        }
     }
     return $result;
 }
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.523 loncom/interface/lonmenu.pm:1.524
--- loncom/interface/lonmenu.pm:1.523	Sat Jun 11 04:30:48 2022
+++ loncom/interface/lonmenu.pm	Thu Jun 30 21:04:14 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.523 2022/06/11 04:30:48 raeburn Exp $
+# $Id: lonmenu.pm,v 1.524 2022/06/30 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -846,7 +846,8 @@
 }
 
 sub innerregister {
-    my ($forcereg,$bread_crumbs,$group,$pagebuttonshide,$hostname,$ltiscope,$ltiuri) = @_;
+    my ($forcereg,$bread_crumbs,$group,$pagebuttonshide,$hostname,
+        $ltiscope,$ltiuri,$showncrumbsref) = @_;
     my $const_space = ($env{'request.state'} eq 'construct');
     my $is_const_dir = 0;
 
@@ -938,14 +939,17 @@
                 if ($env{'form.folderpath'}) {
                     &prepare_functions($resurl,$forcereg,$group,undef,undef,1,$hostname);
                     ($trail) =
-                        &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
+                        &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,1);
                 } else {
                     &Apache::lonhtmlcommon::add_breadcrumb(
                     {text  => "Supplemental $crstype Content",
                      href  => "javascript:gopost('/adm/supplemental','')"});
                     $title = &mt('View Resource');
                     ($trail) = 
-                        &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
+                        &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,1);
+                }
+                if (ref($showncrumbsref)) {
+                    $$showncrumbsref = 1;
                 }
                 return $trail;
             } elsif ($resurl =~ m{^\Q/uploaded$courseurl/portfolio/syllabus/}) {
@@ -954,7 +958,10 @@
                                    $forcereg,$group,undef,undef,1,$hostname);
                 $title = &mt('Syllabus File');
                 my ($trail) =
-                    &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,$hostname);
+                    &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,1);
+                if (ref($showncrumbsref)) {
+                    $$showncrumbsref = 1;
+                }
                 return $trail;
             }
             unless ($env{'request.state'} eq 'construct') {
@@ -1261,10 +1268,13 @@
                 }
             }
         }
-        my $showprogress;
+        my ($showprogress,$linkprotout);
         if (($crstype eq 'Placement') && (!$env{'request.role.adv'})) {
             $showprogress = &placement_progress();
         }
+        if ($env{'request.deeplink.login'}) {
+            $linkprotout = &linkprot_exit();
+        }
 
 	my $addremote=0;
 	foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
@@ -1290,6 +1300,9 @@
             if ($countdown) {
                 &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);
             }
+            if ($linkprotout) {
+                &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout);
+            }
             if ($showprogress) {
                 &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$showprogress);
             }
@@ -1298,6 +1311,9 @@
             if ($countdown) {
                 unshift(@tools,$countdown);
             }
+            if ($linkprotout) {
+                unshift(@tools,$linkprotout);
+            }
             &Apache::lonhtmlcommon::add_breadcrumb_tool(
                 'tools', at tools);
 
@@ -1315,6 +1331,9 @@
         if ($showprogress) {
             &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$showprogress);
         }
+        if ($linkprotout) {
+            &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout);
+        }
     }
     my ($topic_help,$topic_help_text);
     if ($is_const_dir == 2) {
@@ -1326,6 +1345,9 @@
             $topic_help_text = 'About WebDAV access';
         }
     }
+    if (ref($showncrumbsref)) {
+        $$showncrumbsref = 1;
+    }
     return   &Apache::lonhtmlcommon::scripttag('', 'start')
            . &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'','','','',$topic_help,$topic_help_text)
            . &Apache::lonhtmlcommon::scripttag('', 'end');
@@ -3177,6 +3199,86 @@
            &mt('Test is [_1]% complete',$complete).'</span>';
 }
 
+sub linkprot_exit {
+    if (($env{'request.ciurse.id'}) && ($env{'request.deeplink.login'})) {
+        my ($deeplink_symb,$deeplink);
+        my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+        my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+        if (($cnum ne '') && ($cdom ne '')) {
+            $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom);
+            if ($deeplink_symb) {
+                if ($deeplink_symb =~ /\.(page|sequence)$/) {
+                    my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]);
+                    my $navmap = Apache::lonnavmaps::navmap->new();
+                    if (ref($navmap)) {
+                        $deeplink = $navmap->get_mapparam(undef,$mapname,'0.deeplink');
+                    }
+                } else {
+                    $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$deeplink_symb);
+                }
+                if ($deeplink ne '') {
+                    my ($state,$others,$listed,$scope,$protect,$display,$target,$exit) = split(/,/,$deeplink);
+                    my %lt = &Apache::lonlocal::texthash(
+                        title    => 'Exit Tool',
+                        okdone   => 'Click "OK" to exit embedded tool',
+                        cancel   => 'Click "Cancel" to continue working.',
+                        ok       => 'OK',
+                        exit     => 'Cancel',
+                    );
+                    if ($exit) {
+                        my $height = 250;
+                        my $width = 300;
+                        my $exitbuttontext = &mt('Exit Tool');
+                        return <<END;
+<form method="post" name="LCexitButton" action="/adm/linkexit">
+    <input type="hidden" name="LC_deeplink_exit" value="" />
+    <button id="LC_exit-confirm-opener" type="button">$exitbuttontext</button>
+</form>
+
+<div id="LC_exit-confirm" title="$lt{'title'}">
+    <p>$lt{'okdone'} $lt{'cancel'}</p>
+</div>
+
+<script type="text/javascript">
+// <![CDATA[
+\$( "#LC_exit-confirm" ).dialog({ autoOpen: false });
+\$( "#LC_exit-confirm-opener" ).click(function() {
+    \$( "#LC_exit-confirm" ).dialog( "open" );
+    \$( "#LC_exit-confirm" ).dialog({
+      resizable: false,
+      height: $height,
+      width: $width,
+      modal: true,
+      buttons: [
+                 {
+                    text: "$lt{'ok'}",
+                    click: function() {
+                        \$( this ).dialog( "close" );
+                        \$( '[name="LC_deeplink_exit"]' )[0].value = 'true';
+                        \$( '[name="LCexitButton"]' )[0].submit();
+                    },
+                 },
+                 {
+                     text: "$lt{'exit'}",
+                     click: function() {
+                         \$( this ).dialog( "close" );
+                     },
+                  },
+               ],
+       });
+});
+// ]]>
+</script>
+
+END
+                    }
+                }
+            }
+        }
+    }
+    return;
+}
+
 # ================================================================ Main Program
 
 BEGIN {
Index: loncom/interface/lonhtmlcommon.pm
diff -u loncom/interface/lonhtmlcommon.pm:1.404 loncom/interface/lonhtmlcommon.pm:1.405
--- loncom/interface/lonhtmlcommon.pm:1.404	Sat Jun 11 05:07:55 2022
+++ loncom/interface/lonhtmlcommon.pm	Thu Jun 30 21:04:14 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common html routines
 #
-# $Id: lonhtmlcommon.pm,v 1.404 2022/06/11 05:07:55 raeburn Exp $
+# $Id: lonhtmlcommon.pm,v 1.405 2022/06/30 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2237,7 +2237,7 @@
 } # End of scope for @Crumbs
 
 sub docs_breadcrumbs {
-    my ($allowed,$crstype,$contenteditor,$title,$precleared)=@_;
+    my ($allowed,$crstype,$contenteditor,$title,$precleared,$checklinkprot)=@_;
     my ($folderpath, at folders,$supplementalflag);
     @folders = split('&',$env{'form.folderpath'});
     if ($env{'form.folderpath'} =~ /^supplemental/) {
@@ -2308,6 +2308,14 @@
         if (!$allowed && !$contenteditor) {
             $menulink = 1;
         }
+        if ($checklinkprot) {
+            if ($env{'request.deeplink.login'}) {
+                my $linkprotout = &Apache::lonmenu::linkprot_exit();
+                if ($linkprotout) {
+                    &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout);
+                }
+            }
+        }
         return (&breadcrumbs(undef,undef,$menulink,'nohelp',undef,undef,
                              $contenteditor),
                              $randompick,$ishidden,$isencrypted,$plain,
Index: loncom/lti/ltiauth.pm
diff -u loncom/lti/ltiauth.pm:1.38 loncom/lti/ltiauth.pm:1.39
--- loncom/lti/ltiauth.pm:1.38	Sun Jun 26 04:03:48 2022
+++ loncom/lti/ltiauth.pm	Thu Jun 30 21:04:14 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Basic LTI Authentication Module
 #
-# $Id: ltiauth.pm,v 1.38 2022/06/26 04:03:48 raeburn Exp $
+# $Id: ltiauth.pm,v 1.39 2022/06/30 21:04:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -175,6 +175,14 @@
                                 }
                             }
                         }
+                        my $exiturl;
+                        if (($itemid) && ($lti_in_use{'returnurl'} ne '')) {
+                            if (exists($params->{$lti_in_use{'returnurl'}})) {
+                                $exiturl = $params->{$lti_in_use{'returnurl'}};
+                            } elsif (exists($params->{'custom_'.$lti_in_use{'returnurl'}})) {
+                                $exiturl = $params->{'custom_'.$lti_in_use{'returnurl'}};
+                            }
+                        }
                         if (($itemid) && ($lti_in_use{'requser'})) {
                             my %courseinfo = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
                             my $ltiauth;
@@ -225,7 +233,7 @@
                                                 foreach my $key (%{$params}) {
                                                     delete($env{'form.'.$key});
                                                 }
-                                                &linkprot_session($r,$uname,$cnum,$cdom,$uhome,$itemid,$ltitype,$tail,$lonhost);
+                                                &linkprot_session($r,$uname,$cnum,$cdom,$uhome,$itemid,$ltitype,$tail,$lonhost,$exiturl);
                                                 return OK;
                                             }
                                         }
@@ -248,6 +256,9 @@
                             if ($ltiuser ne '') {
                                 $info{'linkprotuser'} = $ltiuser;
                             }
+                            if ($exiturl ne '') {
+                                $info{'linkprotexit'} = $exiturl; 
+                            }
                             my $ltoken = &Apache::lonnet::tmpput(\%info,$lonhost,'link');
                             if (($ltoken eq 'con_lost') || ($ltoken eq 'refused') || ($ltoken =~ /^error:/) ||
                                 ($ltoken eq 'unknown_cmd') || ($ltoken eq 'no_such_host') ||
@@ -1061,7 +1072,7 @@
 }
 
 sub linkprot_session {
-    my ($r,$uname,$cnum,$cdom,$uhome,$itemid,$ltitype,$dest,$lonhost) = @_;
+    my ($r,$uname,$cnum,$cdom,$uhome,$itemid,$ltitype,$dest,$lonhost,$exiturl) = @_;
     $r->user($uname);
     if ($ltitype eq 'c') {
         &Apache::lonnet::logthis("Course Link Protector ($itemid) authorized student: $uname:$cdom, course: $cdom\_$cnum");
@@ -1076,6 +1087,9 @@
         $env{'request.linkprot'} = $itemid.$ltitype.':'.$dest;
         $env{'request.linkprotuser'} = $uname.':'.$cdom;
         $env{'request.deeplink.login'} = $dest;
+        if ($exiturl ne '') {
+            $env{'request.linkprotexit'} = $exiturl;
+        }
         my $redirecturl = '/adm/switchserver';
         if ($otherserver ne '') {
             $redirecturl .= '?otherserver='.$otherserver;
@@ -1095,6 +1109,9 @@
                   'origurl'        => $dest,
                   'deeplink.login' => $dest,
                  );
+        if ($exiturl ne '') {
+            $info{'linkprotexit'} = $exiturl; 
+        }
         my $token = &Apache::lonnet::tmpput(\%info,$lonhost);
         $env{'form.token'} = $token;
         $r->internal_redirect('/adm/migrateuser');
Index: loncom/lontrans.pm
diff -u loncom/lontrans.pm:1.39 loncom/lontrans.pm:1.40
--- loncom/lontrans.pm:1.39	Sat Jun 18 02:10:19 2022
+++ loncom/lontrans.pm	Thu Jun 30 21:04:15 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # URL translation for User Files
 #
-# $Id: lontrans.pm,v 1.39 2022/06/18 02:10:19 raeburn Exp $
+# $Id: lontrans.pm,v 1.40 2022/06/30 21:04:15 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -276,8 +276,10 @@
             my %link_info = &Apache::lonnet::tmpget($info{'ltoken'});
             if ($link_info{'linkprot'}) {
                 $info{'linkprot'} = $link_info{'linkprot'};
-                if ($link_info{'linkprotuser'} ne '') {
-                    $info{'linkprotuser'} = $link_info{'linkprotuser'};
+                foreach my $item ('linkprotuser','linkprotexit') {
+                    if ($link_info{$item} ne '') {
+                        $info{$item} = $link_info{$item};
+                    }
                 }
             }
             &Apache::lonnet::tmpdel($info{'ltoken'});
Index: loncom/loncapa_apache.conf
diff -u loncom/loncapa_apache.conf:1.277 loncom/loncapa_apache.conf:1.278
--- loncom/loncapa_apache.conf:1.277	Sat Jun 18 02:10:19 2022
+++ loncom/loncapa_apache.conf	Thu Jun 30 21:04:15 2022
@@ -2,7 +2,7 @@
 ## loncapa_apache.conf -- Apache HTTP LON-CAPA configuration file
 ##
 
-# $Id: loncapa_apache.conf,v 1.277 2022/06/18 02:10:19 raeburn Exp $
+# $Id: loncapa_apache.conf,v 1.278 2022/06/30 21:04:15 raeburn Exp $
 
 #
 # LON-CAPA Section (extensions to httpd.conf daemon configuration)
@@ -880,6 +880,17 @@
   </IfModule>
 </Location>
 
+<Location /adm/linkexit>
+AuthType LONCAPA
+Require valid-user
+PerlAuthzHandler       Apache::lonacc
+SetHandler perl-script
+PerlHandler Apache::lonlinkexit
+ErrorDocument     403 /adm/login
+ErrorDocument     409 /adm/preferences?action=lockwarning
+ErrorDocument     500 /adm/errorhandler
+</Location>
+
 <Location /adm/annotations>
 AuthType LONCAPA
 Require valid-user
Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.1030 doc/loncapafiles/loncapafiles.lpml:1.1031
--- doc/loncapafiles/loncapafiles.lpml:1.1030	Sat Jun 18 02:10:20 2022
+++ doc/loncapafiles/loncapafiles.lpml	Thu Jun 30 21:04:15 2022
@@ -2,7 +2,7 @@
  "http://lpml.sourceforge.net/DTD/lpml.dtd">
 <!-- loncapafiles.lpml -->
 
-<!-- $Id: loncapafiles.lpml,v 1.1030 2022/06/18 02:10:20 raeburn Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.1031 2022/06/30 21:04:15 raeburn Exp $ -->
 
 <!--
 
@@ -6933,6 +6933,16 @@
 <status>works/unverified</status>
 </file>
 <file>
+<source>loncom/auth/lonlinkexit.pm</source>
+<target dist='default'>home/httpd/lib/perl/Apache/lonlinkexit.pm</target>
+<categoryname>handler</categoryname>
+<description>
+logout session launched via deep link and escape iframe and redirect
+(for LTI-protected link and appropriate Link Protection setting in course)
+</description>
+<status>works/unverified</status>
+</file>
+<file>
   <source>loncom/auth/migrateuser.pm</source>
   <target dist='default'>home/httpd/lib/perl/Apache/migrateuser.pm</target>
   <categoryname>handler</categoryname>

Index: loncom/auth/lonlinkexit.pm
+++ loncom/auth/lonlinkexit.pm
# The LearningOnline Network
# Re-launch guidance for deep linked access with username mismatch
#
# $Id: lonlinkexit.pm,v 1.1 2022/06/30 21:04:13 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#

package Apache::lonlinkexit;

use strict;
use lib '/home/httpd/lib/perl/';
use Apache::Constants qw(:common);
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonlocal;
use LONCAPA;
use CGI::Cookie();

sub handler {
    my $r = shift;

    my $handle = &Apache::lonnet::check_for_valid_session($r);
    my ($exiturl,$deeplinktarget);
    if ($handle ne '') {
        my $lonidsdir=$r->dir_config('lonIDsDir');
        &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);
        if ($env{'request.deeplink.login'}) {
            if ($env{'request.deeplink.target'} ne '') {
                $deeplinktarget = $env{'request.deeplink.target'};
            }
            if ($env{'request.linkprotexit'} =~ m{^https?://}) {
                $exiturl = $env{'request.linkprotexit'};
                &js_escape(\$exiturl);
            }
        }
        if (unlink("$lonidsdir/$handle.id")) {
            if (($env{'user.linkedenv'} =~ /^[a-f0-9]+_linked$/) &&
                (-l "$lonidsdir/$env{'user.linkedenv'}.id") &&
                (readlink("$lonidsdir/$env{'user.linkedenv'}.id") eq "$lonidsdir/$handle.id")) {
                unlink("$lonidsdir/$env{'user.linkedenv'}.id");
            }
        }
        my %temp=('logout' => time);
        my $ip = &Apache::lonnet::get_requestor_ip();
        &Apache::lonnet::put('email_status',\%temp);
        &Apache::lonnet::log($env{'user.domain'},
                             $env{'user.name'},
                             $env{'user.home'},
                             "Logout $ip");
        #expire the cookies
        my %cookies=CGI::Cookie->parse($r->header_in('Cookie'));
        foreach my $name (keys(%cookies)) {
            next unless ($name =~ /^lon(|S|Link|Pub)ID$/);
            my $c = new CGI::Cookie(-name    => $name,
                                    -value   => '',
                                    -expires => '-10y',);
            $r->headers_out->add('Set-cookie' => $c);
        }
    }
    if (!$Apache::lonlocal::lh) {
        &Apache::lonlocal::get_language_handle($r);
    }
    &Apache::loncommon::content_type($r,'text/html');
    $r->send_http_header;
    return OK if $r->header_only;

    my ($msg,$js);
    $msg = '<p>'.&mt('Expired any existing session').'</p>';
    my $args = {'only_body' => 1};
    if ($exiturl) {
        $js = <<ENDJS;
<script type="text/javascript">
// <![CDATA[
\$(document).ready( function() {
    setTimeout(function() {
        if (window.self !== window.top) {
            window.top.location.href = '$exiturl';
        } else {
            document.location.href = '$exiturl';
        }
    },100);
});
// ]]>
</script>
ENDJS
        $msg .= '<p>'.&mt('Redirecting ...').'</p>';
    }

    $r->print(&Apache::loncommon::start_page('Session removed',$js,{'only_body' => 1}));
    $r->print($msg);
    $r->print(&Apache::loncommon::end_page());
    return OK;
}

1;


More information about the LON-CAPA-cvs mailing list