From ec09b87940aec36942267e91d3e073797c5d4fe5 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sun, 16 Jan 2022 12:37:18 +0100 Subject: [PATCH] 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. --- test/io/configs/aliases.config | 1 - test/io/configs/app-settings.config | 2 - .../io/configs/base64-secret-from-file.config | 4 - test/io/configs/boolean-numeric.config | 1 - test/io/configs/boolean-string.config | 1 - test/io/configs/dburi-from-file.config | 3 - test/io/configs/expected/aliases.config | 2 +- .../configs/expected/boolean-numeric.config | 2 +- .../io/configs/expected/boolean-string.config | 2 +- test/io/configs/role-claim-key.config | 3 - test/io/configs/secret-from-file.config | 4 - .../sigusr2-settings-external-secret.config | 3 - test/io/configs/sigusr2-settings.config | 1 - test/io/configs/simple.config | 2 - test/io/test_io.py | 93 +++++++++++++------ 15 files changed, 66 insertions(+), 58 deletions(-) delete mode 100644 test/io/configs/app-settings.config delete mode 100644 test/io/configs/base64-secret-from-file.config delete mode 100644 test/io/configs/dburi-from-file.config delete mode 100644 test/io/configs/role-claim-key.config delete mode 100644 test/io/configs/secret-from-file.config delete mode 100644 test/io/configs/sigusr2-settings-external-secret.config delete mode 100644 test/io/configs/simple.config diff --git a/test/io/configs/aliases.config b/test/io/configs/aliases.config index d22999fc2..6a858f333 100644 --- a/test/io/configs/aliases.config +++ b/test/io/configs/aliases.config @@ -7,4 +7,3 @@ pre-request = "check_alias" role-claim-key = ".aliased" root-spec = "open_alias" secret-is-base64 = true -db-config = false diff --git a/test/io/configs/app-settings.config b/test/io/configs/app-settings.config deleted file mode 100644 index 65408c91d..000000000 --- a/test/io/configs/app-settings.config +++ /dev/null @@ -1,2 +0,0 @@ -app.settings.external_api_secret = "0123456789abcdef" -db-config = false diff --git a/test/io/configs/base64-secret-from-file.config b/test/io/configs/base64-secret-from-file.config deleted file mode 100644 index d31f6f5d8..000000000 --- a/test/io/configs/base64-secret-from-file.config +++ /dev/null @@ -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 diff --git a/test/io/configs/boolean-numeric.config b/test/io/configs/boolean-numeric.config index 315e546c1..6dbe6c88e 100644 --- a/test/io/configs/boolean-numeric.config +++ b/test/io/configs/boolean-numeric.config @@ -5,4 +5,3 @@ db-anon-role = "required" db-channel-enabled = "1" db-prepared-statements = "0" jwt-secret-is-base64 = "2" -db-config = false diff --git a/test/io/configs/boolean-string.config b/test/io/configs/boolean-string.config index 0a4c68ff4..f7967cd4f 100644 --- a/test/io/configs/boolean-string.config +++ b/test/io/configs/boolean-string.config @@ -5,4 +5,3 @@ db-anon-role = "required" db-channel-enabled = "true" db-prepared-statements = "FALSE" jwt-secret-is-base64 = "\"true\"" -db-config = false diff --git a/test/io/configs/dburi-from-file.config b/test/io/configs/dburi-from-file.config deleted file mode 100644 index a9d8441b0..000000000 --- a/test/io/configs/dburi-from-file.config +++ /dev/null @@ -1,3 +0,0 @@ -db-uri = "@/dev/stdin" -jwt-secret = "reallyreallyreallyreallyverysafe" -db-config = false diff --git a/test/io/configs/expected/aliases.config b/test/io/configs/expected/aliases.config index 4ca5c65b9..b0d05fb1a 100644 --- a/test/io/configs/expected/aliases.config +++ b/test/io/configs/expected/aliases.config @@ -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 diff --git a/test/io/configs/expected/boolean-numeric.config b/test/io/configs/expected/boolean-numeric.config index 3be0ecc9d..80ea52215 100644 --- a/test/io/configs/expected/boolean-numeric.config +++ b/test/io/configs/expected/boolean-numeric.config @@ -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 diff --git a/test/io/configs/expected/boolean-string.config b/test/io/configs/expected/boolean-string.config index 3be0ecc9d..80ea52215 100644 --- a/test/io/configs/expected/boolean-string.config +++ b/test/io/configs/expected/boolean-string.config @@ -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 diff --git a/test/io/configs/role-claim-key.config b/test/io/configs/role-claim-key.config deleted file mode 100644 index dc22cf7ae..000000000 --- a/test/io/configs/role-claim-key.config +++ /dev/null @@ -1,3 +0,0 @@ -jwt-role-claim-key = "$(ROLE_CLAIM_KEY)" -jwt-secret = "reallyreallyreallyreallyverysafe" -db-config = false diff --git a/test/io/configs/secret-from-file.config b/test/io/configs/secret-from-file.config deleted file mode 100644 index 6be2deee4..000000000 --- a/test/io/configs/secret-from-file.config +++ /dev/null @@ -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 diff --git a/test/io/configs/sigusr2-settings-external-secret.config b/test/io/configs/sigusr2-settings-external-secret.config deleted file mode 100644 index b3fe854e3..000000000 --- a/test/io/configs/sigusr2-settings-external-secret.config +++ /dev/null @@ -1,3 +0,0 @@ -jwt-secret = "$(JWT_SECRET_FILE)" -jwt-secret-is-base64 = false -db-config = false diff --git a/test/io/configs/sigusr2-settings.config b/test/io/configs/sigusr2-settings.config index cc14ac709..1baab06de 100644 --- a/test/io/configs/sigusr2-settings.config +++ b/test/io/configs/sigusr2-settings.config @@ -2,4 +2,3 @@ db-schemas = "public" app.settings.name_var = "John" jwt-secret = "invalidinvalidinvalidinvalidinvalid" -db-config = false diff --git a/test/io/configs/simple.config b/test/io/configs/simple.config deleted file mode 100644 index b5833825e..000000000 --- a/test/io/configs/simple.config +++ /dev/null @@ -1,2 +0,0 @@ -jwt-secret = "reallyreallyreallyreallyverysafe" -db-config = false diff --git a/test/io/test_io.py b/test/io/test_io.py index 0c7c66e64..7f613e164 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -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/*"