Skip to content

Commit

Permalink
fix: consider authentication failure as a fatal error
Browse files Browse the repository at this point in the history
  • Loading branch information
michivi authored and laurenceisla committed Feb 2, 2023
1 parent 549e574 commit 7d14722
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 3 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

- #2622, Consider any PostgreSQL authentication failure as fatal and exit immediately - @michivi

### Added

- #1414, Add related orders - @steve-chavez
+ On a many-to-one or one-to-one relationship, you can order a parent by a child column `/projects?select=*,clients(*)&order=clients(name).desc.nullsfirst`
- #1233, #1907, #2566, Allow spreading embedded resources - @steve-chavez
+ On a many-to-one or one-to-one relationship, you can unnest a json object with `/projects?select=*,...clients(client_name:name)`
+ Allows including the join table columns when resource embedding
+ Allows disambiguating a recursive m2m embed
+ Allows disambiguating an embed that has a many-to-many relationship using two foreign keys on a junction
- #2340, Allow embedding without selecting any column - @steve-chavez
- #2563, Allow `is.null` or `not.is.null` on an embedded resource - @steve-chavez
+ Offers a more flexible replacement for `!inner`, e.g. `/projects?select=*,clients(*)&clients=not.is.null`
+ Allows doing an anti join, e.g. `/projects?select=*,clients(*)&clients=is.null`
+ Allows using or across related tables conditions

### Fixed

- #2565, Fix bad M2M embedding on RPC - @steve-chavez
Expand Down
6 changes: 5 additions & 1 deletion nix/tools/withTools.nix
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ let
export PGDATABASE
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..."
# We try to make the database cluster as independent as possible from the host
# by specifying the timezone, locale and encoding.
Expand All @@ -62,7 +66,7 @@ let
log "Starting the database cluster..."
# 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"
stop () {
Expand Down
2 changes: 1 addition & 1 deletion src/PostgREST/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ checkIsFatal :: PgError -> Maybe Text
checkIsFatal (PgError _ (SQL.ConnectionUsageError e))
| isAuthFailureMessage = Just $ toS failureMessage
| otherwise = Nothing
where isAuthFailureMessage = "FATAL: password authentication failed" `isPrefixOf` failureMessage
where isAuthFailureMessage = "FATAL: password authentication failed" `isInfixOf` failureMessage
failureMessage = BS.unpack $ fromMaybe mempty e
checkIsFatal (PgError _ (SQL.SessionUsageError (SQL.QueryError _ _ (SQL.ResultError serverError))))
= case serverError of
Expand Down
12 changes: 11 additions & 1 deletion test/io/postgrest.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def run(
env=None,
port=None,
host=None,
wait_for_readiness=True,
no_pool_connection_available=False,
):
"Run PostgREST and yield an endpoint that is ready for connections."
Expand Down Expand Up @@ -88,7 +89,8 @@ def run(
process.stdin.write(stdin or b"")
process.stdin.close()

wait_until_ready(adminurl + "/ready")
if wait_for_readiness:
wait_until_ready(adminurl + "/ready")

process.stdout.read()

Expand Down Expand Up @@ -137,6 +139,14 @@ def freeport():
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):
"Wait for the given HTTP endpoint to return a status of 200."
session = requests_unixsocket.Session()
Expand Down
9 changes: 9 additions & 0 deletions test/io/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ def test_read_secret_from_stdin_dbconfig(defaultenv):
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):
"Connecting with db-uri instead of LIPQ* environment variables should work."
defaultenv_without_libpq = {
Expand Down

0 comments on commit 7d14722

Please sign in to comment.