[LON-CAPA-cvs] cvs: loncom /auth lonauth.pm migrateuser.pm /interface loncommon.pm

raeburn raeburn at source.lon-capa.org
Sat Aug 7 16:49:11 EDT 2021


raeburn		Sat Aug  7 20:49:11 2021 EDT

  Modified files:              
    /loncom/auth	lonauth.pm migrateuser.pm 
    /loncom/interface	loncommon.pm 
  Log:
  - Bug 6907 Content in a course can be set to be deep-link only.
    Enforce link protection for lti-based or key-based access control.
  
  
-------------- next part --------------
Index: loncom/auth/lonauth.pm
diff -u loncom/auth/lonauth.pm:1.163 loncom/auth/lonauth.pm:1.164
--- loncom/auth/lonauth.pm:1.163	Tue May  4 18:47:37 2021
+++ loncom/auth/lonauth.pm	Sat Aug  7 20:49:10 2021
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # User Authentication Module
 #
-# $Id: lonauth.pm,v 1.163 2021/05/04 18:47:37 raeburn Exp $
+# $Id: lonauth.pm,v 1.164 2021/08/07 20:49:10 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -393,8 +393,34 @@
             my $dest = '/adm/roles';
             if ($env{'form.firsturl'} ne '') {
                 $dest = $env{'form.firsturl'};
-                if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
-                    &Apache::lonnet::appenv({'request.deeplink.login' => $env{'form.firsturl'}}); 
+                if (($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) &&
+                    ($env{'request.course.id'})) {
+                    my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+                    my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+                    my $symb = &Apache::loncommon::symb_from_tinyurl($env{'form.firsturl'},$cnum,$cdom);
+                    if ($symb) {
+                        my $buffer;
+                        if ($r->header_in('Content-length') > 0) {
+                            $r->read($buffer,$r->header_in('Content-length'),0);
+                        }
+                        my %form;
+                        foreach my $pair (split(/&/,$buffer)) {
+                            my ($name,$value) = split(/=/,$pair);
+                            $value =~ tr/+/ /;
+                            $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
+                            $form{$name}=$value;
+                        }
+                        &set_deeplink_login(%form);
+                    } else {
+                        $r->print(
+                                  $start_page
+                                 .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
+                                 .'<p>'.&mt('Please [_1]log out[_2] first, and then try your access again',
+                                            '<a href="/adm/logout">','</a>')
+                                 .'</p>'
+                                 .$end_page);
+                        return OK;
+                    }
                 }
             }
             $r->print(
@@ -684,11 +710,11 @@
             }
             if ($form{'linkprot'}) {
                 $env{'request.linkprot'} = $form{'linkprot'};
-            } elsif ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
-                if ($form{'linkkey'}) {
-                    $env{'request.linkkey'} = $form{'linkkey'};
-                }
-                $env{'request.deeplink.login'} = $form{'firsturl'};
+            } elsif ($form{'linkkey'}) {
+                $env{'request.linkkey'} = $form{'linkkey'};
+            }
+            if ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
+                &set_deeplink_login(%form);
             }
             $r->internal_redirect($switchto);
         } else {
@@ -715,12 +741,11 @@
                 }
                 if ($form{'linkprot'}) {
                     $env{'request.linkprot'} = $form{'linkprot'};
-                } elsif ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
-                    if ($form{'linkkey'}) {
-                        $env{'request.linkkey'} = $form{'linkkey'};
-                    }
-                    $env{'request.deeplink.login'} = $form{'firsturl'};
-
+                } elsif ($form{'linkkey'}) {
+                    $env{'request.linkkey'} = $form{'linkkey'};
+                }
+                if ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
+                    &set_deeplink_login(%form);
                 }
                 $r->internal_redirect($switchto);
             } else {
@@ -755,11 +780,11 @@
                          undef,\%form);
                 if ($form{'linkprot'}) {
                     $env{'request.linkprot'} = $form{'linkprot'};
-                } elsif ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
-                    if ($form{'linkkey'}) {
-                        $env{'request.linkkey'} = $form{'linkkey'};
-                    }
-                    $env{'request.deeplink.login'} = $form{'firsturl'};
+                } elsif ($form{'linkkey'}) {
+                    $env{'request.linkkey'} = $form{'linkkey'};
+                }
+                if ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
+                    &set_deeplink_login(%form);
                 }
                 $r->internal_redirect('/adm/switchserver?otherserver='.$unloaded.'&origurl='.$firsturl);
                 return OK;
@@ -773,15 +798,20 @@
             my ($linkprotector,$uri) = split(/:/,$form{'linkprot'},2);
             if ($linkprotector) {
                 $extra_env = {'user.linkprotector' => $linkprotector,
-                              'user.linkproturi'   => $uri,};
+                              'user.linkproturi'   => $uri};
             }
-        } elsif ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
-            if ($form{'linkkey'}) {
-                $extra_env = {'user.deeplinkkey' => $form{'linkkey'},
-                              'user.keyedlinkuri' => $form{'firsturl'},
-                              'request.deeplink.login' => $form{'firsturl'}};
-            } else {
-                $extra_env = {'request.deeplink.login' => $form{'firsturl'}};
+        } elsif ($form{'linkkey'}) {
+            $extra_env = {'user.deeplinkkey' => $form{'linkkey'},
+                          'user.keyedlinkuri' => $form{'firsturl'}};
+        }
+        if ($form{'firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
+            &set_deeplink_login(%form);
+            if ($env{'request.deeplink.login'}) {
+                if (ref($extra_env) eq 'HASH') {
+                    %{$extra_env} = ( %{$extra_env}, 'request.deeplink.login' => $form{'firsturl'} );
+                } else {
+                    $extra_env = {'request.deeplink.login' => $form{'firsturl'}};
+                }
             }
         }
         &success($r,$form{'uname'},$form{'udom'},$authhost,$firsturl,$extra_env,
@@ -790,6 +820,37 @@
     }
 }
 
+sub set_deeplink_login {
+    my (%form) = @_;
+    if ($form{'firsturl'} =~ m{^/tiny/($match_domain)/\w+$}) {
+        my $cdom = $1;
+        my ($cnum,$symb) = &Apache::loncommon::symb_from_tinyurl($form{'firsturl'},'',$cdom);
+        if ($symb) {
+            my $disallow;
+            my $deeplink = &Apache::lonnet::EXT("resource.0.deeplink",$symb);
+            if ($deeplink ne '') {
+                my ($state,$others,$listed,$scope,$protect) = split(/,/,$deeplink);
+                if (($protect ne 'none') && ($protect ne '')) {
+                    my ($acctype,$item) = split(/:/,$protect);
+                    if (($acctype eq 'ltic') || ($acctype eq 'ltid')) {
+                         unless ($form{'linkprot'} eq $protect) {
+                             $disallow = 1;
+                         }
+                    } elsif ($acctype eq 'key') {
+                        unless (form{'linkkey'} eq $item) {
+                            $disallow = 1;
+                        }
+                    }
+                }
+            }
+            unless ($disallow) {
+                $env{'request.deeplink.login'} = $form{'firsturl'};
+            }
+        }
+    }
+    return;
+}
+
 sub check_can_host {
     my ($r,$form,$authhost,$domdesc) = @_;
     return unless (ref($form) eq 'HASH');
Index: loncom/auth/migrateuser.pm
diff -u loncom/auth/migrateuser.pm:1.50 loncom/auth/migrateuser.pm:1.51
--- loncom/auth/migrateuser.pm:1.50	Tue May  4 18:47:37 2021
+++ loncom/auth/migrateuser.pm	Sat Aug  7 20:49:10 2021
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Starts a user off based of an existing token.
 #
-# $Id: migrateuser.pm,v 1.50 2021/05/04 18:47:37 raeburn Exp $
+# $Id: migrateuser.pm,v 1.51 2021/08/07 20:49:10 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -711,9 +711,6 @@
 						     $handle);
             if ($data{'linkprot'} ne '') {
                 my ($linkprotector,$deeplink) = split(/:/,$data{'linkprot'},2);
-                if ($deeplink ne '') {
-                    &Apache::lonnet::appenv({'request.deeplink.login' => $deeplink});
-                }
                 if ($env{'user.linkprotector'}) {
                     my @protectors = split(/,/,$env{'user.linkprotector'});
                     unless (grep(/^\Q$linkprotector\E$/, at protectors)) {
@@ -734,19 +731,19 @@
                 } else {
                     &Apache::lonnet::appenv({'user.linkproturi' => $deeplink});
                 }
-            } elsif ($data{'deeplink.login'}) {
+            } elsif ($data{'linkkey'}) {
                 my $deeplink = $data{'deeplink.login'};
-                if ($data{'linkkey'}) {
-                    my $linkkey = $data{'linkkey'};
-                    if ($env{'user.deeplinkkey'}) {
-                        my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
-                        unless (grep(/^\Q$linkkey\E$/, at linkkeys)) {
-                            push(@linkkeys,$linkkey);
-                            &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
-                        }
-                    } else {
-                        &Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
+                my $linkkey = $data{'linkkey'};
+                if ($env{'user.deeplinkkey'}) {
+                    my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
+                    unless (grep(/^\Q$linkkey\E$/, at linkkeys)) {
+                        push(@linkkeys,$linkkey);
+                        &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
                     }
+                } else {
+                    &Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
+                }
+                if ($deeplink) { 
                     if ($env{'user.keyedlinkuri'}) {
                         my @keyeduris = split(/,/,$env{'user.keyedlinkuri'});
                         unless (grep(/^\Q$deeplink\E$/, at keyeduris)) {
@@ -757,6 +754,8 @@
                         &Apache::lonnet::appenv({'user.keyedlinkuri' => $deeplink});
                     }
                 }
+            }
+            if ($data{'deeplink.login'}) {
                 &Apache::lonnet::appenv({'request.deeplink.login' => $data{'deeplink.login'}});
             }
             if ($data{'lti.login'}) {
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1363 loncom/interface/loncommon.pm:1.1364
--- loncom/interface/loncommon.pm:1.1363	Wed Aug  4 19:59:10 2021
+++ loncom/interface/loncommon.pm	Sat Aug  7 20:49:11 2021
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1363 2021/08/04 19:59:10 raeburn Exp $
+# $Id: loncommon.pm,v 1.1364 2021/08/07 20:49:11 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -9188,29 +9188,41 @@
     my ($cnum,$cdom) = @_;
     my $login_symb;
     if ($env{'request.deeplink.login'}) {
-        if ($env{'request.deeplink.login'} =~ m{^\Q/tiny/$cdom/\E(\w+)$}) {
-            my $key = $1;
-            my ($tinyurl,$login);
-            my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key);
-            if (defined($cached)) {
-                $tinyurl = $result;
-            } else {
-                my $configuname = &Apache::lonnet::get_domainconfiguser($cdom);
-                my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname);
-                if ($currtiny{$key} ne '') {
-                    $tinyurl = $currtiny{$key};
-                    &Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600);
-                }
+        $login_symb = &symb_from_tinyurl($env{'request.deeplink.login'},$cnum,$cdom);
+    }
+    return $login_symb;
+}
+
+sub symb_from_tinyurl {
+    my ($url,$cnum,$cdom) = @_;
+    if ($url =~ m{^\Q/tiny/$cdom/\E(\w+)$}) {
+        my $key = $1;
+        my ($tinyurl,$login);
+        my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key);
+        if (defined($cached)) {
+            $tinyurl = $result;
+        } else {
+            my $configuname = &Apache::lonnet::get_domainconfiguser($cdom);
+            my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname);
+            if ($currtiny{$key} ne '') {
+                $tinyurl = $currtiny{$key};
+                &Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600);
             }
-            if ($tinyurl ne '') {
-                my ($cnumreq,$posslogin) = split(/\&/,$tinyurl);
-                if ($cnumreq eq $cnum) {
-                    $login_symb = $posslogin;
-                }
+        }
+        if ($tinyurl ne '') {
+            my ($cnumreq,$symb) = split(/\&/,$tinyurl);
+            if (wantarray) {
+                return ($cnumreq,$symb);
+            } elsif ($cnumreq eq $cnum) {
+                return $symb;
             }
         }
     }
-    return $login_symb;
+    if (wantarray) {
+        return ();
+    } else {
+        return;
+    }
 }
 
 sub wishlist_window {


More information about the LON-CAPA-cvs mailing list