From 65ecda4827dfc139af2cc85a050e9f4e31ad0acf Mon Sep 17 00:00:00 2001 From: Samay Sharma Date: Wed, 16 Feb 2022 12:28:36 -0800 Subject: [PATCH 3/3] Add tests for test_auth_provider extension Add tap tests for test_auth_provider extension allow make check in src/test/modules to run them. --- src/test/modules/Makefile | 1 + src/test/modules/test_auth_provider/Makefile | 2 + .../test_auth_provider/t/001_custom_auth.pl | 134 ++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 src/test/modules/test_auth_provider/t/001_custom_auth.pl diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index dffc79b2d9..f56533ea13 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -14,6 +14,7 @@ SUBDIRS = \ plsample \ snapshot_too_old \ spgist_name_ops \ + test_auth_provider \ test_bloomfilter \ test_ddl_deparse \ test_extensions \ diff --git a/src/test/modules/test_auth_provider/Makefile b/src/test/modules/test_auth_provider/Makefile index 17971a5c7a..7d601cf7d5 100644 --- a/src/test/modules/test_auth_provider/Makefile +++ b/src/test/modules/test_auth_provider/Makefile @@ -4,6 +4,8 @@ MODULE_big = test_auth_provider OBJS = test_auth_provider.o PGFILEDESC = "test_auth_provider - provider to test auth hooks" +TAP_TESTS = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/src/test/modules/test_auth_provider/t/001_custom_auth.pl b/src/test/modules/test_auth_provider/t/001_custom_auth.pl new file mode 100644 index 0000000000..4eb0cdf43e --- /dev/null +++ b/src/test/modules/test_auth_provider/t/001_custom_auth.pl @@ -0,0 +1,134 @@ + +# Copyright (c) 2021-2022, PostgreSQL Global Development Group + +# Set of tests for testing custom authentication. + +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# Delete pg_hba.conf from the given node, add a new entry to it +# and then execute a reload to refresh it. +sub reset_pg_hba +{ + my $node = shift; + my $hba_method = shift; + + unlink($node->data_dir . '/pg_hba.conf'); + # just for testing purposes, use a continuation line + $node->append_conf('pg_hba.conf', "local all all\\\n $hba_method"); + $node->reload; + return; +} + +# Test that you get expected output after making a change to hba.conf +# and reloading it. +sub test_hba_reload +{ + my ($node,$method,$expected_res,$log_message) = @_; + my $status_string = 'failed'; + $status_string = 'success' if ($expected_res eq 0); + my $testname = "pg_hba.conf reload $status_string for method $method"; + + my $log_location = -s $node->logfile; + + reset_pg_hba($node,$method); + + my $log_contents = slurp_file($node->logfile, $log_location); + + # Search for specific error message if it's a failure. + # For success, just confirm that there was no error message. + if ($expected_res eq 1) + { + like($log_contents,$log_message,$testname); + } + else + { + unlike($log_contents,$log_message,$testname); + } +} + +# Test access for a single role, useful to wrap all tests into one. Extra +# named parameters are passed to connect_ok/fails as-is. +sub test_role +{ + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ($node, $role, $method, $expected_res, %params) = @_; + my $status_string = 'failed'; + $status_string = 'success' if ($expected_res eq 0); + + my $connstr = "user=$role"; + my $testname = + "authentication $status_string for method $method, role $role"; + + if ($expected_res eq 0) + { + $node->connect_ok($connstr, $testname, %params); + } + else + { + # No checks of the error message, only the status code. + $node->connect_fails($connstr, $testname, %params); + } +} + +# Initialize server node +my $node = PostgreSQL::Test::Cluster->new('server'); +$node->init; +$node->append_conf('postgresql.conf', "log_connections = on\n"); +$node->append_conf('postgresql.conf', "shared_preload_libraries = 'test_auth_provider.so'\n"); +$node->start; + +$node->safe_psql('postgres',"CREATE ROLE bob LOGIN;"); +$node->safe_psql('postgres',"CREATE ROLE alice LOGIN;"); +$node->safe_psql('postgres',"CREATE ROLE test LOGIN;"); + +# Add custom auth method to pg_hba.conf +reset_pg_hba($node, 'custom provider=test'); + +# Test that users are able to login with correct passwords. +$ENV{"PGPASSWORD"} = 'bob123'; +test_role($node, 'bob','custom', 0, log_like => [qr/connection authorized: user=bob/]); +$ENV{"PGPASSWORD"} = 'alice123'; +test_role($node, 'alice','custom', 0, log_like => [qr/connection authorized: user=alice/]); + +# Test that bad passwords are rejected. +$ENV{"PGPASSWORD"} = 'badpassword'; +test_role($node, 'bob','custom', 2, log_unlike => [qr/connection authorized:/]); +test_role($node, 'alice','custom', 2, log_unlike => [qr/connection authorized:/]); + +# Test that users not in authentication list are rejected. +test_role($node, 'test','custom', 2, log_unlike => [qr/connection authorized:/]); + +# Tests for invalid auth options + +# Test that an incorrect provider name is not accepted. +test_hba_reload($node, 'custom provider=wrong', 1, qr/cannot use authentication provider wrong/); + +# Test that specifying provider option with different auth method is not allowed. +test_hba_reload($node, 'trust provider=test', 1, qr/only valid for authentication methods custom/); + +# Test that provider name is a mandatory option for custom auth. +test_hba_reload($node, 'custom', 1, qr/requires argument/); + +# Test that correct provider name allows reload to succeed. +test_hba_reload($node, 'custom provider=test', 0, qr/pg_hba.conf was not reloaded/); + +# Custom auth modules require mentioning extension in shared_preload_libraries. + +# Remove extension from shared_preload_libraries and try to restart. +$node->adjust_conf('postgresql.conf','shared_preload_libraries',"''"); +command_fails(['pg_ctl', '-w', '-D', $node->data_dir, '-l', $node->logfile, 'restart'],'restart with empty shared_preload_libraries failed'); + +# Fix shared_preload_libraries and confirm that you can now restart. +$node->adjust_conf('postgresql.conf','shared_preload_libraries',"'test_auth_provider.so'"); +command_ok(['pg_ctl', '-w', '-D', $node->data_dir, '-l', $node->logfile,'start'],'restart with correct shared_preload_libraries succeeded'); + +# Test that we can connect again +$ENV{"PGPASSWORD"} = 'bob123'; +test_role($node, 'bob', 'custom', 0, log_like => [qr/connection authorized: user=bob/]); + +done_testing(); -- 2.34.1