feat: Make db-uri optional
The default is now "postgresql://" which falls back to LIBPQ environment variables. Resolves #1991, Ref #1823
This commit is contained in:
@@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
+ A `<host>:<admin_server_port>/live` endpoint is available for checking if postgrest is running on its port/socket. 200 OK = alive, 503 = dead.
|
+ A `<host>:<admin_server_port>/live` endpoint is available for checking if postgrest is running on its port/socket. 200 OK = alive, 503 = dead.
|
||||||
+ A `<host>:<admin_server_port>/ready` endpoint is available for checking a correct internal state(the database connection plus the schema cache). 200 OK = ready, 503 = not ready.
|
+ A `<host>:<admin_server_port>/ready` endpoint is available for checking a correct internal state(the database connection plus the schema cache). 200 OK = ready, 503 = not ready.
|
||||||
- #1988, Add the current user to the request log on stdout - @DavidLindbom, @wolfgangwalther
|
- #1988, Add the current user to the request log on stdout - @DavidLindbom, @wolfgangwalther
|
||||||
|
- #1991, Add the ability to run without `db-uri` using libpq's PG environment variables to connect. @wolfgangwalther
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ let
|
|||||||
inRootDir = true;
|
inRootDir = true;
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
|
# previously required settings to make this work with older branches
|
||||||
|
export PGRST_DB_URI="postgresql://"
|
||||||
|
|
||||||
export PGRST_DB_CONFIG="false"
|
export PGRST_DB_CONFIG="false"
|
||||||
export PGRST_DB_POOL="1"
|
export PGRST_DB_POOL="1"
|
||||||
export PGRST_DB_TX_END="rollback-allow-override"
|
export PGRST_DB_TX_END="rollback-allow-override"
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ let
|
|||||||
}
|
}
|
||||||
''
|
''
|
||||||
# avoid starting multiple layers of withTmpDb
|
# avoid starting multiple layers of withTmpDb
|
||||||
if test -v PGRST_DB_URI; then
|
if test -v PGHOST; then
|
||||||
exec "$_arg_command" "''${_arg_leftovers[@]}"
|
exec "$_arg_command" "''${_arg_leftovers[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -53,7 +53,6 @@ let
|
|||||||
export PGHOST="$tmpdir/socket"
|
export PGHOST="$tmpdir/socket"
|
||||||
export PGUSER
|
export PGUSER
|
||||||
export PGDATABASE
|
export PGDATABASE
|
||||||
export PGRST_DB_URI="postgresql:///$PGDATABASE?host=$PGHOST&user=$PGUSER"
|
|
||||||
export PGRST_DB_SCHEMAS
|
export PGRST_DB_SCHEMAS
|
||||||
export PGRST_DB_ANON_ROLE
|
export PGRST_DB_ANON_ROLE
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ parser optPath env dbSettings =
|
|||||||
<*> (fromMaybe True <$> optBool "db-config")
|
<*> (fromMaybe True <$> optBool "db-config")
|
||||||
<*> parseTxEnd "db-tx-end" snd
|
<*> parseTxEnd "db-tx-end" snd
|
||||||
<*> parseTxEnd "db-tx-end" fst
|
<*> parseTxEnd "db-tx-end" fst
|
||||||
<*> reqString "db-uri"
|
<*> (fromMaybe "postgresql://" <$> optString "db-uri")
|
||||||
<*> (fromMaybe True <$> optBool "db-use-legacy-gucs")
|
<*> (fromMaybe True <$> optBool "db-use-legacy-gucs")
|
||||||
<*> pure optPath
|
<*> pure optPath
|
||||||
<*> pure Nothing
|
<*> pure Nothing
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
db-anon-role = "required"
|
db-anon-role = "required"
|
||||||
db-uri = "required"
|
|
||||||
|
|
||||||
db-schema = "provided_through_alias"
|
db-schema = "provided_through_alias"
|
||||||
max-rows = 1000
|
max-rows = 1000
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
db-uri = "required"
|
|
||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-anon-role = "required"
|
db-anon-role = "required"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
db-uri = "required"
|
|
||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-anon-role = "required"
|
db-anon-role = "required"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
db-uri = "required"
|
|
||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-anon-role = "required"
|
db-anon-role = "required"
|
||||||
# Not the default, but only works with proper db-uri
|
# Not the default, but only works with PG* variables, which are not set
|
||||||
db-config = false
|
db-config = false
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = "open_alias"
|
|||||||
db-schemas = "provided_through_alias"
|
db-schemas = "provided_through_alias"
|
||||||
db-config = true
|
db-config = true
|
||||||
db-tx-end = "commit"
|
db-tx-end = "commit"
|
||||||
db-uri = "required"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = true
|
db-use-legacy-gucs = true
|
||||||
jwt-aud = ""
|
jwt-aud = ""
|
||||||
jwt-role-claim-key = ".\"aliased\""
|
jwt-role-claim-key = ".\"aliased\""
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = ""
|
|||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-config = true
|
db-config = true
|
||||||
db-tx-end = "commit"
|
db-tx-end = "commit"
|
||||||
db-uri = "required"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = true
|
db-use-legacy-gucs = true
|
||||||
jwt-aud = ""
|
jwt-aud = ""
|
||||||
jwt-role-claim-key = ".\"role\""
|
jwt-role-claim-key = ".\"role\""
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = ""
|
|||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-config = true
|
db-config = true
|
||||||
db-tx-end = "commit"
|
db-tx-end = "commit"
|
||||||
db-uri = "required"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = true
|
db-use-legacy-gucs = true
|
||||||
jwt-aud = ""
|
jwt-aud = ""
|
||||||
jwt-role-claim-key = ".\"role\""
|
jwt-role-claim-key = ".\"role\""
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = ""
|
|||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-config = false
|
db-config = false
|
||||||
db-tx-end = "commit"
|
db-tx-end = "commit"
|
||||||
db-uri = "required"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = true
|
db-use-legacy-gucs = true
|
||||||
jwt-aud = ""
|
jwt-aud = ""
|
||||||
jwt-role-claim-key = ".\"role\""
|
jwt-role-claim-key = ".\"role\""
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = "other_root"
|
|||||||
db-schemas = "test,other_tenant1,other_tenant2"
|
db-schemas = "test,other_tenant1,other_tenant2"
|
||||||
db-config = true
|
db-config = true
|
||||||
db-tx-end = "rollback-allow-override"
|
db-tx-end = "rollback-allow-override"
|
||||||
db-uri = "<REPLACED_WITH_DB_URI>"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = false
|
db-use-legacy-gucs = false
|
||||||
jwt-aud = "https://otherexample.org"
|
jwt-aud = "https://otherexample.org"
|
||||||
jwt-role-claim-key = ".\"other\".\"role\""
|
jwt-role-claim-key = ".\"other\".\"role\""
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = "root"
|
|||||||
db-schemas = "test,tenant1,tenant2"
|
db-schemas = "test,tenant1,tenant2"
|
||||||
db-config = true
|
db-config = true
|
||||||
db-tx-end = "commit-allow-override"
|
db-tx-end = "commit-allow-override"
|
||||||
db-uri = "<REPLACED_WITH_DB_URI>"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = false
|
db-use-legacy-gucs = false
|
||||||
jwt-aud = "https://example.org"
|
jwt-aud = "https://example.org"
|
||||||
jwt-role-claim-key = ".\"a\".\"role\""
|
jwt-role-claim-key = ".\"a\".\"role\""
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ db-root-spec = ""
|
|||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-config = true
|
db-config = true
|
||||||
db-tx-end = "commit"
|
db-tx-end = "commit"
|
||||||
db-uri = "required"
|
db-uri = "postgresql://"
|
||||||
db-use-legacy-gucs = true
|
db-use-legacy-gucs = true
|
||||||
jwt-aud = ""
|
jwt-aud = ""
|
||||||
jwt-role-claim-key = ".\"role\""
|
jwt-role-claim-key = ".\"role\""
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# tests how config options fall back with invalid types
|
# tests how config options fall back with invalid types
|
||||||
db-anon-role = "required"
|
db-anon-role = "required"
|
||||||
db-schemas = "required"
|
db-schemas = "required"
|
||||||
db-uri = "required"
|
|
||||||
|
|
||||||
# expects string
|
# expects string
|
||||||
app.settings.test = false
|
app.settings.test = false
|
||||||
|
|||||||
@@ -27,18 +27,11 @@ cli:
|
|||||||
- name: missing db-anon-role
|
- name: missing db-anon-role
|
||||||
expect: error
|
expect: error
|
||||||
env:
|
env:
|
||||||
PGRST_DB_URI: required
|
|
||||||
PGRST_DB_SCHEMAS: required
|
PGRST_DB_SCHEMAS: required
|
||||||
- name: missing db-schemas
|
- name: missing db-schemas
|
||||||
expect: error
|
expect: error
|
||||||
env:
|
env:
|
||||||
PGRST_DB_ANON_ROLE: required
|
PGRST_DB_ANON_ROLE: required
|
||||||
PGRST_DB_URI: required
|
|
||||||
- name: missing db-uri
|
|
||||||
expect: error
|
|
||||||
env:
|
|
||||||
PGRST_DB_ANON_ROLE: required
|
|
||||||
PGRST_DB_SCHEMAS: required
|
|
||||||
# failures: wrong config values
|
# failures: wrong config values
|
||||||
- name: invalid server-unix-socket-mode not octal
|
- name: invalid server-unix-socket-mode not octal
|
||||||
expect: error
|
expect: error
|
||||||
|
|||||||
+35
-17
@@ -79,14 +79,19 @@ class PostgrestProcess:
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def dburi():
|
def dburi():
|
||||||
"Postgres database connection URI."
|
"Postgres database connection URI."
|
||||||
return os.getenv("PGRST_DB_URI").encode()
|
dbname = os.environ["PGDATABASE"]
|
||||||
|
host = os.environ["PGHOST"]
|
||||||
|
user = os.environ["PGUSER"]
|
||||||
|
return f"postgresql://?dbname={dbname}&host={host}&user={user}".encode()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def defaultenv():
|
def defaultenv():
|
||||||
"Default environment for PostgREST."
|
"Default environment for PostgREST."
|
||||||
return {
|
return {
|
||||||
"PGRST_DB_URI": os.environ["PGRST_DB_URI"],
|
"PGDATABASE": os.environ["PGDATABASE"],
|
||||||
|
"PGHOST": os.environ["PGHOST"],
|
||||||
|
"PGUSER": os.environ["PGUSER"],
|
||||||
"PGRST_DB_SCHEMAS": "public",
|
"PGRST_DB_SCHEMAS": "public",
|
||||||
"PGRST_DB_ANON_ROLE": os.environ["PGRST_DB_ANON_ROLE"],
|
"PGRST_DB_ANON_ROLE": os.environ["PGRST_DB_ANON_ROLE"],
|
||||||
"PGRST_DB_CONFIG": "false",
|
"PGRST_DB_CONFIG": "false",
|
||||||
@@ -309,20 +314,14 @@ def test_expected_config_from_db_settings(defaultenv, role, expectedconfig):
|
|||||||
|
|
||||||
config = CONFIGSDIR / "no-defaults.config"
|
config = CONFIGSDIR / "no-defaults.config"
|
||||||
|
|
||||||
db_uri = defaultenv["PGRST_DB_URI"].replace(
|
|
||||||
"user=postgrest_test_authenticator", f"user={role}"
|
|
||||||
)
|
|
||||||
env = {
|
env = {
|
||||||
**defaultenv,
|
**defaultenv,
|
||||||
"PGRST_DB_URI": db_uri,
|
"PGUSER": role,
|
||||||
|
"PGRST_DB_URI": "postgresql://",
|
||||||
"PGRST_DB_CONFIG": "true",
|
"PGRST_DB_CONFIG": "true",
|
||||||
}
|
}
|
||||||
expected = (
|
|
||||||
(CONFIGSDIR / "expected" / expectedconfig)
|
|
||||||
.read_text()
|
|
||||||
.replace("<REPLACED_WITH_DB_URI>", env["PGRST_DB_URI"])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
expected = (CONFIGSDIR / "expected" / expectedconfig).read_text()
|
||||||
assert dumpconfig(configpath=config, env=env) == expected
|
assert dumpconfig(configpath=config, env=env) == expected
|
||||||
|
|
||||||
|
|
||||||
@@ -418,9 +417,26 @@ def test_read_secret_from_stdin_dbconfig(defaultenv):
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_connect_with_dburi(dburi, defaultenv):
|
||||||
|
"Connecting with db-uri instead of LIPQ* environment variables should work."
|
||||||
|
defaultenv_without_libpq = {
|
||||||
|
key: value
|
||||||
|
for key, value in defaultenv.items()
|
||||||
|
if key not in ["PGDATABASE", "PGHOST", "PGUSER"]
|
||||||
|
}
|
||||||
|
env = {**defaultenv_without_libpq, "PGRST_DB_URI": dburi.decode()}
|
||||||
|
with run(env=env):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_read_dburi_from_stdin_without_eol(dburi, defaultenv):
|
def test_read_dburi_from_stdin_without_eol(dburi, defaultenv):
|
||||||
"Reading the dburi from stdin with a single line should work."
|
"Reading the dburi from stdin with a single line should work."
|
||||||
env = {**defaultenv, "PGRST_DB_URI": "@/dev/stdin"}
|
defaultenv_without_libpq = {
|
||||||
|
key: value
|
||||||
|
for key, value in defaultenv.items()
|
||||||
|
if key not in ["PGDATABASE", "PGHOST", "PGUSER"]
|
||||||
|
}
|
||||||
|
env = {**defaultenv_without_libpq, "PGRST_DB_URI": "@/dev/stdin"}
|
||||||
|
|
||||||
with run(env=env, stdin=dburi):
|
with run(env=env, stdin=dburi):
|
||||||
pass
|
pass
|
||||||
@@ -428,7 +444,12 @@ def test_read_dburi_from_stdin_without_eol(dburi, defaultenv):
|
|||||||
|
|
||||||
def test_read_dburi_from_stdin_with_eol(dburi, defaultenv):
|
def test_read_dburi_from_stdin_with_eol(dburi, defaultenv):
|
||||||
"Reading the dburi from stdin containing a newline should work."
|
"Reading the dburi from stdin containing a newline should work."
|
||||||
env = {**defaultenv, "PGRST_DB_URI": "@/dev/stdin"}
|
defaultenv_without_libpq = {
|
||||||
|
key: value
|
||||||
|
for key, value in defaultenv.items()
|
||||||
|
if key not in ["PGDATABASE", "PGHOST", "PGUSER"]
|
||||||
|
}
|
||||||
|
env = {**defaultenv_without_libpq, "PGRST_DB_URI": "@/dev/stdin"}
|
||||||
|
|
||||||
with run(env=env, stdin=dburi + b"\n"):
|
with run(env=env, stdin=dburi + b"\n"):
|
||||||
pass
|
pass
|
||||||
@@ -802,12 +823,9 @@ def test_admin_ready_wo_channel(defaultenv):
|
|||||||
def test_admin_ready_includes_schema_cache_state(defaultenv):
|
def test_admin_ready_includes_schema_cache_state(defaultenv):
|
||||||
"Should get a failed response from the admin server ready endpoint when the schema cache is not loaded"
|
"Should get a failed response from the admin server ready endpoint when the schema cache is not loaded"
|
||||||
|
|
||||||
db_uri = defaultenv["PGRST_DB_URI"].replace(
|
|
||||||
"postgrest_test_authenticator", "limited_authenticator"
|
|
||||||
)
|
|
||||||
env = {
|
env = {
|
||||||
**defaultenv,
|
**defaultenv,
|
||||||
"PGRST_DB_URI": db_uri,
|
"PGUSER": "limited_authenticator",
|
||||||
"PGRST_DB_ANON_ROLE": "limited_authenticator",
|
"PGRST_DB_ANON_ROLE": "limited_authenticator",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-11
@@ -58,22 +58,19 @@ import qualified Feature.UpsertSpec
|
|||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
testDbConn <- getEnvVarWithDefault "PGRST_DB_URI" "postgres://postgrest_test@localhost/postgrest_test"
|
pool <- P.acquire (3, 10, toUtf8 $ configDbUri testCfg)
|
||||||
|
|
||||||
pool <- P.acquire (3, 10, toS testDbConn)
|
|
||||||
|
|
||||||
actualPgVersion <- either (panic.show) id <$> P.use pool queryPgVersion
|
actualPgVersion <- either (panic.show) id <$> P.use pool queryPgVersion
|
||||||
|
|
||||||
baseDbStructure <-
|
baseDbStructure <-
|
||||||
loadDbStructure pool
|
loadDbStructure pool
|
||||||
(configDbSchemas $ testCfg testDbConn)
|
(configDbSchemas testCfg)
|
||||||
(configDbExtraSearchPath $ testCfg testDbConn)
|
(configDbExtraSearchPath testCfg)
|
||||||
actualPgVersion
|
actualPgVersion
|
||||||
|
|
||||||
let
|
let
|
||||||
-- For tests that run with the same refDbStructure
|
-- For tests that run with the same refDbStructure
|
||||||
app cfg = do
|
app config = do
|
||||||
let config = cfg testDbConn
|
|
||||||
appState <- AppState.initWithPool pool config
|
appState <- AppState.initWithPool pool config
|
||||||
AppState.putPgVersion appState actualPgVersion
|
AppState.putPgVersion appState actualPgVersion
|
||||||
AppState.putDbStructure appState (Just baseDbStructure)
|
AppState.putDbStructure appState (Just baseDbStructure)
|
||||||
@@ -82,8 +79,7 @@ main = do
|
|||||||
return ((), postgrest LogCrit appState $ pure ())
|
return ((), postgrest LogCrit appState $ pure ())
|
||||||
|
|
||||||
-- For tests that run with a different DbStructure(depends on configSchemas)
|
-- For tests that run with a different DbStructure(depends on configSchemas)
|
||||||
appDbs cfg = do
|
appDbs config = do
|
||||||
let config = cfg testDbConn
|
|
||||||
customDbStructure <-
|
customDbStructure <-
|
||||||
loadDbStructure pool
|
loadDbStructure pool
|
||||||
(configDbSchemas config)
|
(configDbSchemas config)
|
||||||
@@ -120,8 +116,8 @@ main = do
|
|||||||
|
|
||||||
let analyze :: IO ()
|
let analyze :: IO ()
|
||||||
analyze = do
|
analyze = do
|
||||||
analyzeTable testDbConn "items"
|
analyzeTable "items"
|
||||||
analyzeTable testDbConn "child_entities"
|
analyzeTable "child_entities"
|
||||||
|
|
||||||
specs = uncurry describe <$> [
|
specs = uncurry describe <$> [
|
||||||
("Feature.AndOrParamsSpec" , Feature.AndOrParamsSpec.spec actualPgVersion)
|
("Feature.AndOrParamsSpec" , Feature.AndOrParamsSpec.spec actualPgVersion)
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import qualified Hasql.Transaction as HT
|
|||||||
import qualified Hasql.Transaction.Sessions as HT
|
import qualified Hasql.Transaction.Sessions as HT
|
||||||
import Text.Heredoc
|
import Text.Heredoc
|
||||||
|
|
||||||
import Protolude hiding (get, toS)
|
import Protolude hiding (get, toS)
|
||||||
import Protolude.Conv (toS)
|
|
||||||
|
|
||||||
import PostgREST.Query.QueryBuilder (requestToCallProcQuery)
|
import PostgREST.Query.QueryBuilder (requestToCallProcQuery)
|
||||||
import PostgREST.Request.Types
|
import PostgREST.Request.Types
|
||||||
@@ -20,14 +19,11 @@ import PostgREST.Request.Types
|
|||||||
import PostgREST.DbStructure.Identifiers
|
import PostgREST.DbStructure.Identifiers
|
||||||
import PostgREST.DbStructure.Proc
|
import PostgREST.DbStructure.Proc
|
||||||
|
|
||||||
import SpecHelper (getEnvVarWithDefault)
|
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
testDbConn <- getEnvVarWithDefault "PGRST_DB_URI" "postgres://postgrest_test@localhost/postgrest_test"
|
pool <- P.acquire (3, 10, "postgresql://")
|
||||||
pool <- P.acquire (3, 10, toS testDbConn)
|
|
||||||
|
|
||||||
hspec $ describe "QueryCost" $
|
hspec $ describe "QueryCost" $
|
||||||
context "call proc query" $ do
|
context "call proc query" $ do
|
||||||
|
|||||||
+50
-50
@@ -72,8 +72,8 @@ getEnvVarWithDefault :: Text -> Text -> IO Text
|
|||||||
getEnvVarWithDefault var def = toS <$>
|
getEnvVarWithDefault var def = toS <$>
|
||||||
getEnv (toS var) `E.catchIOError` const (return $ toS def)
|
getEnv (toS var) `E.catchIOError` const (return $ toS def)
|
||||||
|
|
||||||
_baseCfg :: AppConfig
|
baseCfg :: AppConfig
|
||||||
_baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
||||||
AppConfig {
|
AppConfig {
|
||||||
configAppSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ]
|
configAppSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ]
|
||||||
, configDbAnonRole = "postgrest_test_anonymous"
|
, configDbAnonRole = "postgrest_test_anonymous"
|
||||||
@@ -88,7 +88,7 @@ _baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
|||||||
, configDbRootSpec = Nothing
|
, configDbRootSpec = Nothing
|
||||||
, configDbSchemas = fromList ["test"]
|
, configDbSchemas = fromList ["test"]
|
||||||
, configDbConfig = False
|
, configDbConfig = False
|
||||||
, configDbUri = mempty
|
, configDbUri = "postgresql://"
|
||||||
, configDbUseLegacyGucs = True
|
, configDbUseLegacyGucs = True
|
||||||
, configFilePath = Nothing
|
, configFilePath = Nothing
|
||||||
, configJWKS = parseSecret <$> secret
|
, configJWKS = parseSecret <$> secret
|
||||||
@@ -109,90 +109,90 @@ _baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
|||||||
, configAdminServerPort = Nothing
|
, configAdminServerPort = Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
testCfg :: Text -> AppConfig
|
testCfg :: AppConfig
|
||||||
testCfg testDbConn = _baseCfg { configDbUri = testDbConn }
|
testCfg = baseCfg
|
||||||
|
|
||||||
testCfgDisallowRollback :: Text -> AppConfig
|
testCfgDisallowRollback :: AppConfig
|
||||||
testCfgDisallowRollback testDbConn = (testCfg testDbConn) { configDbTxAllowOverride = False, configDbTxRollbackAll = False }
|
testCfgDisallowRollback = baseCfg { configDbTxAllowOverride = False, configDbTxRollbackAll = False }
|
||||||
|
|
||||||
testCfgForceRollback :: Text -> AppConfig
|
testCfgForceRollback :: AppConfig
|
||||||
testCfgForceRollback testDbConn = (testCfg testDbConn) { configDbTxAllowOverride = False, configDbTxRollbackAll = True }
|
testCfgForceRollback = baseCfg { configDbTxAllowOverride = False, configDbTxRollbackAll = True }
|
||||||
|
|
||||||
testCfgNoJWT :: Text -> AppConfig
|
testCfgNoJWT :: AppConfig
|
||||||
testCfgNoJWT testDbConn = (testCfg testDbConn) { configJwtSecret = Nothing, configJWKS = Nothing }
|
testCfgNoJWT = baseCfg { configJwtSecret = Nothing, configJWKS = Nothing }
|
||||||
|
|
||||||
testUnicodeCfg :: Text -> AppConfig
|
testUnicodeCfg :: AppConfig
|
||||||
testUnicodeCfg testDbConn = (testCfg testDbConn) { configDbSchemas = fromList ["تست"] }
|
testUnicodeCfg = baseCfg { configDbSchemas = fromList ["تست"] }
|
||||||
|
|
||||||
testMaxRowsCfg :: Text -> AppConfig
|
testMaxRowsCfg :: AppConfig
|
||||||
testMaxRowsCfg testDbConn = (testCfg testDbConn) { configDbMaxRows = Just 2 }
|
testMaxRowsCfg = baseCfg { configDbMaxRows = Just 2 }
|
||||||
|
|
||||||
testDisabledOpenApiCfg :: Text -> AppConfig
|
testDisabledOpenApiCfg :: AppConfig
|
||||||
testDisabledOpenApiCfg testDbConn = (testCfg testDbConn) { configOpenApiMode = OADisabled }
|
testDisabledOpenApiCfg = baseCfg { configOpenApiMode = OADisabled }
|
||||||
|
|
||||||
testIgnorePrivOpenApiCfg :: Text -> AppConfig
|
testIgnorePrivOpenApiCfg :: AppConfig
|
||||||
testIgnorePrivOpenApiCfg testDbConn = (testCfg testDbConn) { configOpenApiMode = OAIgnorePriv, configDbSchemas = fromList ["test", "v1"] }
|
testIgnorePrivOpenApiCfg = baseCfg { configOpenApiMode = OAIgnorePriv, configDbSchemas = fromList ["test", "v1"] }
|
||||||
|
|
||||||
testProxyCfg :: Text -> AppConfig
|
testProxyCfg :: AppConfig
|
||||||
testProxyCfg testDbConn = (testCfg testDbConn) { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
testProxyCfg = baseCfg { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
||||||
|
|
||||||
testCfgBinaryJWT :: Text -> AppConfig
|
testCfgBinaryJWT :: AppConfig
|
||||||
testCfgBinaryJWT testDbConn =
|
testCfgBinaryJWT =
|
||||||
let secret = Just . B64.decodeLenient $ "cmVhbGx5cmVhbGx5cmVhbGx5cmVhbGx5dmVyeXNhZmU=" in
|
let secret = Just . B64.decodeLenient $ "cmVhbGx5cmVhbGx5cmVhbGx5cmVhbGx5dmVyeXNhZmU=" in
|
||||||
(testCfg testDbConn) {
|
baseCfg {
|
||||||
configJwtSecret = secret
|
configJwtSecret = secret
|
||||||
, configJWKS = parseSecret <$> secret
|
, configJWKS = parseSecret <$> secret
|
||||||
}
|
}
|
||||||
|
|
||||||
testCfgAudienceJWT :: Text -> AppConfig
|
testCfgAudienceJWT :: AppConfig
|
||||||
testCfgAudienceJWT testDbConn =
|
testCfgAudienceJWT =
|
||||||
let secret = Just . B64.decodeLenient $ "cmVhbGx5cmVhbGx5cmVhbGx5cmVhbGx5dmVyeXNhZmU=" in
|
let secret = Just . B64.decodeLenient $ "cmVhbGx5cmVhbGx5cmVhbGx5cmVhbGx5dmVyeXNhZmU=" in
|
||||||
(testCfg testDbConn) {
|
baseCfg {
|
||||||
configJwtSecret = secret
|
configJwtSecret = secret
|
||||||
, configJwtAudience = Just "youraudience"
|
, configJwtAudience = Just "youraudience"
|
||||||
, configJWKS = parseSecret <$> secret
|
, configJWKS = parseSecret <$> secret
|
||||||
}
|
}
|
||||||
|
|
||||||
testCfgAsymJWK :: Text -> AppConfig
|
testCfgAsymJWK :: AppConfig
|
||||||
testCfgAsymJWK testDbConn =
|
testCfgAsymJWK =
|
||||||
let secret = Just $ encodeUtf8 [str|{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}|]
|
let secret = Just $ encodeUtf8 [str|{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}|]
|
||||||
in (testCfg testDbConn) {
|
in baseCfg {
|
||||||
configJwtSecret = secret
|
configJwtSecret = secret
|
||||||
, configJWKS = parseSecret <$> secret
|
, configJWKS = parseSecret <$> secret
|
||||||
}
|
}
|
||||||
|
|
||||||
testCfgAsymJWKSet :: Text -> AppConfig
|
testCfgAsymJWKSet :: AppConfig
|
||||||
testCfgAsymJWKSet testDbConn =
|
testCfgAsymJWKSet =
|
||||||
let secret = Just $ encodeUtf8 [str|{"keys": [{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}]}|]
|
let secret = Just $ encodeUtf8 [str|{"keys": [{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}]}|]
|
||||||
in (testCfg testDbConn) {
|
in baseCfg {
|
||||||
configJwtSecret = secret
|
configJwtSecret = secret
|
||||||
, configJWKS = parseSecret <$> secret
|
, configJWKS = parseSecret <$> secret
|
||||||
}
|
}
|
||||||
|
|
||||||
testNonexistentSchemaCfg :: Text -> AppConfig
|
testNonexistentSchemaCfg :: AppConfig
|
||||||
testNonexistentSchemaCfg testDbConn = (testCfg testDbConn) { configDbSchemas = fromList ["nonexistent"] }
|
testNonexistentSchemaCfg = baseCfg { configDbSchemas = fromList ["nonexistent"] }
|
||||||
|
|
||||||
testCfgExtraSearchPath :: Text -> AppConfig
|
testCfgExtraSearchPath :: AppConfig
|
||||||
testCfgExtraSearchPath testDbConn = (testCfg testDbConn) { configDbExtraSearchPath = ["public", "extensions"] }
|
testCfgExtraSearchPath = baseCfg { configDbExtraSearchPath = ["public", "extensions"] }
|
||||||
|
|
||||||
testCfgRootSpec :: Text -> AppConfig
|
testCfgRootSpec :: AppConfig
|
||||||
testCfgRootSpec testDbConn = (testCfg testDbConn) { configDbRootSpec = Just $ QualifiedIdentifier mempty "root"}
|
testCfgRootSpec = baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root"}
|
||||||
|
|
||||||
testCfgHtmlRawOutput :: Text -> AppConfig
|
testCfgHtmlRawOutput :: AppConfig
|
||||||
testCfgHtmlRawOutput testDbConn = (testCfg testDbConn) { configRawMediaTypes = ["text/html"] }
|
testCfgHtmlRawOutput = baseCfg { configRawMediaTypes = ["text/html"] }
|
||||||
|
|
||||||
testCfgResponseHeaders :: Text -> AppConfig
|
testCfgResponseHeaders :: AppConfig
|
||||||
testCfgResponseHeaders testDbConn = (testCfg testDbConn) { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" }
|
testCfgResponseHeaders = baseCfg { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" }
|
||||||
|
|
||||||
testMultipleSchemaCfg :: Text -> AppConfig
|
testMultipleSchemaCfg :: AppConfig
|
||||||
testMultipleSchemaCfg testDbConn = (testCfg testDbConn) { configDbSchemas = fromList ["v1", "v2"] }
|
testMultipleSchemaCfg = baseCfg { configDbSchemas = fromList ["v1", "v2"] }
|
||||||
|
|
||||||
testCfgLegacyGucs :: Text -> AppConfig
|
testCfgLegacyGucs :: AppConfig
|
||||||
testCfgLegacyGucs testDbConn = (testCfg testDbConn) { configDbUseLegacyGucs = False }
|
testCfgLegacyGucs = baseCfg { configDbUseLegacyGucs = False }
|
||||||
|
|
||||||
analyzeTable :: Text -> Text -> IO ()
|
analyzeTable :: Text -> IO ()
|
||||||
analyzeTable dbConn tableName =
|
analyzeTable tableName =
|
||||||
void $ readProcess "psql" ["--set", "ON_ERROR_STOP=1", toS dbConn, "-a", "-c", toS $ "ANALYZE test.\"" <> tableName <> "\""] []
|
void $ readProcess "psql" ["--set", "ON_ERROR_STOP=1", "-a", "-c", toS $ "ANALYZE test.\"" <> tableName <> "\""] []
|
||||||
|
|
||||||
rangeHdrs :: ByteRange -> [Header]
|
rangeHdrs :: ByteRange -> [Header]
|
||||||
rangeHdrs r = [rangeUnit, (hRange, renderByteRange r)]
|
rangeHdrs r = [rangeUnit, (hRange, renderByteRange r)]
|
||||||
|
|||||||
Reference in New Issue
Block a user