use strict; use warnings FATAL => 'all'; use Apache::Test; use Apache::TestRequest; use Apache::TestUtil qw(t_write_file); use File::Spec; # test the possibility of doing authz by user id or envvar in conjunction # with the different AuthTypes Apache::TestRequest::user_agent(keep_alive => 1); my @headers = qw(WWW-Authenticate Authentication-Info Location); my %do_tests = ( basic => 11, digest => 11, form => 16, ); my $tests = 2; # AuthzSendForbiddenOnFailure tests foreach my $t (keys %do_tests) { $tests += $do_tests{$t}; } plan tests => $tests, need need_lwp, need_module('mod_authn_core'), need_module('mod_authz_core'), need_module('mod_authn_file'), need_module('mod_authz_host'), need_min_apache_version('2.3.7'); foreach my $t (sort keys %do_tests) { if (!have_module("mod_auth_$t")) { skip("skipping mod_auth_$t tests") for (1 .. $do_tests{$t}); delete $do_tests{$t}; } } write_htpasswd(); # the auth type we are currently testing my $type; foreach my $t (qw/basic digest/) { next unless exists $do_tests{$t}; $type = $t; my $url = "/authz/$type/index.html"; { my $response = GET $url; ok($response->code, 401, "$type: no user to authenticate and no env to authorize"); } { # bad pass my $response = GET $url, username => "u$type", password => 'foo'; ok($response->code, 401, "$type: u$type:foo not found"); } { # authenticated my $response = GET $url, username => "u$type", password => "p$type"; ok($response->code, 200, "$type: u$type:p$type found"); } { # authorized by env my $response = GET $url, 'X-Allowed' => 'yes'; ok($response->code, 200, "$type: authz by envvar"); check_headers($response, 200); } { # authorized by env / with error my $response = GET "$url.foo", 'X-Allowed' => 'yes'; ok($response->code, 404, "$type: not found"); check_headers($response, 404); } } # # Form based authentication works a bit differently # if (exists $do_tests{form} && !have_module("mod_session_cookie")) { skip("skipping mod_auth_form tests (mod_session_cookie required)") for (1 .. $do_tests{form}); } elsif (exists $do_tests{form}) { $type = 'form'; my $url = "/authz/$type/index.html"; my $login_form_url='/authz/login.html'; my $login_url='/authz/form/dologin.html'; my @params = ( reset => 1, cookie_jar => {}, requests_redirectable => 0 ); Apache::TestRequest::user_agent(@params); { my $response = GET $url; ok($response->code, 302, "$type: access without user/env should redirect with 302"); my $loc = $response->header("Location"); if (defined $loc && $loc =~ m{^http://[^/]+(/.*)$}) { $loc = $1; } ok($loc, "/authz/login.html", "form: login without user/env should redirect to login form"); } { Apache::TestRequest::user_agent(@params); # bad pass my $response = POST $login_url, content => "httpd_username=uform&httpd_password=foo"; ok($response->code, 302, "form: login with wrong passwd should redirect with 302"); my $loc = $response->header("Location"); if (defined $loc && $loc =~ m{^http://[^/]+(/.*)$}) { $loc = $1; } ok($loc, "/authz/login.html", "form: login with wrong passwd should redirect to login form"); $response = GET $url; ok($response->code, 302, "$type: wrong passwd should not allow access"); } { # authenticated Apache::TestRequest::user_agent(@params); my $response = POST $login_url, content => "httpd_username=uform&httpd_password=pform"; ok($response->code, 302, "form: login with correct passwd should redirect with 302"); my $loc = $response->header("Location"); if (defined $loc && $loc =~ m{^http://[^/]+(/.*)$}) { $loc = $1; } ok($1, "/authz/form/", "form: login with correct passwd should redirect to SuccessLocation"); $response = GET $url; ok($response->code, 200, "$type: correct passwd did not allow access"); } { # authorized by env Apache::TestRequest::user_agent(@params); my $response = GET $url, 'X-Allowed' => 'yes'; ok($response->code, 200, "$type: authz by envvar"); check_headers($response, 200); } { # authorized by env / with error my $response = GET "$url.foo", 'X-Allowed' => 'yes'; ok($response->code, 404, "$type: not found"); check_headers($response, 404); } } # # Test AuthzSendForbiddenOnFailure # if (have_min_apache_version("2.3.11")) { foreach my $want (401, 403) { my $response = GET "/authz/fail/$want", username => "ubasic", password => "pbasic"; my $got = $response->code; ok($got, $want, "Expected code $want, got $got"); } } else { skip "skipping tests with httpd <2.3.11" foreach (1..2); } # # check that none of the authentication related headers exists # sub check_headers { my $response = shift; my $code = shift; foreach my $h (@headers) { ok($response->header($h), undef, "$type: $code response should have no $h header"); } } # # write out the htpasswd files # sub write_htpasswd { my $digest_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'realm2'); t_write_file($digest_file, << 'EOF' ); # udigest/pdigest udigest:realm2:bccffb0d42943019acfbebf2039b8a3a EOF my $basic_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'basic1'); t_write_file($basic_file, << 'EOF' ); # ubasic:pbasic ubasic:$apr1$opONH1Fj$dX0sZdZ0rRWEk0Wj8y.Qv1 EOF my $form_file = File::Spec->catfile(Apache::Test::vars('serverroot'), 'form1'); t_write_file($form_file, << 'EOF' ); # uform:pform uform:$apr1$BzhDZ03D$U598kbSXGy/R7OhYXu.JJ0 EOF }