Parent Directory
|
Revision Log
added special handling of ' Top' directory for problem templates now selecting top will show files in top directory not literal "Top" directory fixes bug #630
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.8 2004/07/08 14:53:47 gage 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 if (defined $r->param("deleteTemplateFile")) { $type = "templateFile"; $action = "delete"; } 51 if (defined $r->param("downloadTemplateFile")){ $type = "templateFile"; $action = "download"; } 52 if (defined $r->param("uploadTemplateFile")) { $type = "templateFile"; $action = "upload"; } 53 54 55 # make sure we have permission to do what we want to do 56 if ($type eq "def") { 57 unless ($authz->hasPermissions($userID, "modify_set_def_files")) { 58 $self->addbadmessage(CGI::p("You are not authorized to modify the list of set definition files.")); 59 return; 60 } 61 } elsif ($type eq "classlist") { 62 unless ($authz->hasPermissions($userID, "modify_classlist_files")) { 63 $self->addbadmessage(CGI::p("You are not authorized to modify the list of classlist files.")); 64 return; 65 } 66 } elsif ($type eq "scoringFile") { 67 unless ($authz->hasPermissions($userID, "modify_scoring_files")) { 68 $self->addbadmessage(CGI::p("You are not authorized to modify the list of scoring files.")); 69 return; 70 } 71 } elsif ($type eq "templateFile") { 72 unless ($authz->hasPermissions($userID, "modify_problem_template_files")) { 73 $self->addbadmessage(CGI::p("You are not authorized to modify the list of problem template files.")); 74 return; 75 } 76 } 77 78 # call handler for the action we want to perform 79 if ($action eq "delete") { 80 $self->handleDelete($type); 81 } elsif ($action eq "download") { 82 $self->handleDownload($type); 83 } elsif ($action eq "upload") { 84 $self->handleUpload($type); 85 } 86 } 87 88 sub handleDelete { 89 my ($self, $type) = @_; 90 my $r = $self->r; 91 my $ce = $r->ce; 92 93 my (@fileList, $selectParam, $dir); 94 if ($type eq "classlist") { 95 @fileList = $self->getCSVList; 96 $selectParam = "classlist"; 97 $dir = $ce->{courseDirs}->{templates}; 98 } elsif ($type eq "def") { 99 @fileList = $self->getDefList; 100 $selectParam = "def"; 101 $dir = $ce->{courseDirs}->{templates}; 102 } elsif ($type eq "scoringFile") { 103 @fileList = $self->getScoringFileList; 104 $selectParam = "scoringFile"; 105 $dir = $ce->{courseDirs}->{scoring}; 106 } elsif ($type eq "templateFile") { 107 my $templateSubDir = $r->param("templateSubDir"); 108 @fileList = $self->getTemplateFileList($templateSubDir); 109 $selectParam = "templateFile"; 110 $dir = $ce->{courseDirs}->{templates}."/$templateSubDir"; 111 } else { 112 die "handleDelete() doesn't know what to do with file type $type!"; 113 } 114 115 # get file name 116 my $fileToDelete = $r->param($selectParam); 117 unless ($fileToDelete) { 118 $self->addbadmessage(CGI::p("No file selected for deletion.")); 119 return; 120 } 121 122 # FIXME: FOR THE LOVE OF GOD, ADD SECURITY CHECKS!!!!!! 123 # (actually I think it's not such a big deal, since we're checking the 124 # tainted input against a finite set of files that we know are okay to 125 # delete) 126 127 # make sure it's in the file list 128 unless (grep { $_ eq $fileToDelete } @fileList) { 129 $self->addbadmessage(CGI::p("File \"$fileToDelete\" not found in file list.")); 130 return; 131 } 132 133 # (at this point we know the filename isn't dangerous) 134 135 # delete it 136 unlink "$dir/$fileToDelete"; 137 $self->addgoodmessage("$dir/$fileToDelete has been deleted."); 138 } 139 140 sub handleDownload { 141 my ($self, $type) = @_; 142 my $r = $self->r; 143 my $ce = $r->ce; 144 145 my (@fileList, $selectParam, $dir); 146 if ($type eq "classlist") { 147 @fileList = $self->getCSVList; 148 $selectParam = "classlist"; 149 $dir = $ce->{courseDirs}->{templates}; 150 } elsif ($type eq "def") { 151 @fileList = $self->getDefList; 152 $selectParam = "def"; 153 $dir = $ce->{courseDirs}->{templates}; 154 } elsif ($type eq "scoringFile") { 155 @fileList = $self->getScoringFileList; 156 $selectParam = "scoringFile"; 157 $dir = $ce->{courseDirs}->{scoring}; 158 } elsif ($type eq "templateFile") { 159 my $templateSubDir = $r->param("templateSubDir"); 160 @fileList = $self->getTemplateFileList($templateSubDir); 161 $selectParam = "templateFile"; 162 $dir = $ce->{courseDirs}->{templates}; 163 $dir = $ce->{courseDirs}->{templates}."/$templateSubDir"; 164 } else { 165 die "handleDownload() doesn't know what to do with file type $type!"; 166 } 167 168 # get file name 169 my $fileToDownload = $r->param($selectParam); 170 unless ($fileToDownload) { 171 $self->addbadmessage(CGI::p("No file selected for download.")); 172 return; 173 } 174 175 # make sure it's in the file list 176 unless (grep { $_ eq $fileToDownload } @fileList) { 177 $self->addbadmessage(CGI::p("File \"$fileToDownload\" not found in file list.")); 178 return; 179 } 180 181 # set the file to sent: 182 $self->reply_with_file("text/plain", "$dir/$fileToDownload", $fileToDownload, 0); 183 } 184 185 sub handleUpload { 186 my ($self, $type) = @_; 187 my $r = $self->r; 188 my $ce = $r->ce; 189 190 my (@fileList, $uploadParam, $uploadNameParam, $ext, $destDir); 191 if ($type eq "classlist") { 192 @fileList = $self->getCSVList; 193 $uploadParam = "newClasslist"; 194 $uploadNameParam = "newClasslistName"; 195 $ext = ".lst"; 196 $destDir = $ce->{courseDirs}->{templates}; 197 } elsif ($type eq "def") { 198 @fileList = $self->getDefList; 199 $uploadParam = "newDef"; 200 $uploadNameParam = "newDefName"; 201 $ext = ".def"; 202 $destDir = $ce->{courseDirs}->{templates}; 203 } elsif ($type eq "scoringFile") { 204 @fileList = $self->getScoringFileList; 205 $uploadParam = "newScoringFile"; 206 $uploadNameParam = "newScoringFileName"; 207 $ext = ".csv"; 208 $destDir = $ce->{courseDirs}->{scoring}; 209 } elsif ($type eq "templateFile") { 210 my $templateSubDir = $r->param("templateSubDir"); 211 @fileList = $self->getTemplateFileList($templateSubDir); 212 $uploadParam = "newTemplateFile"; 213 $uploadNameParam = "newTemplateFileName"; 214 $ext = ".pg"; 215 $destDir = $ce->{courseDirs}->{templates}."/$templateSubDir"; 216 } 217 218 # get upload ID and hash 219 my $uploadIDHash = $r->param($uploadParam); 220 unless ($uploadIDHash) { 221 $self->addbadmessage(CGI::p("No file selected for upload.")); 222 return; 223 } 224 my ($id, $hash) = split /\s+/, $uploadIDHash; 225 226 #warn "upload param contains $uploadIDHash\n"; 227 #warn "upload ID is $id\n"; 228 #warn "upload hash is $hash\n"; 229 230 # retrieve upload from upload cache 231 my $upload = WeBWorK::Upload->retrieve($id, $hash, 232 dir => $ce->{webworkDirs}->{uploadCache} 233 ); 234 235 # determine what to call the resulting file 236 my $fileName = $r->param($uploadNameParam) || $upload->filename; 237 238 # tack on the file extension if it's not already there 239 $fileName .= $ext unless $fileName =~ m/$ext$/; 240 241 # does the file name have the path separator in it? 242 die "illegal character in upload name: \"/\". (no hacking!)" if $fileName =~ m|/|; 243 244 # does a file already exist with that name? 245 if (grep { $_ eq $fileName } @fileList) { 246 $self->addbadmessage(CGI::p("A file named \"$fileName\" exists. Either remove it, or chose a different name for your upload.")); 247 return; 248 } 249 250 $upload->disposeTo("$destDir/$fileName"); 251 $self->addgoodmessage("$destDir/$fileName has been uploaded."); 252 } 253 254 sub body { 255 my ($self) = @_; 256 my $r = $self->r; 257 my $authz = $r->authz; 258 259 my $userID = $r->param("user"); 260 261 return CGI::div({class=>"ResultsWithError"}, "You are not authorized to access the Instructor tools.") 262 unless $authz->hasPermissions($r->param("user"), "access_instructor_tools"); 263 264 # if we needed to get either of these lists earlier, use the cached copy 265 # otherwise, get them from the filesystem 266 #my $classlistsRef = $self->{classlists} || [ $self->getCSVList ]; 267 #my $setDefsRef = $self->{setDefs} || [ $self->getDefList ]; 268 269 my $templateSubDir = $r->param("templateSubDir"); 270 $templateSubDir = "" if $templateSubDir and $templateSubDir eq ' Top'; #deal with special value for top directory 271 my $classlistsRef = [ $self->getCSVList ]; 272 my $setDefsRef = [ $self->getDefList ]; 273 my $scoringFileRef = [ $self->getScoringFileList ]; 274 my $templateDirRef = [ $self->getTemplateDirList ]; 275 my $templateFileRef = [ $self->getTemplateFileList($templateSubDir) ]; 276 277 278 279 print CGI::p(<<EOT); 280 Use the tools below to modify course files. Set definition files and classlist 281 files are only used for importing and exporting set and user data. 282 EOT 283 284 print CGI::table({-border=>1, -nowrap=>1}, 285 CGI::Tr({-valign=>"top"}, 286 $authz->hasPermissions($userID, "modify_set_def_files") ? 287 CGI::td({}, 288 CGI::p("Set Definition Files"), 289 CGI::startform("POST", $r->uri, "multipart/form-data"), 290 $self->hidden_authen_fields, 291 CGI::scrolling_list( 292 -name => "def", 293 -values => $setDefsRef, 294 -size => 8, 295 -multiple => 0, 296 ), CGI::br(), 297 CGI::submit("deleteDef", "Delete"), 298 CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")), 299 CGI::br(), 300 CGI::submit("downloadDef", "Download"), 301 CGI::br(), 302 CGI::p("Upload New Set Definition File:"), 303 CGI::filefield( 304 -name => "newDef", 305 -size => 30, 306 ), CGI::br(), 307 "Use name:", CGI::textfield("newDefName", "", 30), CGI::br(), 308 CGI::submit("uploadDef", "Upload Set Definition File"), 309 CGI::endform(), 310 ) : CGI::td({}, CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to modify the list of set definition files."))), 311 $authz->hasPermissions($userID, "modify_classlist_files") ? 312 CGI::td({}, 313 CGI::p("Classlist Files"), 314 CGI::startform("POST", $r->uri, "multipart/form-data"), 315 $self->hidden_authen_fields, 316 CGI::scrolling_list( 317 -name => "classlist", 318 -values => $classlistsRef, 319 -size => 8, 320 -multiple => 0, 321 ), CGI::br(), 322 CGI::submit("deleteClasslist", "Delete"), 323 CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")), 324 CGI::br(), 325 CGI::submit("downloadClasslist", "Download"), CGI::br(), 326 CGI::p("Upload New Classlist File:"), 327 CGI::filefield( 328 -name => "newClasslist", 329 -size => 30, 330 ), CGI::br(), 331 "Use name:", CGI::textfield("newClasslistName", "", 30), CGI::br(), 332 CGI::submit("uploadClasslist", "Upload Classlist File"), 333 CGI::endform(), 334 ) : CGI::td({}, CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to modify the list of classlist files."))), 335 ), 336 CGI::Tr({-valign=>"top"}, 337 $authz->hasPermissions($userID, "modify_scoring_files") ? 338 CGI::td({}, 339 CGI::p("Scoring Files"), 340 CGI::startform("POST", $r->uri, "multipart/form-data"), 341 $self->hidden_authen_fields, 342 CGI::scrolling_list( 343 -name => "scoringFile", 344 -values => $scoringFileRef, 345 -size => 8, 346 -multiple => 0, 347 ), CGI::br(), 348 CGI::submit("deleteScoringFile", "Delete"), 349 CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")), 350 CGI::br(), 351 CGI::submit("downloadScoringFile", "Download"), 352 CGI::br(), 353 CGI::p("Upload New Scoring File:"), 354 CGI::filefield( 355 -name => "newScoringFile", 356 -size => 30, 357 ), CGI::br(), 358 "Use name:", CGI::textfield("newScoringFileName", "", 30), CGI::br(), 359 CGI::submit("uploadScoringFile", "Upload Scoring File"), 360 CGI::endform(), 361 ) : CGI::td({}, CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to modify the list of scoring files."))), 362 $authz->hasPermissions($userID, "modify_problem_template_files") ? 363 CGI::td({}, 364 CGI::p("Problem Template Files"), 365 CGI::startform("POST", $r->uri, "multipart/form-data"), 366 $self->hidden_authen_fields, 367 CGI::popup_menu( 368 -name => "templateSubDir", 369 -values => $templateDirRef, 370 -default => ( defined($templateSubDir) )? $templateSubDir:' Top', 371 ),CGI::br(), 372 CGI::submit('UpdateList','Update List'),CGI::br(), 373 CGI::scrolling_list( 374 -name => "templateFile", 375 -values => $templateFileRef, 376 -size => 8, 377 -multiple => 0, 378 ), CGI::br(), 379 CGI::submit("deleteTemplateFile", "Delete"), 380 CGI::font({-color=>"red"}, CGI::em("Delete is not undoable!")), 381 CGI::br(), 382 CGI::submit("downloadTemplateFile", "Download"), 383 CGI::br(), 384 CGI::p("Upload New Problem Template File:"), 385 CGI::filefield( 386 -name => "newTemplateFile", 387 -size => 30, 388 ), CGI::br(), 389 "Use name:", CGI::textfield("newTemplateFileName", "", 30), CGI::br(), 390 CGI::submit("uploadTemplateFile", "Upload Problem Template File"), 391 CGI::endform(), 392 ) : CGI::td({}, CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to modify the list of problem template files."))), 393 394 ), 395 396 ); 397 398 return ""; 399 } 400 401 1; 402 403 __END__ 404 405 =head1 AUTHOR 406 407 Written by Sam Hathaway, sh002i (at) math.rochester.edu 408 409 =cut
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |