Skip to content

Commit

Permalink
Correct hardcoded postgrest_test_authenticator (#1743)
Browse files Browse the repository at this point in the history
Also remove panic from Config and correct io test not running
  • Loading branch information
steve-chavez authored Jan 25, 2021
1 parent 6557f1f commit c93e8f9
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 14 deletions.
11 changes: 4 additions & 7 deletions src/PostgREST/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import Development.GitRev (gitHash)
import Numeric (readOct, showOct)
import Paths_postgrest (version)
import System.Environment (getEnvironment)
import System.IO.Error (IOError)
import System.Posix.Types (FileMode)

import Control.Applicative
Expand Down Expand Up @@ -334,14 +333,12 @@ readAppConfig :: [(Text, Text)] -> Environment -> Maybe FilePath -> IO (Either T
readAppConfig dbSettings env optPath = do
-- Now read the actual config file
conf <- case optPath of
Just cfgPath -> C.load cfgPath `catches`
[ Handler (\(ex :: IOError) -> panic $ "Cannot open config file: " <> show ex)
, Handler (\(C.ParseError err) -> panic $ "Error parsing config file: " <> err)
]
-- Both C.ParseError and IOError are shown here
Just cfgPath -> mapLeft show <$> (try $ C.load cfgPath :: IO (Either SomeException C.Config))
-- if no filename provided, start with an empty map to read config from environment
Nothing -> return M.empty
Nothing -> return $ Right M.empty

pure $ mapLeft ("Error in config: " <>) $ C.runParser parseConfig conf
pure $ mapLeft ("Error in config: " <>) $ C.runParser parseConfig =<< conf

where
parseConfig =
Expand Down
2 changes: 1 addition & 1 deletion src/PostgREST/Statements.hs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ dbSettingsStatement = H.Statement sql HE.noParams decodeSettings False
sql = [q|
with
role_setting as (
select unnest(setconfig) as setting from pg_catalog.pg_db_role_setting where setrole = 'postgrest_test_authenticator'::regrole::oid
select unnest(setconfig) as setting from pg_catalog.pg_db_role_setting where setrole = current_user::regrole::oid
),
kv_settings as (
select split_part(setting, '=', 1) as key, split_part(setting, '=', 2) as value from role_setting
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/roles.sql
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,19 @@ ALTER ROLE postgrest_test_authenticator SET pgrst."db-channel" = 'ignored';
ALTER ROLE postgrest_test_authenticator SET pgrst."db-pool" = 'ignored';
ALTER ROLE postgrest_test_authenticator SET pgrst."db-pool-timeout" = 'ignored';
ALTER ROLE postgrest_test_authenticator SET pgrst."db-load-guc-config" = 'ignored';

-- other authenticator reloadable config options for io tests
CREATE ROLE other_authenticator LOGIN NOINHERIT;
ALTER ROLE other_authenticator SET pgrst."jwt-aud" = 'https://otherexample.org';
ALTER ROLE other_authenticator SET pgrst."openapi-server-proxy-uri" = 'https://otherexample.org/api';
ALTER ROLE other_authenticator SET pgrst."raw-media-types" = 'application/vnd.pgrst.other-db-config';
ALTER ROLE other_authenticator SET pgrst."jwt-secret" = 'ODERREALLYREALLYREALLYREALLYVERYSAFE';
ALTER ROLE other_authenticator SET pgrst."jwt-secret-is-base64" = 'true';
ALTER ROLE other_authenticator SET pgrst."jwt-role-claim-key" = '."other"."role"';
ALTER ROLE other_authenticator SET pgrst."db-tx-end" = 'rollback-allow-override';
ALTER ROLE other_authenticator SET pgrst."db-schemas" = 'test, other_tenant1, other_tenant2';
ALTER ROLE other_authenticator SET pgrst."db-root-spec" = 'other_root';
ALTER ROLE other_authenticator SET pgrst."db-prepared-statements" = 'false';
ALTER ROLE other_authenticator SET pgrst."db-pre-request" = 'test.other_custom_headers';
ALTER ROLE other_authenticator SET pgrst."db-max-rows" = '100';
ALTER ROLE other_authenticator SET pgrst."db-extra-search-path" = 'public, extensions, other';
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
db-anon-role = "postgrest_test_anonymous"
db-channel = "postgrest"
db-channel-enabled = true
db-extra-search-path = "public,extensions,other"
db-max-rows = 100
db-pool = 1
db-pool-timeout = 100
db-pre-request = "test.other_custom_headers"
db-prepared-statements = false
db-root-spec = "other_root"
db-schemas = "test,other_tenant1,other_tenant2"
db-load-guc-config = "true"
db-tx-end = "rollback-allow-override"
db-uri = "<REPLACED_WITH_DB_URI>"
jwt-aud = "https://otherexample.org"
jwt-role-claim-key = ".\"other\".\"role\""
jwt-secret = "ODERREALLYREALLYREALLYREALLYVERYSAFE"
jwt-secret-is-base64 = true
log-level = "info"
openapi-server-proxy-uri = "https://otherexample.org/api"
raw-media-types = "application/vnd.pgrst.other-db-config"
server-host = "0.0.0.0"
server-port = 80
server-unix-socket = "/tmp/pgrst_io_test.sock"
server-unix-socket-mode = "777"
app.settings.test = "test"
app.settings.test2 = "test"
27 changes: 21 additions & 6 deletions test/io-tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ def run(configpath=None, stdin=None, env=None, port=None):
if configpath:
command.append(configpath)

process = subprocess.Popen(command, stdin=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
process = subprocess.Popen(
command, stdin=subprocess.PIPE, stderr=subprocess.PIPE, env=env
)

try:
process.stdin.write(stdin or b"")
Expand Down Expand Up @@ -267,23 +269,34 @@ def test_expected_config_from_environment():
assert dumpconfig(env=env) == expected


def test_expected_config_from_db_settings(defaultenv):
@pytest.mark.parametrize(
"role, expectedconfig",
[
("postgrest_test_authenticator", "no-defaults-with-db.config"),
("other_authenticator", "no-defaults-with-db-other-authenticator.config"),
],
)
def test_expected_config_from_db_settings(defaultenv, role, expectedconfig):
"Config should be overriden from database settings"

config = CONFIGSDIR / "no-defaults.config"

db_uri = defaultenv["PGRST_DB_URI"].replace(
"user=postgrest_test_authenticator", f"user={role}"
)
env = {
**defaultenv,
"PGRST_DB_URI": db_uri,
"PGRST_DB_LOAD_GUC_CONFIG": "true",
}
expected = (
(CONFIGSDIR / "expected" / "no-defaults-with-db.config")
(CONFIGSDIR / "expected" / expectedconfig)
.read_text()
.replace("<REPLACED_WITH_DB_URI>", env["PGRST_DB_URI"])
)

assert dumpconfig(configpath=config, env=env) == expected


@pytest.mark.parametrize(
"config",
[conf for conf in CONFIGSDIR.iterdir() if conf.suffix == ".config"],
Expand Down Expand Up @@ -591,7 +604,7 @@ def test_max_rows_notify_reload(defaultenv):
# reset max-rows config on the db
postgrest.session.post("/rpc/reset_max_rows_config")

def invalid_role_claim_key_notify_reload(defaultenv):
def test_invalid_role_claim_key_notify_reload(defaultenv):
"NOTIFY reload config should show an error if role-claim-key is invalid"

env = {
Expand All @@ -603,6 +616,8 @@ def invalid_role_claim_key_notify_reload(defaultenv):
with run(env=env) as postgrest:
postgrest.session.post("/rpc/invalid_role_claim_key_reload")

assert "failed to parse role-claim-key value" in str(postgrest.process.stderr.readline())
assert "failed to parse role-claim-key value" in str(
postgrest.process.stderr.readline()
)

postgrest.session.post("/rpc/reset_invalid_role_claim_key")

0 comments on commit c93e8f9

Please sign in to comment.