Skip to content

Commit

Permalink
Item1453: changed the switchboard into a hash, and added allow and de…
Browse files Browse the repository at this point in the history
…ny to support fine control over the HTTP method permitted for different actions (only applies to engines that define a method, such as CGI). Note that this sort of filtering can also be done in Apache.

git-svn-id: http://svn.foswiki.org/trunk@3453 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
CrawfordCurrie authored and CrawfordCurrie committed Apr 16, 2009
1 parent 438f1f2 commit bc145a1
Showing 1 changed file with 134 additions and 51 deletions.
185 changes: 134 additions & 51 deletions core/lib/Foswiki/UI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,119 @@ use strict;

BEGIN {
$Foswiki::cfg{SwitchBoard} ||= {};
$Foswiki::cfg{SwitchBoard}{attach} =
[ 'Foswiki::UI::Attach', 'attach', { attach => 1 } ];
$Foswiki::cfg{SwitchBoard}{changes} =
[ 'Foswiki::UI::Changes', 'changes', { changes => 1 } ];
$Foswiki::cfg{SwitchBoard}{edit} =
[ 'Foswiki::UI::Edit', 'edit', { edit => 1 } ];
$Foswiki::cfg{SwitchBoard}{login} =
[ undef, 'logon', { ( login => 1, logon => 1 ) } ];
$Foswiki::cfg{SwitchBoard}{logon} =
[ undef, 'logon', { ( login => 1, logon => 1 ) } ];
$Foswiki::cfg{SwitchBoard}{manage} =
[ 'Foswiki::UI::Manage', 'manage', { manage => 1 } ];
$Foswiki::cfg{SwitchBoard}{oops} =
[ 'Foswiki::UI::Oops', 'oops_cgi', { oops => 1 } ];
$Foswiki::cfg{SwitchBoard}{preview} =
[ 'Foswiki::UI::Preview', 'preview', { preview => 1 } ];
$Foswiki::cfg{SwitchBoard}{rdiffauth} =
[ 'Foswiki::UI::RDiff', 'diff', { diff => 1 } ];
$Foswiki::cfg{SwitchBoard}{rdiff} =
[ 'Foswiki::UI::RDiff', 'diff', { diff => 1 } ];
$Foswiki::cfg{SwitchBoard}{register} =
[ 'Foswiki::UI::Register', 'register_cgi', { register => 1 } ];
$Foswiki::cfg{SwitchBoard}{rename} =
[ 'Foswiki::UI::Rename', 'rename', { rename => 1 } ];
$Foswiki::cfg{SwitchBoard}{resetpasswd} =
[ 'Foswiki::UI::Passwords', 'resetPassword', { resetpasswd => 1 } ];
$Foswiki::cfg{SwitchBoard}{rest} =
[ 'Foswiki::UI::Rest', 'rest', { rest => 1 } ];
$Foswiki::cfg{SwitchBoard}{save} =
[ 'Foswiki::UI::Save', 'save', { save => 1 } ];
$Foswiki::cfg{SwitchBoard}{search} =
[ 'Foswiki::UI::Search', 'search', { search => 1 } ];
$Foswiki::cfg{SwitchBoard}{statistics} =
[ 'Foswiki::UI::Statistics', 'statistics', { statistics => 1 } ];
$Foswiki::cfg{SwitchBoard}{upload} =
[ 'Foswiki::UI::Upload', 'upload', { upload => 1 } ];
$Foswiki::cfg{SwitchBoard}{viewauth} =
[ 'Foswiki::UI::View', 'view', { view => 1 } ];
$Foswiki::cfg{SwitchBoard}{viewfile} =
[ 'Foswiki::UI::Viewfile', 'viewfile', { viewfile => 1 } ];
$Foswiki::cfg{SwitchBoard}{view} =
[ 'Foswiki::UI::View', 'view', { view => 1 } ];

# package - perl package that contains the method for this request
# function - name of the function in package
# context - hash of context vars to define
# allow - hash of HTTP methods to allow (all others are denied)
# deny - hash of HTTP methods that are denied (all others are allowed)
# 'deny' is not tested if 'allow' is defined
$Foswiki::cfg{SwitchBoard}{attach} = {
package => 'Foswiki::UI::Attach',
function => 'attach',
context => { attach => 1 },
};
$Foswiki::cfg{SwitchBoard}{changes} = {
package => 'Foswiki::UI::Changes',
function => 'changes',
context => { changes => 1 },
};
$Foswiki::cfg{SwitchBoard}{edit} = {
package => 'Foswiki::UI::Edit',
function => 'edit',
context => { edit => 1 },
};
$Foswiki::cfg{SwitchBoard}{login} = {
package => undef,
function => 'logon',
context => { ( login => 1, logon => 1 ) },
};
$Foswiki::cfg{SwitchBoard}{logon} = {
package => undef,
function => 'logon',
context => { ( login => 1, logon => 1 ) },
};
$Foswiki::cfg{SwitchBoard}{manage} = {
package => 'Foswiki::UI::Manage',
function => 'manage',
context => { manage => 1 },
};
$Foswiki::cfg{SwitchBoard}{oops} = {
package => 'Foswiki::UI::Oops',
function => 'oops_cgi',
context => { oops => 1 },
};
$Foswiki::cfg{SwitchBoard}{preview} = {
package => 'Foswiki::UI::Preview',
function => 'preview',
context => { preview => 1 },
};
$Foswiki::cfg{SwitchBoard}{rdiffauth} = {
package => 'Foswiki::UI::RDiff',
function => 'diff',
context => { diff => 1 },
};
$Foswiki::cfg{SwitchBoard}{rdiff} = {
package => 'Foswiki::UI::RDiff',
function => 'diff',
context => { diff => 1 },
};
$Foswiki::cfg{SwitchBoard}{register} = {
package => 'Foswiki::UI::Register',
function => 'register_cgi',
context => { register => 1 },
};
$Foswiki::cfg{SwitchBoard}{rename} = {
package => 'Foswiki::UI::Rename',
function => 'rename',
context => { rename => 1 },
};
$Foswiki::cfg{SwitchBoard}{resetpasswd} = {
package => 'Foswiki::UI::Passwords',
function => 'resetPassword',
context => { resetpasswd => 1 },
};
$Foswiki::cfg{SwitchBoard}{rest} = {
package => 'Foswiki::UI::Rest',
function => 'rest',
context => { rest => 1 },
};
$Foswiki::cfg{SwitchBoard}{save} = {
package => 'Foswiki::UI::Save',
function => 'save',
context => { save => 1 },
allow => { POST => 1 }
};
$Foswiki::cfg{SwitchBoard}{search} = {
package => 'Foswiki::UI::Search',
function => 'search',
context => { search => 1 },
};
$Foswiki::cfg{SwitchBoard}{statistics} = {
package => 'Foswiki::UI::Statistics',
function => 'statistics',
context => { statistics => 1 },
};
$Foswiki::cfg{SwitchBoard}{upload} = {
package => 'Foswiki::UI::Upload',
function => 'upload',
context => { upload => 1 },
};
$Foswiki::cfg{SwitchBoard}{viewauth} = {
package => 'Foswiki::UI::View',
function => 'view',
context => { view => 1 },
};
$Foswiki::cfg{SwitchBoard}{viewfile} = {
package => 'Foswiki::UI::Viewfile',
function => 'viewfile',
context => { viewfile => 1 },
};
$Foswiki::cfg{SwitchBoard}{view} = {
package => 'Foswiki::UI::View',
function => 'view',
context => { view => 1 },
};
}

use Error qw(:try);
Expand Down Expand Up @@ -89,7 +160,7 @@ sub handleRequest {

my $res;
my $dispatcher = $Foswiki::cfg{SwitchBoard}{ $req->action() };
unless ( defined $dispatcher && ref($dispatcher) eq 'ARRAY' ) {
unless ( defined $dispatcher ) {
$res = new Foswiki::Response();
$res->header( -type => 'text/html', -status => '404' );
my $html = CGI::start_html('404 Not Found');
Expand All @@ -102,23 +173,35 @@ sub handleRequest {
$res->print($html);
return $res;
}
my ( $package, $function, $context ) = @$dispatcher;

if ( $package && !$isInitialized{$package} ) {
eval qq(use $package);
if ( $dispatcher->{package} && !$isInitialized{$dispatcher->{package}} ) {
eval qq(use $dispatcher->{package});
die $@ if $@;
$isInitialized{$package} = 1;
$isInitialized{$dispatcher->{package}} = 1;
}

my $sub;
$sub = $package . '::' if $package;
$sub .= $function;
$sub = $dispatcher->{package} . '::' if $dispatcher->{package};
$sub .= $dispatcher->{function};

if ( UNIVERSAL::isa( $Foswiki::engine, 'Foswiki::Engine::CLI' ) ) {
$context->{command_line} = 1;
$dispatcher->{context}->{command_line} = 1;
} elsif ( defined $req->method()
&& (
( defined $dispatcher->{allow}
&& !$dispatcher->{allow}->{$req->method()} )
||
( defined $dispatcher->{deny}
&& $dispatcher->{deny}->{$req->method()} )
)
) {
$res = new Foswiki::Response();
$res->header( -type => 'text/html', -status => '403' );
$res->print($req->method().' denied for '.$req->action());
return $res;
}

$res = execute( $req, \&$sub, %$context );
$res = execute( $req, \&$sub, %{$dispatcher->{context}} );
return $res;
}

Expand Down

0 comments on commit bc145a1

Please sign in to comment.