test: Make io tests use environment variables instead of config files where possible.

Load jwt secret from file instead of stdin in tests, because stdin is not supported when reloading the config. Resolves #2126.
This commit is contained in:
Wolfgang Walther
2022-01-22 15:10:25 +01:00
parent 6b5370f145
commit ec09b87940
15 changed files with 66 additions and 58 deletions
-1
View File
@@ -7,4 +7,3 @@ pre-request = "check_alias"
role-claim-key = ".aliased"
root-spec = "open_alias"
secret-is-base64 = true
db-config = false
-2
View File
@@ -1,2 +0,0 @@
app.settings.external_api_secret = "0123456789abcdef"
db-config = false
@@ -1,4 +0,0 @@
# Read secret from a file: /dev/stdin (alias for standard input)
jwt-secret = "@/dev/stdin"
jwt-secret-is-base64 = true
db-config = false
-1
View File
@@ -5,4 +5,3 @@ db-anon-role = "required"
db-channel-enabled = "1"
db-prepared-statements = "0"
jwt-secret-is-base64 = "2"
db-config = false
-1
View File
@@ -5,4 +5,3 @@ db-anon-role = "required"
db-channel-enabled = "true"
db-prepared-statements = "FALSE"
jwt-secret-is-base64 = "\"true\""
db-config = false
-3
View File
@@ -1,3 +0,0 @@
db-uri = "@/dev/stdin"
jwt-secret = "reallyreallyreallyreallyverysafe"
db-config = false
+1 -1
View File
@@ -9,7 +9,7 @@ db-pre-request = "check_alias"
db-prepared-statements = true
db-root-spec = "open_alias"
db-schemas = "provided_through_alias"
db-config = false
db-config = true
db-tx-end = "commit"
db-uri = "required"
db-use-legacy-gucs = true
@@ -9,7 +9,7 @@ db-pre-request = ""
db-prepared-statements = false
db-root-spec = ""
db-schemas = "required"
db-config = false
db-config = true
db-tx-end = "commit"
db-uri = "required"
db-use-legacy-gucs = true
@@ -9,7 +9,7 @@ db-pre-request = ""
db-prepared-statements = false
db-root-spec = ""
db-schemas = "required"
db-config = false
db-config = true
db-tx-end = "commit"
db-uri = "required"
db-use-legacy-gucs = true
-3
View File
@@ -1,3 +0,0 @@
jwt-role-claim-key = "$(ROLE_CLAIM_KEY)"
jwt-secret = "reallyreallyreallyreallyverysafe"
db-config = false
-4
View File
@@ -1,4 +0,0 @@
# Read secret from a file: /dev/stdin (alias for standard input)
jwt-secret = "@/dev/stdin"
jwt-secret-is-base64 = false
db-config = false
@@ -1,3 +0,0 @@
jwt-secret = "$(JWT_SECRET_FILE)"
jwt-secret-is-base64 = false
db-config = false
-1
View File
@@ -2,4 +2,3 @@ db-schemas = "public"
app.settings.name_var = "John"
jwt-secret = "invalidinvalidinvalidinvalidinvalid"
db-config = false
-2
View File
@@ -1,2 +0,0 @@
jwt-secret = "reallyreallyreallyreallyverysafe"
db-config = false
+63 -30
View File
@@ -375,32 +375,62 @@ def test_port_connection(defaultenv):
)
def test_read_secret_from_file(secretpath, defaultenv):
"Authorization should succeed when the secret is read from a file."
env = {**defaultenv, "PGRST_JWT_SECRET": f"@{secretpath}"}
if secretpath.suffix == ".b64":
configfile = CONFIGSDIR / "base64-secret-from-file.config"
else:
configfile = CONFIGSDIR / "secret-from-file.config"
env["PGRST_JWT_SECRET_IS_BASE64"] = "true"
secret = secretpath.read_bytes()
headers = authheader(secretpath.with_suffix(".jwt").read_text())
with run(configfile, stdin=secret, env=defaultenv) as postgrest:
with run(stdin=secret, env=env) as postgrest:
response = postgrest.session.get("/authors_only", headers=headers)
assert response.status_code == 200
def test_read_dburi_from_file_without_eol(dburi, defaultenv):
"Reading the dburi from a file with a single line should work."
config = CONFIGSDIR / "dburi-from-file.config"
env = {key: value for key, value in defaultenv.items() if key != "PGRST_DB_URI"}
with run(config, env=env, stdin=dburi):
def test_read_secret_from_stdin(defaultenv):
"Authorization should succeed when the secret is read from stdin."
env = {**defaultenv, "PGRST_DB_CONFIG": "false", "PGRST_JWT_SECRET": "@/dev/stdin"}
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET)
with run(stdin=SECRET.encode(), env=env) as postgrest:
response = postgrest.session.get("/authors_only", headers=headers)
print(response.text)
assert response.status_code == 200
# TODO: This test would fail right now, because of
# https://github.com/PostgREST/postgrest/issues/2126
@pytest.mark.skip
def test_read_secret_from_stdin_dbconfig(defaultenv):
"Authorization should succeed when the secret is read from stdin with db-config=true."
env = {**defaultenv, "PGRST_DB_CONFIG": "true", "PGRST_JWT_SECRET": "@/dev/stdin"}
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET)
with run(stdin=SECRET.encode(), env=env) as postgrest:
response = postgrest.session.get("/authors_only", headers=headers)
print(response.text)
assert response.status_code == 200
def test_read_dburi_from_stdin_without_eol(dburi, defaultenv):
"Reading the dburi from stdin with a single line should work."
env = {**defaultenv, "PGRST_DB_URI": "@/dev/stdin"}
with run(env=env, stdin=dburi):
pass
def test_read_dburi_from_file_with_eol(dburi, defaultenv):
"Reading the dburi from a file containing a newline should work."
config = CONFIGSDIR / "dburi-from-file.config"
env = {key: value for key, value in defaultenv.items() if key != "PGRST_DB_URI"}
with run(config, env=env, stdin=dburi + b"\n"):
def test_read_dburi_from_stdin_with_eol(dburi, defaultenv):
"Reading the dburi from stdin containing a newline should work."
env = {**defaultenv, "PGRST_DB_URI": "@/dev/stdin"}
with run(env=env, stdin=dburi + b"\n"):
pass
@@ -411,11 +441,12 @@ def test_role_claim_key(roleclaim, defaultenv):
"Authorization should depend on a correct role-claim-key and JWT claim."
env = {
**defaultenv,
"ROLE_CLAIM_KEY": roleclaim["key"],
"PGRST_JWT_ROLE_CLAIM_KEY": roleclaim["key"],
"PGRST_JWT_SECRET": SECRET,
}
headers = jwtauthheader(roleclaim["data"], SECRET)
with run(CONFIGSDIR / "role-claim-key.config", env=env) as postgrest:
with run(env=env) as postgrest:
response = postgrest.session.get("/authors_only", headers=headers)
assert response.status_code == roleclaim["expected_status"]
@@ -425,11 +456,11 @@ def test_invalid_role_claim_key(invalidroleclaimkey, defaultenv):
"Given an invalid role-claim-key, Postgrest should exit with a non-zero exit code."
env = {
**defaultenv,
"ROLE_CLAIM_KEY": invalidroleclaimkey,
"PGRST_JWT_ROLE_CLAIM_KEY": invalidroleclaimkey,
}
with pytest.raises(PostgrestError):
dump = dumpconfig(CONFIGSDIR / "role-claim-key.config", env=env)
dump = dumpconfig(env=env)
for line in dump.split("\n"):
if line.startswith("jwt-role-claim-key"):
print(line)
@@ -458,10 +489,13 @@ def test_iat_claim(defaultenv):
https://github.com/PostgREST/postgrest/issues/1139
"""
env = {**defaultenv, "PGRST_JWT_SECRET": SECRET}
claim = {"role": "postgrest_test_author", "iat": datetime.utcnow()}
headers = jwtauthheader(claim, SECRET)
with run(CONFIGSDIR / "simple.config", env=defaultenv) as postgrest:
with run(env=env) as postgrest:
for _ in range(10):
response = postgrest.session.get("/authors_only", headers=headers)
assert response.status_code == 200
@@ -476,7 +510,10 @@ def test_app_settings(defaultenv):
See: https://github.com/PostgREST/postgrest/issues/1141
"""
with run(CONFIGSDIR / "app-settings.config", env=defaultenv) as postgrest:
env = {**defaultenv, "PGRST_APP_SETTINGS_EXTERNAL_API_SECRET": "0123456789abcdef"}
with run(env=env) as postgrest:
# Wait for the db pool to time out, set to 1s in config
time.sleep(2)
@@ -487,7 +524,7 @@ def test_app_settings(defaultenv):
def test_app_settings_reload(tmp_path, defaultenv):
"App settings should be reloaded when PostgREST is sent SIGUSR2."
"App settings should be reloaded from file when PostgREST is sent SIGUSR2."
config = (CONFIGSDIR / "sigusr2-settings.config").read_text()
configfile = tmp_path / "test.config"
configfile.write_text(config)
@@ -509,7 +546,7 @@ def test_app_settings_reload(tmp_path, defaultenv):
def test_jwt_secret_reload(tmp_path, defaultenv):
"JWT secret should be reloaded when PostgREST is sent SIGUSR2."
"JWT secret should be reloaded from file when PostgREST is sent SIGUSR2."
config = (CONFIGSDIR / "sigusr2-settings.config").read_text()
configfile = tmp_path / "test.config"
configfile.write_text(config)
@@ -534,8 +571,6 @@ def test_jwt_secret_reload(tmp_path, defaultenv):
def test_jwt_secret_external_file_reload(tmp_path, defaultenv):
"JWT secret external file should be reloaded when PostgREST is sent a SIGUSR2 or a NOTIFY."
config = CONFIGSDIR / "sigusr2-settings-external-secret.config"
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET)
external_secret_file = tmp_path / "jwt-secret-config"
@@ -543,11 +578,11 @@ def test_jwt_secret_external_file_reload(tmp_path, defaultenv):
env = {
**defaultenv,
"JWT_SECRET_FILE": f"@{external_secret_file}",
"PGRST_JWT_SECRET": f"@{external_secret_file}",
"PGRST_DB_CHANNEL_ENABLED": "true",
}
with run(config, env=env) as postgrest:
with run(env=env) as postgrest:
response = postgrest.session.get("/authors_only", headers=headers)
assert response.status_code == 401
@@ -580,7 +615,7 @@ def test_jwt_secret_external_file_reload(tmp_path, defaultenv):
def test_db_schema_reload(tmp_path, defaultenv):
"DB schema should be reloaded when PostgREST is sent SIGUSR2."
"DB schema should be reloaded from file when PostgREST is sent SIGUSR2."
config = (CONFIGSDIR / "sigusr2-settings.config").read_text()
configfile = tmp_path / "test.config"
configfile.write_text(config)
@@ -634,14 +669,12 @@ def test_db_schema_notify_reload(defaultenv):
def test_max_rows_reload(defaultenv):
"max-rows should be reloaded from role settings when PostgREST receives a SIGUSR2."
config = CONFIGSDIR / "sigusr2-settings.config"
env = {
**defaultenv,
"PGRST_DB_CONFIG": "true",
}
with run(config, env=env) as postgrest:
with run(env=env) as postgrest:
response = postgrest.session.head("/projects")
assert response.status_code == 200
assert response.headers["Content-Range"] == "0-4/*"