--- loncom/homework/daxesave.pm 2015/12/03 20:40:27 1.1 +++ loncom/homework/daxesave.pm 2023/08/23 20:43:34 1.6 @@ -1,7 +1,7 @@ # The LearningOnline Network # Convert and save a problem from Daxe. # -# $Id: daxesave.pm,v 1.1 2015/12/03 20:40:27 damieng Exp $ +# $Id: daxesave.pm,v 1.6 2023/08/23 20:43:34 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -28,8 +28,9 @@ ### package Apache::daxesave; +use strict; -use Apache::Constants; +use Apache::Constants qw(:common); use Apache::lonnet; use Try::Tiny; use File::Copy; @@ -41,45 +42,71 @@ use Apache::xml_to_loncapa; sub handler { my $request = shift; - my $path = $env{'form.path'}; # should be in the form "/daxeopen/priv/..." + $request->content_type('text/plain'); + + # path should be in the form "/daxeopen/priv/..." + # or ^/daxeopen/uploaded/[^/]+/[^/]+/.*html?$ + my $path = $env{'form.path'}; $path =~ s/^\/daxeopen//; - my $allowed; - my ($ownername,$ownerdom,$ownerhome) = - &Apache::lonnet::constructaccess($path, 'setpriv'); - if (($ownername ne '') && ($ownerdom ne '') && ($ownerhome ne '')) { - unless ($ownerhome eq 'no_host') { - my @hosts = &Apache::lonnet::current_machine_ids(); - if (grep(/^\Q$ownerhome\E$/,@hosts)) { - $allowed = 1; + my $allowed = 0; + if ($path =~ /^\/priv/) { + my ($ownername,$ownerdom,$ownerhome) = + &Apache::lonnet::constructaccess($path, 'setpriv'); + if (($ownername ne '') && ($ownerdom ne '') && ($ownerhome ne '')) { + unless ($ownerhome eq 'no_host') { + my @hosts = &Apache::lonnet::current_machine_ids(); + if (grep(/^\Q$ownerhome\E$/,@hosts)) { + $allowed = 1; + } + } + } + } elsif ($path =~ m|^/uploaded/[^/]+/[^/]+/|) { + if ($env{'user.name'} ne '' && $env{'user.domain'} ne '' && $env{'request.course.id'}) { + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + if ($path =~ m|^/uploaded/\Q$cdom\E/\Q$cnum\E/| && $path !~ /\.\./) { + if (&Apache::lonnet::allowed('mdc', $env{'request.course.id'})) { + $allowed = 1; + } } } } unless ($allowed) { - $request->log_reason("Unauthorized path: $path", $path); - return HTTP_NOT_ACCEPTABLE; + $request->log_reason("Unauthorized path: $path", $path); + $request->print("error\nUnauthorized path: $path"); + $request->status(403); + return OK; } my $newpath = &Apache::lonnet::filelocation('', $path); my $contents = $env{'form.file'}; - try { - $contents = &Apache::xml_to_loncapa::convert_file($contents); - } catch { - $request->print("error\nconvert failed for $path: $_"); - return OK; - }; + my $mode; + if ($path =~ /\.(task|problem|exam|quiz|assess|survey|library|xml|html|htm|xhtml|xhtm)$/) { + try { + $contents = &Apache::xml_to_loncapa::convert_file($contents); + } catch { + $request->print("error\nconvert failed for $path: $_"); + return OK; + }; + $mode = '>:encoding(UTF-8)'; + } else { + $mode = '>'; + } my $filebak = $newpath.".bak"; if (-e $newpath) { copy($newpath, $filebak); # errors ignored } - open my $out, '>:encoding(UTF-8)', $newpath; - print $out $contents; - close $out; - - $request->print("ok\n"); + if (open(my $out, $mode, $newpath)) { + print $out $contents; + close $out; + $request->print("ok\n"); + } else { + $request->print("error\nFailed to open file to save $path"); + } return OK; }