[system] / branches / rel-2-3-dev / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / FileXfer.pm Repository:
ViewVC logotype

View of /branches/rel-2-3-dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/FileXfer.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2000 - (download) (as text) (annotate)
Wed May 5 00:53:13 2004 UTC (9 years ago) by sh002i
Original Path: trunk/webwork2/lib/WeBWorK/ContentGenerator/Instructor/FileXfer.pm
File size: 10802 byte(s)
added support for upload/download/delete of scoring files

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/FileXfer.pm,v 1.3 2004/03/23 01:15:58 sh002i Exp $
    5 #
    6 # This program is free software; you can redistribute it and/or modify it under
    7 # the terms of either: (a) the GNU General Public License as published by the
    8 # Free Software Foundation; either version 2, or (at your option) any later
    9 # version, or (b) the "Artistic License" which comes with this package.
   10 #
   11 # This program is distributed in the hope that it will be useful, but WITHOUT
   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
   14 # Artistic License for more details.
   15 ################################################################################
   16 
   17 package WeBWorK::ContentGenerator::Instructor::FileXfer;
   18 use base qw(WeBWorK::ContentGenerator::Instructor);
   19 
   20 =head1 NAME
   21 
   22 WeBWorK::ContentGenerator::Instructor::FileXfer - transfer course files from/to
   23 client
   24 
   25 =cut
   26 
   27 use strict;
   28 use warnings;
   29 use Apache::Constants qw(:common REDIRECT DONE);
   30 use CGI qw();
   31 
   32 sub pre_header_initialize {
   33   my ($self) = @_;
   34   my $r = $self->r;
   35   my $ce = $r->ce;
   36   my $authz = $r->authz;
   37 
   38   my $userID = $r->param("user");
   39 
   40   my ($type, $action) = ("", "");
   41   if (defined $r->param("deleteDef"))           { $type = "def";         $action = "delete";   }
   42   if (defined $r->param("downloadDef"))         { $type = "def";         $action = "download"; }
   43   if (defined $r->param("uploadDef"))           { $type = "def";         $action = "upload";   }
   44   if (defined $r->param("deleteClasslist"))     { $type = "classlist";   $action = "delete";   }
   45   if (defined $r->param("downloadClasslist"))   { $type = "classlist";   $action = "download"; }
   46   if (defined $r->param("uploadClasslist"))     { $type = "classlist";   $action = "upload";   }
   47   if (defined $r->param("deleteScoringFile"))   { $type = "scoringFile"; $action = "delete";   }
   48   if (defined $r->param("downloadScoringFile")) { $type = "scoringFile"; $action = "download"; }
   49   if (defined $r->param("uploadScoringFile"))   { $type = "scoringFile"; $action = "upload";   }
   50 
   51   # make sure we have permission to do what we want to do
   52   if ($type eq "def") {
   53     unless ($authz->hasPermissions($userID, "modify_set_def_files")) {
   54       $self->{submitError} = "You are not authorized to modify the list of set definition files.";
   55       return;
   56     }
   57   } elsif ($type eq "classlist") {
   58     unless ($authz->hasPermissions($userID, "modify_classlist_files")) {
   59       $self->{submitError} = "You are not authorized to modify the list of classlist files.";
   60       return;
   61     }
   62   } elsif ($type eq "scoringFile") {
   63     unless ($authz->hasPermissions($userID, "modify_scoring_files")) {
   64       $self->{submitError} = "You are not authorized to modify the list of scoring files.";
   65       return;
   66     }
   67   }
   68 
   69   # call handler for the action we want to perform
   70   if ($action eq "delete") {
   71     $self->handleDelete($type);
   72   } elsif ($action eq "download") {
   73     $self->handleDownload($type);
   74   } elsif ($action eq "upload") {
   75     $self->handleUpload($type);
   76   }
   77 }
   78 
   79 sub handleDelete {
   80   my ($self, $type) = @_;
   81   my $r = $self->r;
   82   my $ce = $r->ce;
   83 
   84   my (@fileList, $selectParam, $dir);
   85   if ($type eq "classlist") {
   86     @fileList = $self->getCSVList;
   87     $selectParam = "classlist";
   88     $dir = $ce->{courseDirs}->{templates};
   89   } elsif ($type eq "def") {
   90     @fileList = $self->getDefList;
   91     $selectParam = "def";
   92     $dir = $ce->{courseDirs}->{templates};
   93   } elsif ($type eq "scoringFile") {
   94     @fileList = $self->getScoringFileList;
   95     $selectParam = "scoringFile";
   96     $dir = $ce->{courseDirs}->{scoring};
   97   } else {
   98     die "handleDelete() doesn't know what to do with file type $type!";
   99   }
  100 
  101   # get file name
  102   my $fileToDelete = $r->param($selectParam);
  103   unless ($fileToDelete) {
  104     $self->{submitError} = "No file selected for deletion.";
  105     return;
  106   }
  107 
  108   # FIXME: FOR THE LOVE OF GOD, ADD SECURITY CHECKS!!!!!!
  109   # (actually I think it's not such a big deal, since we're checking the
  110   # tainted input against a finite set of files that we know are okay to
  111   # delete)
  112 
  113   # make sure it's in the file list
  114   unless (grep { $_ eq $fileToDelete } @fileList) {
  115     $self->{submitError} = "File \"$fileToDelete\" not found in file list.";
  116     return;
  117   }
  118 
  119   # (at this point we know the filename isn't dangerous)
  120 
  121   # delete it
  122   unlink "$dir/$fileToDelete";
  123 }
  124 
  125 sub handleDownload {
  126   my ($self, $type) = @_;
  127   my $r = $self->r;
  128   my $ce = $r->ce;
  129 
  130   my (@fileList, $selectParam, $dir);
  131   if ($type eq "classlist") {
  132     @fileList = $self->getCSVList;
  133     $selectParam = "classlist";
  134     $dir = $ce->{courseDirs}->{templates};
  135   } elsif ($type eq "def") {
  136     @fileList = $self->getDefList;
  137     $selectParam = "def";
  138     $dir = $ce->{courseDirs}->{templates};
  139   } elsif ($type eq "scoringFile") {
  140     @fileList = $self->getScoringFileList;
  141     $selectParam = "scoringFile";
  142     $dir = $ce->{courseDirs}->{scoring};
  143   } else {
  144     die "handleDownload() doesn't know what to do with file type $type!";
  145   }
  146 
  147   # get file name
  148   my $fileToDownload = $r->param($selectParam);
  149   unless ($fileToDownload) {
  150     $self->{submitError} = "No file selected for download.";
  151     return;
  152   }
  153 
  154   # make sure it's in the file list
  155   unless (grep { $_ eq $fileToDownload } @fileList) {
  156     $self->{submitError} = "File \"$fileToDownload\" not found in file list.";
  157     return;
  158   }
  159 
  160   # set the file to sent:
  161   $self->{sendFile} = {
  162     source => "$dir/$fileToDownload",
  163     type => "text/plain",
  164     name => $fileToDownload,
  165   };
  166 }
  167 
  168 sub handleUpload {
  169   my ($self, $type) = @_;
  170   my $r = $self->r;
  171   my $ce = $r->ce;
  172 
  173   my (@fileList, $uploadParam, $uploadNameParam, $ext, $destDir);
  174   if ($type eq "classlist") {
  175     @fileList = $self->getCSVList;
  176     $uploadParam = "newClasslist";
  177     $uploadNameParam = "newClasslistName";
  178     $ext = ".lst";
  179     $destDir = $ce->{courseDirs}->{templates};
  180   } elsif ($type eq "def") {
  181     @fileList = $self->getDefList;
  182     $uploadParam = "newDef";
  183     $uploadNameParam = "newDefName";
  184     $ext = ".def";
  185     $destDir = $ce->{courseDirs}->{templates};
  186   } elsif ($type eq "scoringFile") {
  187     @fileList = $self->getScoringFileList;
  188     $uploadParam = "newScoringFile";
  189     $uploadNameParam = "newScoringFileName";
  190     $ext = ".csv";
  191     $destDir = $ce->{courseDirs}->{scoring};
  192   }
  193 
  194   # get upload ID and hash
  195   my $uploadIDHash = $r->param($uploadParam);
  196   unless ($uploadIDHash) {
  197     $self->{submitError} = "No file selected for upload.";
  198     return;
  199   }
  200   my ($id, $hash) = split /\s+/, $uploadIDHash;
  201 
  202   #warn "upload param contains $uploadIDHash\n";
  203   #warn "upload ID is $id\n";
  204   #warn "upload hash is $hash\n";
  205 
  206   # retrieve upload from upload cache
  207   my $upload = WeBWorK::Upload->retrieve($id, $hash,
  208     dir => $ce->{webworkDirs}->{uploadCache}
  209   );
  210 
  211   # determine what to call the resulting file
  212   my $fileName = $r->param($uploadNameParam) || $upload->filename;
  213 
  214   # tack on the file extension if it's not already there
  215   $fileName .= $ext unless $fileName =~ m/$ext$/;
  216 
  217   # does the file name have the path separator in it?
  218   die "illegal character in upload name: \"/\". (no hacking!)" if $fileName =~ m|/|;
  219 
  220   # does a file already exist with that name?
  221   if (grep { $_ eq $fileName } @fileList) {
  222     $self->{submitError} = "A file named \"$fileName\" exists. Either remove it, or chose a different name for your upload.";
  223     return;
  224   }
  225 
  226   $upload->disposeTo("$destDir/$fileName");
  227 }
  228 
  229 sub body {
  230   my ($self) = @_;
  231   my $r = $self->r;
  232   my $authz = $r->authz;
  233 
  234   my $userID = $r->param("user");
  235 
  236   return CGI::em("You are not authorized to access the Instructor tools.")
  237     unless $authz->hasPermissions($userID, "access_instructor_tools");
  238 
  239   # if we needed to get either of these lists earlier, use the cached copy
  240   # otherwise, get them from the filesystem
  241   #my $classlistsRef = $self->{classlists} || [ $self->getCSVList ];
  242   #my $setDefsRef    = $self->{setDefs}    || [ $self->getDefList ];
  243   my $classlistsRef     = [ $self->getCSVList         ];
  244   my $setDefsRef        = [ $self->getDefList         ];
  245   my $scoringFileRef    = [ $self->getScoringFileList ];
  246 
  247   print CGI::p(<<EOT);
  248 Use the tools below to modify course files. Set definition files and classlist
  249 files are only used for importing and exporting set and user data.
  250 EOT
  251 
  252   print CGI::table({-border=>1},
  253     CGI::Tr({-valign=>"top"},
  254       CGI::td({},
  255         CGI::p("Set Definition Files"),
  256         CGI::startform("POST", $r->uri, "multipart/form-data"),
  257         $self->hidden_authen_fields,
  258         CGI::scrolling_list(
  259           -name => "def",
  260           -values => $setDefsRef,
  261           -size => 8,
  262           -multiple => 0,
  263         ), CGI::br(),
  264         CGI::submit("deleteDef", "Delete"),
  265         CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")),
  266         CGI::br(),
  267         CGI::submit("downloadDef", "Download"),
  268         CGI::br(),
  269         CGI::p("Upload New Set Definition File:"),
  270         CGI::filefield(
  271           -name => "newDef",
  272           -size => 30,
  273         ), CGI::br(),
  274         "Use name:", CGI::textfield("newDefName", "", 30), CGI::br(),
  275         CGI::submit("uploadDef", "Upload Set Definition File"),
  276         CGI::endform(),
  277       ),
  278       CGI::td({},
  279         CGI::p("Classlist Files"),
  280         CGI::startform("POST", $r->uri, "multipart/form-data"),
  281         $self->hidden_authen_fields,
  282         CGI::scrolling_list(
  283           -name => "classlist",
  284           -values => $classlistsRef,
  285           -size => 8,
  286           -multiple => 0,
  287         ), CGI::br(),
  288         CGI::submit("deleteClasslist", "Delete"),
  289         CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")),
  290         CGI::br(),
  291         CGI::submit("downloadClasslist", "Download"), CGI::br(),
  292         CGI::p("Upload New Classlist File:"),
  293         CGI::filefield(
  294           -name => "newClasslist",
  295           -size => 30,
  296         ), CGI::br(),
  297         "Use name:", CGI::textfield("newClasslistName", "", 30), CGI::br(),
  298         CGI::submit("uploadClasslist", "Upload Classlist File"),
  299         CGI::endform(),
  300       ),
  301     ),
  302     CGI::Tr({-valign=>"top"},
  303       CGI::td({},
  304         CGI::p("Scoring Files"),
  305         CGI::startform("POST", $r->uri, "multipart/form-data"),
  306         $self->hidden_authen_fields,
  307         CGI::scrolling_list(
  308           -name => "scoringFile",
  309           -values => $scoringFileRef,
  310           -size => 8,
  311           -multiple => 0,
  312         ), CGI::br(),
  313         CGI::submit("deleteScoringFile", "Delete"),
  314         CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")),
  315         CGI::br(),
  316         CGI::submit("downloadScoringFile", "Download"),
  317         CGI::br(),
  318         CGI::p("Upload New Scoring File:"),
  319         CGI::filefield(
  320           -name => "newScoringFile",
  321           -size => 30,
  322         ), CGI::br(),
  323         "Use name:", CGI::textfield("newScoringFileName", "", 30), CGI::br(),
  324         CGI::submit("uploadScoringFile", "Upload Scoring File"),
  325         CGI::endform(),
  326       ),
  327     ),
  328   );
  329 
  330   return "";
  331 }
  332 
  333 1;
  334 
  335 __END__
  336 
  337 =head1 AUTHOR
  338 
  339 Written by Sam Hathaway, sh002i (at) math.rochester.edu
  340 
  341 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9