Added WebGUI::Middleware::WGAccess for .wgaccess-aware static serving on dev servers

This commit is contained in:
Patrick Donelan 2010-04-13 19:33:35 -04:00
parent 82ce3331b7
commit b1ab8287ca
3 changed files with 72 additions and 92 deletions

View file

@ -16,6 +16,9 @@ builder {
config => $wg->config,
error_docs => { 500 => "$root/www/maintenance.html" };
# This one uses the Session object, so it comes after WebGUI::Middleware::Session
enable '+WebGUI::Middleware::WGAccess', config => $wg->config;
# Return the app
$wg;
};

View file

@ -1,92 +0,0 @@
package Plack::Middleware::WGAccess;
use strict;
use warnings;
use base qw/Plack::Middleware::Static/;
use Path::Class 'dir';
=head1 NAME
Plack::Middleware::WGAccess
=head1 DESCRIPTION
Plack Middleware that delivers static files with .wgaccess awareness
=cut
sub _handle_static {
my($self, $env) = @_;
#######################################
# Copied from Plack::Middleware::Static::_handle_static
my $path_match = $self->path or return;
if ($env->{PATH_INFO} =~ m!\.\.[/\\]!) {
return $self->return_403;
}
my $path = do {
my $matched;
local $_ = $env->{PATH_INFO};
if (ref $path_match eq 'CODE') {
$matched = $path_match->($_);
} else {
$matched = $_ =~ $path_match;
}
return unless $matched;
$_;
} or return;
my $docroot = dir($self->root || ".");
my $file = $docroot->file(File::Spec::Unix->splitpath($path));
my $realpath = Cwd::realpath($file->absolute->stringify);
# Is the requested path within the root?
if ($realpath && !$docroot->subsumes($realpath)) {
return $self->return_403;
}
# Does the file actually exist?
if (!$realpath || !-f $file) {
return $self->return_404;
}
# If the requested file present but lacking the permission to read it?
if (!-r $file) {
return $self->return_403;
}
###############################
# Copied from WebGUI::URL::Uploads
my $wgaccess = File::Spec::Unix->catfile($file->dir, '.wgaccess');
if (-e $wgaccess) {
my $fileContents;
open(my $FILE, "<", $wgaccess);
while (my $line = <$FILE>) {
$fileContents .= $line;
}
close($FILE);
my @privs = split("\n", $fileContents);
unless ($privs[1] eq "7" || $privs[1] eq "1") {
my $request = Plack::Request->new( $env );
# my $session = $request->pnotes('wgSession');
unless (defined $session) {
# $session = WebGUI::Session->open($env->{dir_config('WebguiRoot'), $request->dir_config('WebguiConfig'), $request );
}
my $hasPrivs = ($session->var->get("userId") eq $privs[0] || $session->user->isInGroup($privs[1]) || $session->user->isInGroup($privs[2]));
$session->close();
if ($hasPrivs) {
return $self->SUPER::_handle_static($env); # serve statically
}
else {
return $self->return_403;
}
}
} else {
return $self->SUPER::_handle_static($env); # serve statically
}
}
1;

View file

@ -0,0 +1,69 @@
package WebGUI::Middleware::WGAccess;
use strict;
use Plack::App::File;
use parent qw(Plack::Middleware);
use Path::Class 'dir';
=head1 NAME
WebGUI::Middleware::WGAccess - control access to .wgaccess protected uploads
=head1 DESCRIPTION
This is PSGI middleware for WebGUI that delivers static files (uploads) with .wgaccess
awareness.
This middleware should really only be used in development, for production you want
to be serving static files with something a lot faster.
=cut
use Plack::Util::Accessor qw( config );
sub call {
my $self = shift;
my $env = shift;
my $app = $self->app;
my $config = $self->config or die 'Mandatory config parameter missing';
my $uploadsPath = $config->get('uploadsPath');
my $uploadsURL = $config->get('uploadsURL');
my $path = $env->{PATH_INFO};
my $matched = $path =~ s{^\Q$uploadsURL\E/}{};
return $app->($env) unless $matched;
my $root = dir($uploadsPath);
my $file = $root->file(File::Spec::Unix->splitpath($path));
my $wgaccess = File::Spec::Unix->catfile($file->dir, '.wgaccess');
if (-e $wgaccess) {
my $fileContents;
open(my $FILE, "<", $wgaccess);
while (my $line = <$FILE>) {
$fileContents .= $line;
}
close($FILE);
my @privs = split("\n", $fileContents);
unless ($privs[1] eq "7" || $privs[1] eq "1") {
my $session = $env->{'webgui.session'};
my $hasPrivs = ($session->var->get("userId") eq $privs[0] || $session->user->isInGroup($privs[1]) || $session->user->isInGroup($privs[2]));
warn "has: $hasPrivs";
warn $session->var->get("userId");
warn $session->user->isInGroup($privs[1]);
warn $session->user->isInGroup($privs[2]);
if ($hasPrivs) {
$self->{file} ||= Plack::App::File->new;
return $self->{file}->serve_path($env, $file); # serve statically
}
else {
return [403, ['Content-Type' => 'text/plain'], ['Forbidden']];
}
}
}
$self->{file} ||= Plack::App::File->new;
return $self->{file}->serve_path($env, $file); # serve statically
}
1;