mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-23 01:16:30 +00:00
216 lines
9.0 KiB
Ruby
216 lines
9.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative 'spec_helper'
|
|
require_relative 'helpers/auth_query_helper'
|
|
|
|
describe "Auth Query" do
|
|
let(:configured_instances) {[5432, 10432]}
|
|
let(:config_user) { { 'username' => 'sharding_user', 'password' => 'sharding_user' } }
|
|
let(:pg_user) { { 'username' => 'sharding_user', 'password' => 'sharding_user' } }
|
|
let(:processes) { Helpers::AuthQuery.single_shard_auth_query(pool_name: "sharded_db", pg_user: pg_user, config_user: config_user, extra_conf: config, wait_until_ready: wait_until_ready ) }
|
|
let(:config) { {} }
|
|
let(:wait_until_ready) { true }
|
|
|
|
after do
|
|
unless @failing_process
|
|
processes.all_databases.map(&:reset)
|
|
processes.pgcat.shutdown
|
|
end
|
|
@failing_process = false
|
|
end
|
|
|
|
context "when auth_query is not configured" do
|
|
context 'and cleartext passwords are set' do
|
|
it "uses local passwords" do
|
|
conn = PG.connect(processes.pgcat.connection_string("sharded_db", config_user['username'], config_user['password']))
|
|
|
|
expect(conn.async_exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
end
|
|
|
|
context 'and cleartext passwords are not set' do
|
|
let(:config_user) { { 'username' => 'sharding_user' } }
|
|
|
|
it "does not start because it is not possible to authenticate" do
|
|
@failing_process = true
|
|
expect { processes.pgcat }.to raise_error(StandardError, /You have to specify a user password for every pool if auth_query is not specified/)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when auth_query is configured' do
|
|
context 'with global configuration' do
|
|
around(:example) do |example|
|
|
|
|
# Set up auth query
|
|
Helpers::AuthQuery.set_up_auth_query_for_user(
|
|
user: 'md5_auth_user',
|
|
password: 'secret'
|
|
);
|
|
|
|
example.run
|
|
|
|
# Drop auth query support
|
|
Helpers::AuthQuery.tear_down_auth_query_for_user(
|
|
user: 'md5_auth_user',
|
|
password: 'secret'
|
|
);
|
|
end
|
|
|
|
context 'with correct global parameters' do
|
|
let(:config) { { 'general' => { 'auth_query' => "SELECT * FROM public.user_lookup('$1');", 'auth_query_user' => 'md5_auth_user', 'auth_query_password' => 'secret' } } }
|
|
context 'and with cleartext passwords set' do
|
|
it 'it uses local passwords' do
|
|
conn = PG.connect(processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password']))
|
|
expect(conn.exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
end
|
|
|
|
context 'and with cleartext passwords not set' do
|
|
let(:config_user) { { 'username' => 'sharding_user' } }
|
|
|
|
it 'it uses obtained passwords' do
|
|
connection_string = processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password'])
|
|
conn = PG.connect(connection_string)
|
|
expect(conn.async_exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
|
|
it 'allows passwords to be changed without closing existing connections' do
|
|
pgconn = PG.connect(processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password']))
|
|
expect(pgconn.exec("SELECT 1 + 2")).not_to be_nil
|
|
Helpers::AuthQuery.exec_in_instances(query: "ALTER USER #{pg_user['username']} WITH ENCRYPTED PASSWORD 'secret2';")
|
|
expect(pgconn.exec("SELECT 1 + 4")).not_to be_nil
|
|
Helpers::AuthQuery.exec_in_instances(query: "ALTER USER #{pg_user['username']} WITH ENCRYPTED PASSWORD '#{pg_user['password']}';")
|
|
end
|
|
|
|
it 'allows passwords to be changed and that new password is needed when reconnecting' do
|
|
pgconn = PG.connect(processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password']))
|
|
expect(pgconn.exec("SELECT 1 + 2")).not_to be_nil
|
|
Helpers::AuthQuery.exec_in_instances(query: "ALTER USER #{pg_user['username']} WITH ENCRYPTED PASSWORD 'secret2';")
|
|
newconn = PG.connect(processes.pgcat.connection_string("sharded_db", pg_user['username'], 'secret2'))
|
|
expect(newconn.exec("SELECT 1 + 2")).not_to be_nil
|
|
Helpers::AuthQuery.exec_in_instances(query: "ALTER USER #{pg_user['username']} WITH ENCRYPTED PASSWORD '#{pg_user['password']}';")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with wrong parameters' do
|
|
let(:config) { { 'general' => { 'auth_query' => 'SELECT 1', 'auth_query_user' => 'wrong_user', 'auth_query_password' => 'wrong' } } }
|
|
|
|
context 'and with clear text passwords set' do
|
|
it "it uses local passwords" do
|
|
conn = PG.connect(processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password']))
|
|
|
|
expect(conn.async_exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
end
|
|
|
|
context 'and with cleartext passwords not set' do
|
|
let(:config_user) { { 'username' => 'sharding_user' } }
|
|
it "it fails to start as it cannot authenticate against servers" do
|
|
@failing_process = true
|
|
expect { PG.connect(processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password'])) }.to raise_error(StandardError, /Error trying to obtain password from auth_query/ )
|
|
end
|
|
|
|
context 'and we fix the issue and reload' do
|
|
let(:wait_until_ready) { false }
|
|
|
|
it 'fails in the beginning but starts working after reloading config' do
|
|
connection_string = processes.pgcat.connection_string("sharded_db", pg_user['username'], pg_user['password'])
|
|
while !(processes.pgcat.logs =~ /Waiting for clients/) do
|
|
sleep 0.5
|
|
end
|
|
|
|
expect { PG.connect(connection_string)}.to raise_error(PG::ConnectionBad)
|
|
expect(processes.pgcat.logs).to match(/Error trying to obtain password from auth_query/)
|
|
|
|
current_config = processes.pgcat.current_config
|
|
config = { 'general' => { 'auth_query' => "SELECT * FROM public.user_lookup('$1');", 'auth_query_user' => 'md5_auth_user', 'auth_query_password' => 'secret' } }
|
|
processes.pgcat.update_config(current_config.deep_merge(config))
|
|
processes.pgcat.reload_config
|
|
|
|
conn = nil
|
|
expect { conn = PG.connect(connection_string)}.not_to raise_error
|
|
expect(conn.async_exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with per pool configuration' do
|
|
around(:example) do |example|
|
|
|
|
# Set up auth query
|
|
Helpers::AuthQuery.set_up_auth_query_for_user(
|
|
user: 'md5_auth_user',
|
|
password: 'secret'
|
|
);
|
|
|
|
Helpers::AuthQuery.set_up_auth_query_for_user(
|
|
user: 'md5_auth_user1',
|
|
password: 'secret',
|
|
database: 'shard1'
|
|
);
|
|
|
|
example.run
|
|
|
|
# Tear down auth query
|
|
Helpers::AuthQuery.tear_down_auth_query_for_user(
|
|
user: 'md5_auth_user',
|
|
password: 'secret'
|
|
);
|
|
|
|
Helpers::AuthQuery.tear_down_auth_query_for_user(
|
|
user: 'md5_auth_user1',
|
|
password: 'secret',
|
|
database: 'shard1'
|
|
);
|
|
end
|
|
|
|
context 'with correct parameters' do
|
|
let(:processes) { Helpers::AuthQuery.two_pools_auth_query(pool_names: ["sharded_db0", "sharded_db1"], pg_user: pg_user, config_user: config_user, extra_conf: config ) }
|
|
let(:config) {
|
|
{ 'pools' =>
|
|
{
|
|
'sharded_db0' => {
|
|
'auth_query' => "SELECT * FROM public.user_lookup('$1');",
|
|
'auth_query_user' => 'md5_auth_user',
|
|
'auth_query_password' => 'secret'
|
|
},
|
|
'sharded_db1' => {
|
|
'auth_query' => "SELECT * FROM public.user_lookup('$1');",
|
|
'auth_query_user' => 'md5_auth_user1',
|
|
'auth_query_password' => 'secret'
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
context 'and with cleartext passwords set' do
|
|
it 'it uses local passwords' do
|
|
conn = PG.connect(processes.pgcat.connection_string("sharded_db0", pg_user['username'], pg_user['password']))
|
|
expect(conn.exec("SELECT 1 + 2")).not_to be_nil
|
|
conn = PG.connect(processes.pgcat.connection_string("sharded_db1", pg_user['username'], pg_user['password']))
|
|
expect(conn.exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
end
|
|
|
|
context 'and with cleartext passwords not set' do
|
|
let(:config_user) { { 'username' => 'sharding_user' } }
|
|
|
|
it 'it uses obtained passwords' do
|
|
connection_string = processes.pgcat.connection_string("sharded_db0", pg_user['username'], pg_user['password'])
|
|
conn = PG.connect(connection_string)
|
|
expect(conn.async_exec("SELECT 1 + 2")).not_to be_nil
|
|
connection_string = processes.pgcat.connection_string("sharded_db1", pg_user['username'], pg_user['password'])
|
|
conn = PG.connect(connection_string)
|
|
expect(conn.async_exec("SELECT 1 + 2")).not_to be_nil
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|