fix: consider authentication failure as a fatal error
This commit is contained in:
@@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- #2622, Consider any PostgreSQL authentication failure as fatal and exit immediately - @michivi
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- #1414, Add related orders - @steve-chavez
|
- #1414, Add related orders - @steve-chavez
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ let
|
|||||||
export PGDATABASE
|
export PGDATABASE
|
||||||
export PGRST_DB_SCHEMAS
|
export PGRST_DB_SCHEMAS
|
||||||
|
|
||||||
|
HBA_FILE="$tmpdir/pg_hba.conf"
|
||||||
|
echo "local $PGDATABASE some_protected_user password" > "$HBA_FILE"
|
||||||
|
echo "local $PGDATABASE all trust" >> "$HBA_FILE"
|
||||||
|
|
||||||
log "Initializing database cluster..."
|
log "Initializing database cluster..."
|
||||||
# We try to make the database cluster as independent as possible from the host
|
# We try to make the database cluster as independent as possible from the host
|
||||||
# by specifying the timezone, locale and encoding.
|
# by specifying the timezone, locale and encoding.
|
||||||
@@ -62,7 +66,7 @@ let
|
|||||||
|
|
||||||
log "Starting the database cluster..."
|
log "Starting the database cluster..."
|
||||||
# Instead of listening on a local port, we will listen on a unix domain socket.
|
# Instead of listening on a local port, we will listen on a unix domain socket.
|
||||||
pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"\" -k $PGHOST -c log_statement=\"all\"" \
|
pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $PGHOST -c log_statement=\"all\"" \
|
||||||
>> "$setuplog"
|
>> "$setuplog"
|
||||||
|
|
||||||
# shellcheck disable=SC2317
|
# shellcheck disable=SC2317
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ checkIsFatal :: PgError -> Maybe Text
|
|||||||
checkIsFatal (PgError _ (SQL.ConnectionUsageError e))
|
checkIsFatal (PgError _ (SQL.ConnectionUsageError e))
|
||||||
| isAuthFailureMessage = Just $ toS failureMessage
|
| isAuthFailureMessage = Just $ toS failureMessage
|
||||||
| otherwise = Nothing
|
| otherwise = Nothing
|
||||||
where isAuthFailureMessage = "FATAL: password authentication failed" `isPrefixOf` failureMessage
|
where isAuthFailureMessage = "FATAL: password authentication failed" `isInfixOf` failureMessage
|
||||||
failureMessage = BS.unpack $ fromMaybe mempty e
|
failureMessage = BS.unpack $ fromMaybe mempty e
|
||||||
checkIsFatal (PgError _ (SQL.SessionUsageError (SQL.QueryError _ _ (SQL.ResultError serverError))))
|
checkIsFatal (PgError _ (SQL.SessionUsageError (SQL.QueryError _ _ (SQL.ResultError serverError))))
|
||||||
= case serverError of
|
= case serverError of
|
||||||
|
|||||||
+11
-1
@@ -50,6 +50,7 @@ def run(
|
|||||||
env=None,
|
env=None,
|
||||||
port=None,
|
port=None,
|
||||||
host=None,
|
host=None,
|
||||||
|
wait_for_readiness=True,
|
||||||
no_pool_connection_available=False,
|
no_pool_connection_available=False,
|
||||||
):
|
):
|
||||||
"Run PostgREST and yield an endpoint that is ready for connections."
|
"Run PostgREST and yield an endpoint that is ready for connections."
|
||||||
@@ -88,7 +89,8 @@ def run(
|
|||||||
process.stdin.write(stdin or b"")
|
process.stdin.write(stdin or b"")
|
||||||
process.stdin.close()
|
process.stdin.close()
|
||||||
|
|
||||||
wait_until_ready(adminurl + "/ready")
|
if wait_for_readiness:
|
||||||
|
wait_until_ready(adminurl + "/ready")
|
||||||
|
|
||||||
process.stdout.read()
|
process.stdout.read()
|
||||||
|
|
||||||
@@ -137,6 +139,14 @@ def freeport():
|
|||||||
return s.getsockname()[1]
|
return s.getsockname()[1]
|
||||||
|
|
||||||
|
|
||||||
|
def wait_until_exit(postgrest):
|
||||||
|
"Wait for PostgREST to exit, or times out"
|
||||||
|
try:
|
||||||
|
return postgrest.process.wait(timeout=1)
|
||||||
|
except (subprocess.TimeoutExpired):
|
||||||
|
raise PostgrestTimedOut()
|
||||||
|
|
||||||
|
|
||||||
def wait_until_ready(url):
|
def wait_until_ready(url):
|
||||||
"Wait for the given HTTP endpoint to return a status of 200."
|
"Wait for the given HTTP endpoint to return a status of 200."
|
||||||
session = requests_unixsocket.Session()
|
session = requests_unixsocket.Session()
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ def test_read_secret_from_stdin_dbconfig(defaultenv):
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_fail_with_invalid_password(defaultenv):
|
||||||
|
"Connecting with an invalid password should fail without retries."
|
||||||
|
uri = f'postgresql://?dbname={defaultenv["PGDATABASE"]}&host={defaultenv["PGHOST"]}&user=some_protected_user&password=invalid_pass'
|
||||||
|
env = {**defaultenv, "PGRST_DB_URI": uri}
|
||||||
|
with run(env=env, wait_for_readiness=False) as postgrest:
|
||||||
|
exitCode = wait_until_exit(postgrest)
|
||||||
|
assert exitCode == 1
|
||||||
|
|
||||||
|
|
||||||
def test_connect_with_dburi(dburi, defaultenv):
|
def test_connect_with_dburi(dburi, defaultenv):
|
||||||
"Connecting with db-uri instead of LIPQ* environment variables should work."
|
"Connecting with db-uri instead of LIPQ* environment variables should work."
|
||||||
defaultenv_without_libpq = {
|
defaultenv_without_libpq = {
|
||||||
|
|||||||
Reference in New Issue
Block a user