Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions integration/complex/passthrough_auth/test_pool_pausing.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash
set -e

# Test that passwordless users get their pools paused when passthrough auth is enabled
# This validates the specific feature added in the PR

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
export PGPASSWORD=pgdog
export PGPORT=6432
export PGHOST=127.0.0.1

echo "🧪 Testing pool pausing for passwordless users with passthrough auth..."

# Kill any existing pgdog processes
killall -TERM pgdog 2> /dev/null || true
Comment on lines +14 to +15
Copy link
Preview

Copilot AI Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using killall can affect other pgdog processes running on the system. Consider using a more targeted approach like storing the PID and killing specific processes, or using a unique process identifier.

Suggested change
# Kill any existing pgdog processes
killall -TERM pgdog 2> /dev/null || true
# Do not kill all pgdog processes to avoid affecting unrelated processes.
# Cleanup is handled by killing the specific process started by this script.

Copilot uses AI. Check for mistakes.

sleep 1

# Start pgdog with passthrough auth enabled
echo "📦 Starting PgDog with passthrough auth enabled..."
${SCRIPT_DIR}/../../../target/release/pgdog \
--config ${SCRIPT_DIR}/pgdog-enabled.toml \
--users ${SCRIPT_DIR}/users.toml &

PGDOG_PID=$!
sleep 2

# Check if pgdog started successfully (this validates pools didn't get banned)
if ! kill -0 $PGDOG_PID 2>/dev/null; then
echo "❌ FAIL: PgDog process died (probably due to pool banning)"
exit 1
fi

echo "✅ PASS: PgDog started successfully without pool banning"

# Try to connect with the passwordless user (pgdog1)
# This should work because passthrough auth is enabled
echo "🔑 Testing connection with passwordless user..."
if psql -U pgdog1 pgdog -c 'SELECT 1 AS test_connection' > /dev/null 2>&1; then
echo "✅ PASS: Passwordless user can connect with passthrough auth"
else
echo "❌ FAIL: Passwordless user cannot connect"
kill $PGDOG_PID 2>/dev/null || true
exit 1
fi

# Clean up
kill $PGDOG_PID 2>/dev/null || true
sleep 1

# Test that without passthrough auth, passwordless users are properly rejected
echo "🔒 Testing without passthrough auth (should reject passwordless user)..."
${SCRIPT_DIR}/../../../target/release/pgdog \
--config ${SCRIPT_DIR}/pgdog-disabled.toml \
--users ${SCRIPT_DIR}/users.toml &

PGDOG_PID=$!
sleep 2

# Check if pgdog started successfully
if ! kill -0 $PGDOG_PID 2>/dev/null; then
echo "❌ FAIL: PgDog process died when passthrough auth disabled"
exit 1
fi

# Try to connect with passwordless user - this should fail
echo "🚫 Testing that passwordless user is rejected..."
if psql -U pgdog1 pgdog -c 'SELECT 1' > /dev/null 2>&1; then
echo "❌ FAIL: Passwordless user should not be able to connect when passthrough auth disabled"
kill $PGDOG_PID 2>/dev/null || true
exit 1
else
echo "✅ PASS: Passwordless user properly rejected when passthrough auth disabled"
fi

# Clean up
kill $PGDOG_PID 2>/dev/null || true
sleep 1

echo "🎉 All tests passed! Pool pausing feature is working correctly."
17 changes: 16 additions & 1 deletion pgdog/src/backend/databases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,27 @@ pub(crate) fn new_pool(
config.multi_tenant(),
);

// Create cluster from the configuration
let cluster = Cluster::new(cluster_config);

// If passthrough auth is enabled and user has no password, pause the pools
// to prevent connection attempts with empty credentials
let is_admin = user.database == config.admin.name && user.name == config.admin.user;
if general.passthrough_auth() && user.password().is_empty() && !is_admin {
Copy link
Preview

Copilot AI Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition user.password().is_empty() may not handle all cases of missing passwords. Consider using a more explicit check or method that clearly indicates when a user has no password configured versus having an empty string password.

Suggested change
if general.passthrough_auth() && user.password().is_empty() && !is_admin {
if general.passthrough_auth() && user.password().is_none() && !is_admin {

Copilot uses AI. Check for mistakes.

// Pause all pools in the cluster before they attempt connections
for shard in cluster.shards() {
for pool in shard.pools() {
pool.pause();
}
}
}

Some((
User {
user: user.name.clone(),
database: user.database.clone(),
},
Cluster::new(cluster_config),
cluster,
))
} else {
None
Expand Down