File:  [LON-CAPA] / loncom / publisher / lonupload.pm
Revision 1.11: download - view: text, annotated - select for diffs
Mon Aug 5 02:22:56 2002 UTC (21 years, 10 months ago) by foxr
Branches: MAIN
CVS tags: HEAD
Fix bug 59: Uploaded file permissions not correct.

    1: # The LearningOnline Network with CAPA
    2: # Handler to upload files into construction space
    3: #
    4: # $Id: lonupload.pm,v 1.11 2002/08/05 02:22:56 foxr Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: # (Handler to retrieve an old version of a file
   29: #
   30: # (Publication Handler
   31: # 
   32: # (TeX Content Handler
   33: #
   34: # YEAR=2000
   35: # 05/29/00,05/30,10/11 Gerd Kortemeyer)
   36: #
   37: # 11/28,11/29,11/30,12/01,12/02,12/04,12/23 Gerd Kortemeyer
   38: # YEAR=2001
   39: # 03/23 Guy Albertelli
   40: # 03/24,03/29 Gerd Kortemeyer)
   41: #
   42: # 03/31,04/03 Gerd Kortemeyer)
   43: #
   44: # 04/05,04/09,05/25,06/23,06/24,08/22 Gerd Kortemeyer
   45: # 11/29 Matthew Hall
   46: # 12/16 Scott Harrison
   47: #
   48: ###
   49: 
   50: package Apache::lonupload;
   51: 
   52: use strict;
   53: use Apache::File;
   54: use File::Copy;
   55: use Apache::Constants qw(:common :http :methods);
   56: use Apache::loncacc;
   57: use Apache::loncommon();
   58: 
   59: sub upfile_store {
   60:     my $r=shift;
   61: 	
   62:     my $fname=$ENV{'form.upfile.filename'};
   63:     $fname=~s/\W//g;
   64:     
   65:     chop($ENV{'form.upfile'});
   66:   
   67:     my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.
   68: 		  '_upload_'.$fname.'_'.time.'_'.$$;
   69:     {
   70:        my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
   71:                                    '/tmp/'.$datatoken.'.tmp');
   72:        print $fh $ENV{'form.upfile'};
   73:     }
   74:     return $datatoken;
   75: }
   76: 
   77: 
   78: sub phaseone {
   79:    my ($r,$fn,$uname,$udom)=@_;
   80:    $ENV{'form.upfile.filename'}=~s/\\/\//g;
   81:    $ENV{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;
   82:    if ($ENV{'form.upfile.filename'}) {
   83:     $fn=~s/\/[^\/]+$//;
   84:     $fn=~s/([^\/])$/$1\//;
   85:     $fn.=$ENV{'form.upfile.filename'};
   86:     $fn=~s/^\///;
   87:     $fn=~s/(\/)+/\//g;
   88: 
   89:     if (($fn) && ($fn!~/\/$/)) {
   90:       $r->print(
   91:  '<form action=/adm/upload method=post>'.
   92:  '<input type=hidden name=phase value=two>'.
   93:  '<input type=hidden name=datatoken value="'.&upfile_store.'">'.
   94:  'Store uploaded file as '.
   95:  '<input type=text size=50 name=filename value="/priv/'.
   96:   $uname.'/'.$fn.'"><br>'.
   97:  '<input type=submit value="Store"></form>');
   98:       # Check for bad extension and warn user
   99:       if ($fn=~/\.(\w+)$/ && 
  100: 	  (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
  101: 	  $r->print(
  102:  '<font color=red>'.
  103:  'The extension on this file, "'.$1.
  104:  '", is reserved internally by LON-CAPA. <br \>'.
  105:  'Please change the extension.'.
  106:  '</font>');
  107:       } elsif($fn=~/\.(\w+)$/ && 
  108: 	      !defined(&Apache::loncommon::fileembstyle($1))) {
  109: 	  $r->print(
  110:  '<font color=red>'.
  111:  'The extension on this file, "'.$1.
  112:  '", is not recognized by LON-CAPA. <br \>'.
  113:  'Please change the extension.'.
  114:  '</font>');
  115:       }
  116:   } else {
  117:       $r->print('<font color=red>Illegal filename.</font>');
  118:   }
  119:  } else {
  120:      $r->print('<font color=red>No upload file specified.</font>');
  121:  }
  122: }
  123: 
  124: sub phasetwo {
  125:    my ($r,$fn,$uname,$udom)=@_;
  126:    if ($fn=~/^\/priv\/$uname\//) { 
  127:     my $tfn=$fn;
  128:     $tfn=~s/^\/(\~|priv)\/(\w+)//;
  129:     my $target='/home/'.$uname.'/public_html'.$tfn;
  130:     my $datatoken=$ENV{'form.datatoken'};
  131:     if (($fn) && ($datatoken)) {
  132: 	if ((-e $target) && ($ENV{'form.override'} ne 'Yes')) {
  133:            $r->print(
  134:  '<form action=/adm/upload method=post>'.
  135:  'File <tt>'.$fn.'</tt> exists. Overwrite? '.
  136:  '<input type=hidden name=phase value=two>'.
  137:  '<input type=hidden name=filename value="'.$fn.'">'.
  138:  '<input type=hidden name=datatoken value="'.$datatoken.'">'.
  139:  '<input type=submit name=override value="Yes"></form>');
  140:        } else {
  141:            my $source=$r->dir_config('lonDaemons').
  142: 	                             '/tmp/'.$datatoken.'.tmp';
  143:            # Check for bad extension and disallow upload
  144: 	   if ($fn=~/\.(\w+)$/ && 
  145: 	       (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
  146: 	       $r->print(
  147:  'File <tt>'.$fn.'</tt> could not be copied.<br />'.
  148:  '<font color=red>'.
  149:  'The extension on this file is reserved internally by LON-CAPA.'.
  150:  '</font>');
  151: 	   } elsif ($fn=~/\.(\w+)$/ && 
  152: 		    !defined(&Apache::loncommon::fileembstyle($1))) {
  153: 	       $r->print(
  154:  'File <tt>'.$fn.'</tt> could not be copied.<br />'.
  155:  '<font color=red>'.
  156:  'The extension on this file is not recognized by LON-CAPA.'.
  157:  '</font>');
  158: 	   } elsif (copy($source,$target)) {
  159: 	       chmod(0660, $target); # Set permissions to rw-rw---.
  160: 	      $r->print('File copied.');
  161:               $r->print('<p><font size=+2><a href="'.$fn.
  162:                         '">View file</a></font>');
  163: 	   } else {
  164:               $r->print('Failed to copy: '.$!);
  165: 	   }
  166:        }
  167:     } else {
  168:        $r->print(
  169:    '<font size=+1 color=red>Please pick a filename</font><p>');
  170:        &phaseone($r,$fn,$uname,$udom);
  171:     }
  172:   } else {
  173:     $r->print(
  174:    '<font size=+1 color=red>Please pick a filename</font><p>');
  175:     &phaseone($r,$fn,$uname,$udom);
  176:   }
  177: }
  178: 
  179: # ---------------------------------------------------------------- Main Handler
  180: sub handler {
  181: 
  182:   my $r=shift;
  183: 
  184:   my $uname;
  185:   my $udom;
  186: 
  187:   ($uname,$udom)=
  188:     &Apache::loncacc::constructaccess(
  189: 			 $ENV{'form.filename'},$r->dir_config('lonDefDomain'));
  190:   unless (($uname) && ($udom)) {
  191:      $r->log_reason($uname.' at '.$udom.
  192:          ' trying to publish file '.$ENV{'form.filename'}.
  193:          ' - not authorized', 
  194:          $r->filename); 
  195:      return HTTP_NOT_ACCEPTABLE;
  196:   }
  197: 
  198:   my $fn;
  199: 
  200:   if ($ENV{'form.filename'}) {
  201:       $fn=$ENV{'form.filename'};
  202:       $fn=~s/^http\:\/\/[^\/]+\/(\~|priv\/)(\w+)//;
  203:   } else {
  204:      $r->log_reason($ENV{'user.name'}.' at '.$ENV{'user.domain'}.
  205:          ' unspecified filename for upload', $r->filename); 
  206:      return HTTP_NOT_FOUND;
  207:   }
  208: 
  209: # ----------------------------------------------------------- Start page output
  210: 
  211: 
  212:   $r->content_type('text/html');
  213:   $r->send_http_header;
  214: 
  215:   $r->print('<html><head><title>LON-CAPA Construction Space</title></head>');
  216: 
  217:   $r->print(
  218:    '<body bgcolor="#FFFFFF"><img align=right src=/adm/lonIcons/lonlogos.gif>');
  219: 
  220:   
  221:   $r->print('<h1>Upload file to Construction Space</h1>');
  222:   
  223:   if (($uname ne $ENV{'user.name'}) || ($udom ne $ENV{'user.domain'})) {
  224:           $r->print('<h3><font color=red>Co-Author: '.$uname.' at '.$udom.
  225:                '</font></h3>');
  226:   }
  227: 
  228: 
  229:   if ($ENV{'form.phase'} eq 'two') {
  230:       &phasetwo($r,$fn,$uname,$udom);
  231:   } else {
  232:       &phaseone($r,$fn,$uname,$udom);
  233:   }
  234: 
  235:   $r->print('</body></html>');
  236:   return OK;  
  237: }
  238: 
  239: 1;
  240: __END__
  241: 
  242: =head1 NAME
  243: 
  244: Apache::lonupload - upload files into construction space
  245: 
  246: =head1 SYNOPSIS
  247: 
  248: Invoked by /etc/httpd/conf/srm.conf:
  249: 
  250:  <Location /adm/upload>
  251:  PerlAccessHandler       Apache::lonacc
  252:  SetHandler perl-script
  253:  PerlHandler Apache::lonupload
  254:  ErrorDocument     403 /adm/login
  255:  ErrorDocument     404 /adm/notfound.html
  256:  ErrorDocument     406 /adm/unauthorized.html
  257:  ErrorDocument	  500 /adm/errorhandler
  258:  </Location>
  259: 
  260: =head1 INTRODUCTION
  261: 
  262: This module uploads a file sitting on a client computer into 
  263: library server construction space.
  264: 
  265: This is part of the LearningOnline Network with CAPA project
  266: described at http://www.lon-capa.org.
  267: 
  268: =head1 HANDLER SUBROUTINE
  269: 
  270: This routine is called by Apache and mod_perl.
  271: 
  272: =over 4
  273: 
  274: =item *
  275: 
  276: Initialize variables
  277: 
  278: =item *
  279: 
  280: Start page output
  281: 
  282: =item *
  283: 
  284: output relevant interface phase (phaseone or phasetwo)
  285: 
  286: =item *
  287: 
  288: (phase one is to specify upload file; phase two is to handle conditions
  289: subsequent to specification--like overwriting an existing file)
  290: 
  291: =back
  292: 
  293: =head1 OTHER SUBROUTINES
  294: 
  295: =over 4
  296: 
  297: =item *
  298: 
  299: phaseone() : Interface for specifying file to upload.
  300: 
  301: =item *
  302: 
  303: phasetwo() : Interface for handling post-conditions about uploading (such
  304: as overwriting an existing file).
  305: 
  306: =item *
  307: 
  308: upfile_store() : Store contents of uploaded file into temporary space.  Invoked
  309: by phaseone subroutine.
  310: 
  311: =back
  312: 
  313: =cut

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