Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f60eb3f

Browse files
committed
Add authentication TAP test for peer authentication
This commit introduces an authentication test for the peer method, as of a set of scenarios with and without a user name map. The script is automatically skipped if peer is not supported in the environment where this test is run, checking this behavior by attempting a connection first on a cluster up and running. Author: Bertrand Drouvot Discussion: https://postgr.es/m/aa60994b-1c66-ca7a-dab9-9a200dbac3d2@amazon.com
1 parent 89d16b6 commit f60eb3f

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/test/authentication/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ tests += {
66
'tests': [
77
't/001_password.pl',
88
't/002_saslprep.pl',
9+
't/003_peer.pl',
910
],
1011
},
1112
}

src/test/authentication/t/003_peer.pl

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
# Copyright (c) 2021-2022, PostgreSQL Global Development Group
3+
4+
# Tests for peer authentication and user name map.
5+
# The test is skipped if the platform does not support peer authentication.
6+
7+
use strict;
8+
use warnings;
9+
use PostgreSQL::Test::Cluster;
10+
use PostgreSQL::Test::Utils;
11+
use Test::More;
12+
13+
# Delete pg_hba.conf from the given node, add a new entry to it
14+
# and then execute a reload to refresh it.
15+
sub reset_pg_hba
16+
{
17+
my $node = shift;
18+
my $hba_method = shift;
19+
20+
unlink($node->data_dir . '/pg_hba.conf');
21+
$node->append_conf('pg_hba.conf', "local all all $hba_method");
22+
$node->reload;
23+
return;
24+
}
25+
26+
# Test access for a single role, useful to wrap all tests into one.
27+
sub test_role
28+
{
29+
local $Test::Builder::Level = $Test::Builder::Level + 1;
30+
31+
my ($node, $role, $method, $expected_res, %params) = @_;
32+
my $status_string = 'failed';
33+
$status_string = 'success' if ($expected_res eq 0);
34+
35+
my $connstr = "user=$role";
36+
my $testname =
37+
"authentication $status_string for method $method, role $role";
38+
39+
if ($expected_res eq 0)
40+
{
41+
$node->connect_ok($connstr, $testname, %params);
42+
}
43+
else
44+
{
45+
# No checks of the error message, only the status code.
46+
$node->connect_fails($connstr, $testname, %params);
47+
}
48+
}
49+
50+
# Find $pattern in log file of $node.
51+
sub find_in_log
52+
{
53+
my ($node, $offset, $pattern) = @_;
54+
55+
my $log = PostgreSQL::Test::Utils::slurp_file($node->logfile, $offset);
56+
return 0 if (length($log) <= 0);
57+
58+
return $log =~ m/$pattern/;
59+
}
60+
61+
my $node = PostgreSQL::Test::Cluster->new('node');
62+
$node->init;
63+
$node->append_conf('postgresql.conf', "log_connections = on\n");
64+
$node->start;
65+
66+
# Set pg_hba.conf with the peer authentication.
67+
reset_pg_hba($node, 'peer');
68+
69+
# Check if peer authentication is supported on this platform.
70+
my $log_offset = -s $node->logfile;
71+
$node->psql('postgres');
72+
if (find_in_log(
73+
$node, $log_offset,
74+
qr/peer authentication is not supported on this platform/))
75+
{
76+
plan skip_all => 'peer authentication is not supported on this platform';
77+
}
78+
79+
# Add a database role, to use for the user name map.
80+
$node->safe_psql('postgres', qq{CREATE ROLE testmapuser LOGIN});
81+
82+
# Extract as well the system user for the user name map.
83+
my $system_user =
84+
$node->safe_psql('postgres',
85+
q(select (string_to_array(SYSTEM_USER, ':'))[2]));
86+
87+
# Tests without the user name map.
88+
# Failure as connection is attempted with a database role not mapping
89+
# to an authorized system user.
90+
test_role($node, qq{testmapuser}, 'peer', 2,
91+
log_like => [qr/Peer authentication failed for user "testmapuser"/]);
92+
93+
# Tests with a user name map.
94+
$node->append_conf('pg_ident.conf', qq{mypeermap $system_user testmapuser});
95+
reset_pg_hba($node, 'peer map=mypeermap');
96+
97+
# Success as the database role matches with the system user in the map.
98+
test_role($node, qq{testmapuser}, 'peer', 0,
99+
log_like =>
100+
[qr/connection authenticated: identity="$system_user" method=peer/]);
101+
102+
done_testing();

0 commit comments

Comments
 (0)