Diff for /loncom/publisher/lonupload.pm between versions 1.59 and 1.71

version 1.59, 2011/11/14 00:20:31 version 1.71, 2023/07/23 11:54:56
Line 125  use Apache::File; Line 125  use Apache::File;
 use File::Copy;  use File::Copy;
 use File::Basename;  use File::Basename;
 use Apache::Constants qw(:common :http :methods);  use Apache::Constants qw(:common :http :methods);
 use Apache::loncacc;  
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonnet;  use Apache::lonnet;
 use HTML::Entities();  use HTML::Entities();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use LONCAPA();  use LONCAPA qw(:DEFAULT :match);
   
 my $DEBUG=0;  my $DEBUG=0;
   
Line 151  sub upfile_store { Line 150  sub upfile_store {
           
     chomp($env{'form.upfile'});      chomp($env{'form.upfile'});
       
     my $datatoken=$env{'user.name'}.'_'.$env{'user.domain'}.      my $datatoken;
   '_upload_'.$fname.'_'.time.'_'.$$;      if (($env{'user.name'} =~ /^$match_username$/) && ($env{'user.domain'} =~ /^$match_domain$/)) {
           $datatoken=$env{'user.name'}.'_'.$env{'user.domain'}.
                      '_upload_'.$fname.'_'.time.'_'.$$;
       }
       return if ($datatoken eq '');
     {      {
        my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').         my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
                                    '/tmp/'.$datatoken.'.tmp');                                     '/tmp/'.$datatoken.'.tmp');
Line 162  sub upfile_store { Line 165  sub upfile_store {
 }  }
   
 sub phaseone {  sub phaseone {
     my ($r,$fn,$mode)=@_;      my ($r,$fn,$mode,$uname,$udom)=@_;
     my $action = '/adm/upload';      my $action = '/adm/upload';
     if ($mode eq 'testbank') {      if ($mode eq 'testbank') {
         $action = '/adm/testbank';          $action = '/adm/testbank';
Line 173  sub phaseone { Line 176  sub phaseone {
     # Check for file to be uploaded      # Check for file to be uploaded
     $env{'form.upfile.filename'}=~s/\\/\//g;      $env{'form.upfile.filename'}=~s/\\/\//g;
     $env{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;      $env{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;
       $env{'form.upfile.filename'}=~s/(\s+$|^\s+)//g;
     if (!$env{'form.upfile.filename'}) {      if (!$env{'form.upfile.filename'}) {
         $r->print('<p class="LC_warning">'.&mt('No upload file specified.').'</p>');          $r->print('<p class="LC_warning">'.&mt('No upload file specified.').'</p>'.
                     &earlyout($fn,$uname,$udom));
         return;          return;
     }      }
   
Line 188  sub phaseone { Line 193  sub phaseone {
         $r->print('<p class="LC_warning">'.&mt('Illegal filename.').'</p>');          $r->print('<p class="LC_warning">'.&mt('Illegal filename.').'</p>');
         return;          return;
     }      }
       # Check if quota exceeded
       my $filesize = length($env{'form.upfile'});
       if (!$filesize) {
           $r->print('<p class="LC_warning">'.
                     &mt('Unable to upload [_1]. (size = [_2] bytes)',
                         '<span class="LC_filename">'.$env{'form.upfile.filename'}.'</span>',
                         $filesize).'<br />'.
                     &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'<br />'.
                     '</p>'.
                     &earlyout($fn,$uname,$udom));
           return;
       }
       $filesize = int($filesize/1000); #expressed in kb
       my $output = &Apache::loncommon::excess_filesize_warning($uname,$udom,'author',
                                                                $env{'form.upfile.filename'},$filesize,'upload');
       if ($output) {
           $r->print($output.&earlyout($fn,$uname,$udom));
           return;
       }
   
 # Split part that I can change from the part that I cannot change  # Split part that I can change from the part that I cannot change
     my ($fn1,$fn2)=($fn=~/^(\/priv\/[^\/]+\/[^\/]+\/)(.*)$/);      my ($fn1,$fn2)=($fn=~/^(\/priv\/[^\/]+\/[^\/]+\/)(.*)$/);
   # Check for pattern: .number.extension which is reserved for LON-CAPA versioning. 
   # Check for disallowed characters: #?&%:<>`|, and remove
       if ($fn2 ne '') {
           ($fn2,my $warning) = &check_filename($fn2);
           if ($warning ne '') {
               $r->print($warning);
           }
       }
     # Display additional options for upload      # Display additional options for upload
     # and upload button      # and upload button
     $r->print(      $r->print(
Line 257  sub phasetwo { Line 290  sub phasetwo {
  my $base = &File::Basename::basename($fn);   my $base = &File::Basename::basename($fn);
  my $path = &File::Basename::dirname($fn);   my $path = &File::Basename::dirname($fn);
  $base    = &HTML::Entities::encode($base,'<>&"');   $base    = &HTML::Entities::encode($base,'<>&"');
  my $url  = $path."/".$base;    my $url  = $path."/".$base;
  &Debug($r, "URL is now ".$url);   &Debug($r, "URL is now ".$url);
  my $datatoken=$env{'form.datatoken'};   my $datatoken;
           if ($env{'form.datatoken'} =~ /^$match_username\_$match_domain\_upload_\w*_\d+_\d+$/) {
               $datatoken = $env{'form.datatoken'};
           }
  if (($fn) && ($datatoken)) {   if (($fn) && ($datatoken)) {
             if ($env{'form.cancel'}) {              if ($env{'form.cancel'}) {
                 my $source=$r->dir_config('lonDaemons').'/tmp/'.$datatoken.'.tmp';                  my $source=$r->dir_config('lonDaemons').'/tmp/'.$datatoken.'.tmp';
Line 373  sub check_extension { Line 409  sub check_extension {
                         if ($pathchg) {                          if ($pathchg) {
                             if ($mode eq 'testbank') {                              if ($mode eq 'testbank') {
                                 $returnflag = 'embedded';                                  $returnflag = 'embedded';
                                 $result .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without modifying the references(s).','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';                                  $result .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';
                             }                              }
                         }                          }
                     }                      }
Line 394  sub check_extension { Line 430  sub check_extension {
     return ($result,$returnflag);      return ($result,$returnflag);
 }  }
   
   sub check_filename {
       my ($fname) = @_;
       my $warning;
       if ($fname =~/[#\?&%":<>`|]/) {
           $fname =~s/[#\?&%":<>`|]//g;
           $warning .= '<p class="LC_warning">'
                      .&mt('Removed one or more disallowed characters from filename')
                      .'</p>';
       }
       if ($fname=~ /\.(\d+)\.(\w+)$/) {
           my $num = $1;
           $warning .= '<p class="LC_warning">'
                      .&mt('Bad filename [_1]','<span class="LC_filename">'.$fname.'</span>')
                      .'<br />'
                      .&mt('[_1](name).(number).(extension)[_2] not allowed.','<tt>','</tt>')
                      .'<br />'
                      .&mt('Replacing the [_1].number.[_2] with [_1]_letter.[_2] in requested filename.','<tt>','</tt>')
                      .'</p>';
           if ($num eq '0') {
               $fname =~ s/\.(\d+)(\.\w+)$/_A$2/;
           } else {
               my $letts = '';
               my %digletter = reverse &Apache::lonnet::letter_to_digits();
               if ($num >= 100) {
                   $num = substr($num,-2);
               }
               foreach my $digit (split('',$num)) {
                   $letts .= $digletter{$digit};
               }
               $fname =~ s/\.(\d+)(\.\w+)$/_$letts$2/;
           }
       }
       if ($fname =~/___/) {
           $fname =~s/_+/_/g;
           $warning .= '<p class="LC_warning">'
                       .&mt('Changed ___ to a single _ in filename')
                       .'</p>';
       }
       return ($fname,$warning);
   }
   
 sub phasethree {  sub phasethree {
     my ($r,$fn,$uname,$udom,$mode) = @_;      my ($r,$fn,$uname,$udom,$mode) = @_;
   
Line 407  sub phasethree { Line 484  sub phasethree {
     my $dir_root = $r->dir_config('lonDocRoot').$url_root;      my $dir_root = $r->dir_config('lonDocRoot').$url_root;
     my $path = &File::Basename::dirname($fn);      my $path = &File::Basename::dirname($fn);
     $path =~ s{^\Q$url_root\E}{};      $path =~ s{^\Q$url_root\E}{};
       my $dirpath = $url_root.$path.'/';
       $dirpath=~s{/+}{/}g;
     my $filename = &HTML::Entities::encode($env{'form.filename'},'<>&"');      my $filename = &HTML::Entities::encode($env{'form.filename'},'<>&"');
     my $state = &embedded_form_elems('modify_orightml',$filename,$mode).      my $state = &embedded_form_elems('modify_orightml',$filename,$mode).
                 '<input type="hidden" name="phase" value="four" />';                  '<input type="hidden" name="phase" value="four" />';
Line 417  sub phasethree { Line 496  sub phasethree {
     if ($mode ne 'imsimport' && $mode ne 'testbank') {      if ($mode ne 'imsimport' && $mode ne 'testbank') {
         $result .= '<br /><h3><a href="'.$fn.'">'.          $result .= '<br /><h3><a href="'.$fn.'">'.
                   &mt('View main file').'</a></h3>'.                    &mt('View main file').'</a></h3>'.
                   '<h3><a href="'.$url_root.$path.'">'.                    '<h3><a href="'.$dirpath.'">'.
                   &mt('Back to Directory').'</a></h3><br />';                    &mt('Back to Directory').'</a></h3><br />';
     }      }
     return ($result,$returnflag);      return ($result,$returnflag);
Line 446  sub phasefour { Line 525  sub phasefour {
     my $dir_root = $r->dir_config('lonDocRoot').$url_root;      my $dir_root = $r->dir_config('lonDocRoot').$url_root;
     my $path = &File::Basename::dirname($fn);      my $path = &File::Basename::dirname($fn);
     $path =~ s{^\Q$url_root\E}{};      $path =~ s{^\Q$url_root\E}{};
     $result .= &Apache::loncommon::modify_html_refs($mode,$path,      my $dirpath = $url_root.$path.'/';
                               $uname,$udom,$dir_root);      $dirpath=~s{/+}{/}g;
       my $outcome = 
           &Apache::loncommon::modify_html_refs($mode,$path,$uname,$udom,$dir_root);
       $result .= $outcome;
     if ($mode ne 'imsimport' && $mode ne 'testbank') {      if ($mode ne 'imsimport' && $mode ne 'testbank') {
         $result .= '<br /><h3><a href="'.$fn.'">'.          $result .= '<br /><h3><a href="'.$fn.'">'.
                   &mt('View main file').'</a></h3>'.                    &mt('View main file').'</a></h3>'.
                   '<h3><a href="'.$url_root.$path.'">'.                    '<h3><a href="'.$dirpath.'">'.
                   &mt('Back to Directory').'</a></h3><br />';                    &mt('Back to Directory').'</a></h3><br />';
     }      }
     return $result;      return $result;
 }  }
   
   sub earlyout {
       my ($fn,$uname,$udom) = @_;
       if ($fn =~ m{^(/priv/$udom/$uname(?:.*)/)[^/]*}) {
           return &Apache::lonhtmlcommon::actionbox(
                  ['<a href="'.$1.'">'.&mt('Return to Directory').'</a>']);
       }
       return;
   }
   
 # ---------------------------------------------------------------- Main Handler  # ---------------------------------------------------------------- Main Handler
 sub handler {  sub handler {
   
     my $r=shift;      my $r=shift;
     my $javascript = '';      my $javascript = '';
     my $fn=$env{'form.filename'};      my $fn;
       my $warning;
   
     if ($env{'form.filename1'}) {      if ($env{'form.filename1'}) {
        $fn=$env{'form.filename1'}.$env{'form.filename2'};          my $fn1 = $env{'form.filename1'};
           my $fn2 = $env{'form.filename2'};
           $fn2 =~ s/(\s+$|^\s+)//g;
           $fn2 =~ s/\/+/\//g;
           ($fn2,$warning) = &check_filename($fn2);
           $fn = $fn1.$fn2;
       } else {
           $fn = $env{'form.filename'};
     }      }
     $fn=~s/\/+/\//g;      $fn=~s/\/+/\//g;
       if ($fn =~ m{/\.\./}) {
           $warning .= '<p class="LC_warning">'
                      .&mt('Path modified as a result of one or more instances of /../')
                      .'</p>';
           while ($fn =~ m{/\.\./}) {
               $fn =~ s{/[^/]+/\.\./}{/}g;
           }
       }
   
     unless ($fn) {      unless ($fn) {
         $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.          $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
Line 475  sub handler { Line 582  sub handler {
         return HTTP_NOT_FOUND;          return HTTP_NOT_FOUND;
     }      }
   
     my ($uname,$udom)=&Apache::loncacc::constructaccess($fn);      my ($uname,$udom)=&Apache::lonnet::constructaccess($fn);
   
     unless (($uname) && ($udom)) {      unless (($uname) && ($udom)) {
         $r->log_reason($uname.' at '.$udom.          $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
                        ' trying to publish file '.$env{'form.filename'}.                         ' trying to upload file '.$fn.
                        ' - not authorized',                         ' - not authorized',
                        $r->filename);                         $r->filename);
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
Line 517  ENDJS Line 624  ENDJS
     $trailfile =~ s{^/(priv/)}{$londocroot/$1};      $trailfile =~ s{^/(priv/)}{$londocroot/$1};
   
     # Breadcrumbs      # Breadcrumbs
     my $brcrum = [{'href' => &Apache::loncommon::authorspace($fn),      my $text = 'Authoring Space';
                    'text' => 'Construction Space'},      my $href = &Apache::loncommon::authorspace($fn);
       my $crsauthor;
       if ($env{'request.course.id'}) {
           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           if ($href eq "/priv/$cdom/$cnum/") {
               $text = 'Course Authoring Space';
               $crsauthor = 1;
           }
       }
       my $brcrum = [{'href' => $href,
                      'text' => $text},
                   {'href' => '/adm/upload',                    {'href' => '/adm/upload',
                    'text' => 'Upload file to Construction Space'}];                     'text' => 'Upload file to '.$text}];
     $r->print(&Apache::loncommon::start_page('Upload file to Construction Space',      $r->print(&Apache::loncommon::start_page('Upload file to '.$text,
                                              $javascript,                                               $javascript,
                                              {'bread_crumbs' => $brcrum,})                                               {'bread_crumbs' => $brcrum,})
              .&Apache::loncommon::head_subbox(               .&Apache::loncommon::head_subbox(
                 &Apache::loncommon::CSTR_pageheader($trailfile))                  &Apache::loncommon::CSTR_pageheader($trailfile))
     );      );
     
     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {      unless ($crsauthor) {
         $r->print('<p class="LC_info">'          if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
                  .&mt('Co-Author [_1]',$uname.':'.$udom)              $r->print('<p class="LC_info">'
                  .'</p>'                       .&mt('Co-Author [_1]',$uname.':'.$udom)
         );                       .'</p>'
               );
           }
       }
       if ($warning) {
           $r->print($warning);
     }      }
     if ($env{'form.phase'} eq 'four') {      if ($env{'form.phase'} eq 'four') {
         my $output = &phasefour($r,$fn,$uname,$udom,'author');          my $output = &phasefour($r,$fn,$uname,$udom,'author');
Line 544  ENDJS Line 667  ENDJS
  my ($output,$returnflag) = &phasetwo($r,$fn);   my ($output,$returnflag) = &phasetwo($r,$fn);
         $r->print($output);          $r->print($output);
     } else {      } else {
  &phaseone($r,$fn);   &phaseone($r,$fn,undef,$uname,$udom);
     }      }
   
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
     return OK;        return OK;
 }  }
   
 1;  1;

Removed from v.1.59  
changed lines
  Added in v.1.71


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