t/modules/authz_core.t (320 lines of code) (raw):
use strict;
use warnings FATAL => 'all';
use Apache::Test;
use Apache::TestRequest;
use Apache::TestUtil qw(t_write_file);
use File::Spec;
# test RequireAll/RequireAny containers and AuthzMerging
plan tests => 168 + 14*24,
need need_lwp,
need_module('mod_authn_core'),
need_module('mod_authz_core'),
need_module('mod_authz_host'),
need_module('mod_authz_groupfile'),
need_min_apache_version('2.3.6');
my $text = '';
sub check
{
my $rc = shift;
my $path = shift;
my @args;
foreach my $e (@_) {
if ($e =~ /user/) {
push @args, username => $e, password => $e;
}
else {
push @args, "X-Allowed$e" => 'yes';
}
}
my $res = GET "/authz_core/$path", @args;
my $got = $res->code;
print "# got $got, expected $rc [$text: $path @_]\n";
ok($got == $rc);
}
sub write_htaccess
{
my $path = shift;
my $merging = shift || "";
my $container = shift || "";
$text = "$path $merging $container @_";
my $need_auth;
my $content = "";
$content .= "AuthMerging $merging\n" if $merging;
if ($container) {
$content .= "<Require$container>\n";
}
foreach (@_) {
my $req = $_;
my $not = "";
if ($req =~ s/^\!//) {
$not = 'not';
}
if ($req =~ /all/) {
$content .= "Require $not $req\n";
}
elsif ($req =~ /user/) {
# 'group' is correct, see comment about mod_authany below
$content .= "Require $not group $req\n";
$need_auth = 1;
}
else {
$content .= "Require $not env allowed$req\n";
}
}
if ($container) {
$content .= "</Require$container>\n";
}
if ($need_auth) {
$content .= "AuthType basic\n";
$content .= "AuthName basic1\n";
$content .= "AuthUserFile basic1\n";
$content .= "AuthGroupFile groups1\n";
}
my $file = File::Spec->catfile(Apache::Test::vars('documentroot'),
"/authz_core/$path/.htaccess");
t_write_file($file, $content);
}
# create some users (username == password)
my $basic_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'basic1');
t_write_file($basic_file, << 'EOF' );
user1:NYSYdf7MU5KpU
user2:KJ7Yxzr1VVzAI
user3:xnpSvZ2iqti/c
EOF
# mod_authany overrides the 'user' provider, so we can't check users directly :-(
# create some groups instead:
my $group_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'groups1');
t_write_file($group_file, << 'EOF' );
user1:user1
user2:user2
user3:user3
EOF
write_htaccess("a/", undef, undef);
check(200, "a/");
check(200, "a/", 1);
check(200, "a/", 2);
check(200, "a/", 1, 2);
check(200, "a/", 3);
write_htaccess("a/", undef, undef, "user1");
check(401, "a/");
check(200, "a/", "user1");
check(401, "a/", "user2");
write_htaccess("a/", undef, "Any", 1, 2);
check(403, "a/");
check(200, "a/", 1);
check(200, "a/", 2);
check(200, "a/", 1, 2);
check(403, "a/", 3);
write_htaccess("a/b/", undef, "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "Off", "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "Or", "Any", 2, 3);
check(403, "a/b/");
check(200, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "And", "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 1, 2);
check(200, "a/b/", 1, 3);
check(200, "a/b/", 2, 3);
write_htaccess("a/b/", undef, "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 2, 3);
check(403, "a/b/", 1, 3);
write_htaccess("a/b/", "Off", "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 2, 3);
check(403, "a/b/", 1, 3);
write_htaccess("a/b/", "Or", "All", 3, 4);
check(403, "a/b/");
check(200, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 2, 3);
check(200, "a/b/", 3, 4);
check(403, "a/b/", 3);
check(403, "a/b/", 4);
write_htaccess("a/b/", "And", "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(403, "a/b/", 1, 2);
check(403, "a/b/", 1, 3);
check(200, "a/b/", 2, 3);
write_htaccess("a/", undef, "All", 1, "!2");
check(403, "a/");
check(200, "a/", 1);
check(403, "a/", 2);
check(403, "a/", 1, 2);
check(403, "a/", 3);
write_htaccess("a/b/", undef, "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "Off", "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "Or", "Any", 3, 4);
check(403, "a/b/");
check(200, "a/b/", 1);
check(403, "a/b/", 1, 2);
check(200, "a/b/", 1, 2, 3);
check(200, "a/b/", 1, 2, 4);
check(200, "a/b/", 4);
write_htaccess("a/b/", "And", "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(403, "a/b/", 1, 2);
check(200, "a/b/", 1, 3);
check(403, "a/b/", 2, 3);
# should not inherit AuthMerging And from a/b/
write_htaccess("a/b/c/", undef, "Any", 4);
check(403, "a/b/c/", 1, 3);
check(200, "a/b/c/", 4);
check(200, "a/b/c/", 1, 2, 4);
write_htaccess("a/b/", undef, "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 2, 3);
check(403, "a/b/", 1, 3);
write_htaccess("a/b/", "Off", "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 2, 3);
check(403, "a/b/", 1, 3);
write_htaccess("a/b/", "Or", "All", 3, 4);
check(403, "a/b/");
check(200, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 2, 3);
check(200, "a/b/", 3, 4);
check(403, "a/b/", 3);
check(403, "a/b/", 4);
write_htaccess("a/b/", "And", "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(403, "a/b/", 1, 2);
check(403, "a/b/", 1, 3);
check(403, "a/b/", 2, 3);
write_htaccess("a/", undef, "All", 1, 2);
check(403, "a/");
check(403, "a/", 1);
check(403, "a/", 2);
check(200, "a/", 1, 2);
write_htaccess("a/b/", undef, "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "Off", "Any", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(200, "a/b/", 2);
check(200, "a/b/", 3);
write_htaccess("a/b/", "Or", "Any", 3, 4);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(200, "a/b/", 1, 2);
check(200, "a/b/", 3);
check(200, "a/b/", 4);
write_htaccess("a/b/", "And", "Any", 3, 4);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(403, "a/b/", 4);
check(403, "a/b/", 1, 2);
check(200, "a/b/", 1, 2, 3);
check(200, "a/b/", 1, 2, 4);
check(403, "a/b/", 1, 3, 4);
write_htaccess("a/b/", undef, "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 2, 3);
check(403, "a/b/", 1, 3);
write_htaccess("a/b/", "Off", "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(200, "a/b/", 2, 3);
check(403, "a/b/", 1, 3);
write_htaccess("a/b/", "Or", "All", 3, 4);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(403, "a/b/", 4);
check(403, "a/b/", 2, 3);
check(200, "a/b/", 3, 4);
check(200, "a/b/", 1, 2);
write_htaccess("a/b/", "And", "All", 2, 3);
check(403, "a/b/");
check(403, "a/b/", 1);
check(403, "a/b/", 2);
check(403, "a/b/", 3);
check(403, "a/b/", 1, 2);
check(403, "a/b/", 1, 3);
check(403, "a/b/", 2, 3);
check(200, "a/b/", 1, 2, 3);
#
# To test merging of a mix of user and non-user authz providers,
# we should test all orders.
#
# helper function to get all permutations of an array
# returns array of references
sub permutations
{
my @results = [shift];
foreach my $el (@_) {
my @new_results;
foreach my $arr (@results) {
my $len = scalar(@{$arr});
foreach my $i (0 .. $len) {
my @new = @{$arr};
splice @new, $i, 0, $el;
push @new_results, \@new;
}
}
@results = @new_results;
}
return @results;
}
my @perms = permutations(qw/user1 user2 1 2/);
foreach my $p (@perms) {
write_htaccess("a/", undef, "All", @{$p});
check(403, "a/");
check(403, "a/", 1);
check(403, "a/", "user1");
check(401, "a/", 1, 2);
check(401, "a/", 1, 2, "user1");
check(401, "a/", 1, 2, "user3");
check(403, "a/", 1, "user1");
write_htaccess("a/", undef, "Any", @{$p});
check(401, "a/");
check(200, "a/", 1);
check(200, "a/", "user1");
check(401, "a/", "user3");
check(200, "a/", 1, 2);
check(200, "a/", 1, "user1");
check(200, "a/", 1, "user3");
}