Diff for /loncom/lti/ltiauth.pm between versions 1.1 and 1.5

version 1.1, 2017/12/06 01:53:56 version 1.5, 2018/01/12 20:42:38
Line 36  use Apache::lonlocal; Line 36  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon;  use Apache::loncommon;
 use Apache::lonacc;  use Apache::lonacc;
   use LONCAPA::ltiutils;
   
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
Line 141  sub handler { Line 142  sub handler {
 # (b) from tail of requested URL (after /adm/lti) if it has format of a symb    # (b) from tail of requested URL (after /adm/lti) if it has format of a symb  
 # (c) from tail of requested URL (after /adm/lti) if it has format of a map   # (c) from tail of requested URL (after /adm/lti) if it has format of a map 
 # (d) from tail of requested URL (after /adm/lti) if it has format /domain/courseID  # (d) from tail of requested URL (after /adm/lti) if it has format /domain/courseID
 # (e) from tail of requested URL (after /adm/lti) if it has format /tiny/domain/...  # (e) from tail of requested URL (after /adm/lti) if it has format /tiny/domain/\w+
 # i.e., a shortened URL (see bug #6400) -- not implemented yet.     #     i.e., a shortened URL (see bug #6400).
 # (f) same as user's domain   # (f) same as user's domain 
 #  #
 # Request invalid if custom_coursedomain is defined and is inconsistent with  # Request invalid if custom_coursedomain is defined and is inconsistent with
Line 180  sub handler { Line 181  sub handler {
                 $symb = $tail;                  $symb = $tail;
                 $symb =~ s{^/+}{};                  $symb =~ s{^/+}{};
             }              }
 #FIXME Need to handle encrypted URLs   #FIXME Need to handle encrypted URLs
         } elsif ($tail =~ m{^/($match_domain)/($match_courseid)$}) {          } elsif ($tail =~ m{^/($match_domain)/($match_courseid)$}) {
             ($urlcdom,$urlcnum) = ($1,$2);              ($urlcdom,$urlcnum) = ($1,$2);
             if (($cdom ne '') && ($cdom ne $urlcdom)) {              if (($cdom ne '') && ($cdom ne $urlcdom)) {
                 &invalid_request($r,4);                  &invalid_request($r,4);
                 return OK;                  return OK;
             }              }
           } elsif ($tail =~ m{^/tiny/($match_domain)/(\w+)$}) {
               ($urlcdom,my $key) = ($1,$2);
               if (($cdom ne '') && ($cdom ne $urlcdom)) {
                   &invalid_request($r,5);
                   return OK;
               }
               my $tinyurl;
               my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$urlcdom."\0".$key);
               if (defined($cached)) {
                   $tinyurl = $result;
               } else {
                   my $configuname = &Apache::lonnet::get_domainconfiguser($urlcdom);
                   my %currtiny = &Apache::lonnet::get('tiny',[$key],$urlcdom,$configuname);
                   if ($currtiny{$key} ne '') {
                       $tinyurl = $currtiny{$key};
                       &Apache::lonnet::do_cache_new('tiny',$urlcdom."\0".$key,$currtiny{$key},600);
                   }
               }
               if ($tinyurl ne '') {
                   $urlcnum = (split(/\&/,$tinyurl))[0];
               }
         }          }
         if (($cdom eq '') && ($urlcdom ne '')) {           if (($cdom eq '') && ($urlcdom ne '')) { 
             my $cprimary_id = &Apache::lonnet::domain($urlcdom,'primary');              my $cprimary_id = &Apache::lonnet::domain($urlcdom,'primary');
Line 216  sub handler { Line 238  sub handler {
     
     my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider');      my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider');
     unless (keys(%lti) > 0) {      unless (keys(%lti) > 0) {
         &invalid_request($r,5);          &invalid_request($r,6);
         return OK;          return OK;
     }      }
     my %lti_by_key;      my %lti_by_key;
Line 240  sub handler { Line 262  sub handler {
         $protocol = 'https';          $protocol = 'https';
     }      }
   
     my $itemid;      my ($itemid,$consumer_key,$secret,@ltiroles);
     my $key = $params->{'oauth_consumer_key'};      $consumer_key = $params->{'oauth_consumer_key'};
     my @ltiroles;      if (ref($lti_by_key{$consumer_key}) eq 'ARRAY') {
     if (ref($lti_by_key{$key}) eq 'ARRAY') {          foreach my $id (@{$lti_by_key{$consumer_key}}) {
         foreach my $id (@{$lti_by_key{$key}}) {  
             if (ref($lti{$id}) eq 'HASH') {              if (ref($lti{$id}) eq 'HASH') {
                 my $secret = $lti{$id}{'secret'};                  $secret = $lti{$id}{'secret'};
                 my $request = Net::OAuth->request('request token')->from_hash($params,                  my $request = Net::OAuth->request('request token')->from_hash($params,
                                                    request_url => $protocol.'://'.$hostname.$requri,                                                     request_url => $protocol.'://'.$hostname.$requri,
                                                    request_method => $env{'request.method'},                                                     request_method => $env{'request.method'},
Line 265  sub handler { Line 286  sub handler {
 # configuration in LON-CAPA for that LTI Consumer.  # configuration in LON-CAPA for that LTI Consumer.
 #  #
     unless (($itemid) && (ref($lti{$itemid}) eq 'HASH')) {      unless (($itemid) && (ref($lti{$itemid}) eq 'HASH')) {
         &invalid_request($r,6);          &invalid_request($r,7);
         return OK;          return OK;
     }      }
   
Line 273  sub handler { Line 294  sub handler {
 # Determine if nonce in POSTed data has expired.  # Determine if nonce in POSTed data has expired.
 # If unexpired, confirm it has not already been used.  # If unexpired, confirm it has not already been used.
 #  #
     unless (&check_nonce($r,$params->{'oauth_nonce'},$params->{'oauth_timestamp'},$lti{$itemid}{'lifetime'},$cdom)) {      unless (&LONCAPA::ltiutils::check_nonce($params->{'oauth_nonce'},$params->{'oauth_timestamp'},
         &invalid_request($r,7);                                              $lti{$itemid}{'lifetime'},$cdom,$r->dir_config('lonLTIDir'))) {
           &invalid_request($r,8);
         return OK;          return OK;
     }      }
   
Line 310  sub handler { Line 332  sub handler {
 # (b) from tail of requested URL (after /adm/lti) if it has format of a symb  # (b) from tail of requested URL (after /adm/lti) if it has format of a symb
 # (c) from tail of requested URL (after /adm/lti) if it has format of a map  # (c) from tail of requested URL (after /adm/lti) if it has format of a map
 # (d) from tail of requested URL (after /adm/lti) if it has format /domain/courseID  # (d) from tail of requested URL (after /adm/lti) if it has format /domain/courseID
 # (e) from tail of requested URL (after /adm/lti) if it has format /tiny/domain/...  # (e) from tail of requested URL (after /adm/lti) if it has format /tiny/domain/\w+
 # i.e., a shortened URL (see bug #6400) -- not implemented yet.  #     i.e., a shortened URL (see bug #6400).
 #  #
 # If Consumer course included in POSTed data points as a target course which  # If Consumer course included in POSTed data points as a target course which
 # has a format which matches a LON-CAPA courseID, but the course does not  # has a format which matches a LON-CAPA courseID, but the course does not
Line 334  sub handler { Line 356  sub handler {
             if ($consumers{$sourcecrs} =~ /^$match_courseid$/) {              if ($consumers{$sourcecrs} =~ /^$match_courseid$/) {
                 my $crshome = &Apache::lonnet::homeserver($consumers{$sourcecrs},$cdom);                  my $crshome = &Apache::lonnet::homeserver($consumers{$sourcecrs},$cdom);
                 if ($crshome =~ /(con_lost|no_host|no_such_host)/) {                  if ($crshome =~ /(con_lost|no_host|no_such_host)/) {
                     &invalid_request($r,8);                      &invalid_request($r,9);
                     return OK;                      return OK;
                 } else {                  } else {
                     $posscnum = $consumers{$sourcecrs};                      $posscnum = $consumers{$sourcecrs};
Line 346  sub handler { Line 368  sub handler {
     if ($urlcnum ne '') {      if ($urlcnum ne '') {
         if ($posscnum ne '') {          if ($posscnum ne '') {
             if ($posscnum ne $urlcnum) {              if ($posscnum ne $urlcnum) {
                 &invalid_request($r,9);                  &invalid_request($r,10);
                 return OK;                  return OK;
             } else {              } else {
                 $cnum = $posscnum;                  $cnum = $posscnum;
Line 354  sub handler { Line 376  sub handler {
         } else {          } else {
             my $crshome = &Apache::lonnet::homeserver($urlcnum,$cdom);              my $crshome = &Apache::lonnet::homeserver($urlcnum,$cdom);
             if ($crshome =~ /(con_lost|no_host|no_such_host)/) {              if ($crshome =~ /(con_lost|no_host|no_such_host)/) {
                 &invalid_request($r,10);                  &invalid_request($r,11);
                 return OK;                  return OK;
             } else {              } else {
                 $cnum = $urlcnum;                  $cnum = $urlcnum;
Line 426  sub handler { Line 448  sub handler {
 #FIXME Do user creation here.  #FIXME Do user creation here.
                 return OK                  return OK
             } else {              } else {
                 &invalid_request($r,11);                  &invalid_request($r,12);
                 return OK;                  return OK;
             }               } 
         }           } 
     } else {      } else {
         &invalid_request($r,12);          &invalid_request($r,13);
         return OK;          return OK;
     }      }
   
Line 447  sub handler { Line 469  sub handler {
 #FIXME Create a new LON-CAPA course here.  #FIXME Create a new LON-CAPA course here.
             return OK;              return OK;
         } else {          } else {
             &invalid_request($r,13);              &invalid_request($r,14);
             return OK;               return OK; 
         }          }
     }      }
Line 481  sub handler { Line 503  sub handler {
 #FIXME Do self-enrollment here  #FIXME Do self-enrollment here
             return OK;              return OK;
         } else {          } else {
             &invalid_request($r,14);              &invalid_request($r,15);
               return OK;
         }          }
     }      }
   
Line 496  sub handler { Line 519  sub handler {
 # Check if user should be hosted here or switched to another server.  # Check if user should be hosted here or switched to another server.
 #  #
   
     &Apache::lonnet::logthis(" LTI authorized user: $uname:$udom role: $role course: $cnum:$cdom");      &Apache::lonnet::logthis(" LTI authorized user: $uname:$udom role: $role course: $cdom\_$cnum");
     $r->user($uname);      $r->user($uname);
     my ($is_balancer,$otherserver,$hosthere);      my ($is_balancer,$otherserver,$hosthere);
     ($is_balancer,$otherserver) =      ($is_balancer,$otherserver) =
Line 609  sub handler { Line 632  sub handler {
     return OK;      return OK;
 }  }
   
 sub check_nonce {  
     my ($r,$nonce,$timestamp,$lifetime,$domain) = @_;  
     if (($timestamp eq '') || ($timestamp =~ /^\D/) || ($lifetime eq '') || ($lifetime =~ /\D/) || ($domain eq '')) {  
         return 0;  
     }  
     my $now = time;  
     if (($timestamp) && ($timestamp < ($now - $lifetime))) {  
         return 0;  
     }  
     if ($nonce eq '') {  
         return 0;  
     }  
     my $lonltidir = $r->dir_config('lonLTIDir');  
     if (-e "$lonltidir/$domain/$nonce") {  
         return 0;  
     } else {  
         unless (-e "$lonltidir/$domain") {  
             mkdir("$lonltidir/$domain",0755);  
         }    
         if (open(my $fh,'>',"$lonltidir/$domain/$nonce")) {  
             print $fh $now;  
             close($fh);  
         } else {  
             return 0;  
         }  
     }  
     return 1;  
 }  
   
 sub invalid_request {  sub invalid_request {
     my ($r,$num) = @_;      my ($r,$num) = @_;
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');

Removed from v.1.1  
changed lines
  Added in v.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>