Restrict db settings to current db and global
Global settings are overriden by database specific settings if they share common ones.
This commit is contained in:
committed by
Steve Chavez
parent
e4516ab606
commit
6750a5c44d
@@ -195,18 +195,23 @@ decodeGucHeaders = first (const GucHeadersError) . JSON.eitherDecode . toS <$> H
|
|||||||
decodeGucStatus :: HD.Value (Either Error (Maybe Status))
|
decodeGucStatus :: HD.Value (Either Error (Maybe Status))
|
||||||
decodeGucStatus = first (const GucStatusError) . fmap (Just . toEnum . fst) . decimal <$> HD.text
|
decodeGucStatus = first (const GucStatusError) . fmap (Just . toEnum . fst) . decimal <$> HD.text
|
||||||
|
|
||||||
-- | Get db settings from the connection role. Only used for configuration.
|
-- | Get db settings from the connection role. Global settings will be overridden by database specific settings.
|
||||||
dbSettingsStatement :: H.Statement () [(Text, Text)]
|
dbSettingsStatement :: H.Statement () [(Text, Text)]
|
||||||
dbSettingsStatement = H.Statement sql HE.noParams decodeSettings False
|
dbSettingsStatement = H.Statement sql HE.noParams decodeSettings False
|
||||||
where
|
where
|
||||||
sql = [q|
|
sql = [q|
|
||||||
with
|
with
|
||||||
role_setting as (
|
role_setting as (
|
||||||
select unnest(setconfig) as setting from pg_catalog.pg_db_role_setting where setrole = current_user::regrole::oid
|
select setdatabase, unnest(setconfig) as setting from pg_catalog.pg_db_role_setting
|
||||||
|
where setrole = current_user::regrole::oid
|
||||||
|
and setdatabase in (0, (select oid from pg_catalog.pg_database where datname = current_catalog))
|
||||||
),
|
),
|
||||||
kv_settings as (
|
kv_settings as (
|
||||||
select split_part(setting, '=', 1) as key, split_part(setting, '=', 2) as value from role_setting
|
select setdatabase, split_part(setting, '=', 1) as k, split_part(setting, '=', 2) as value from role_setting
|
||||||
|
where setting like 'pgrst.%'
|
||||||
)
|
)
|
||||||
select replace(key, 'pgrst.', '') as key, value from kv_settings where key like 'pgrst.%';
|
select distinct on (key) replace(k, 'pgrst.', '') as key, value
|
||||||
|
from kv_settings
|
||||||
|
order by key, setdatabase desc;
|
||||||
|]
|
|]
|
||||||
decodeSettings = HD.rowList $ (,) <$> column HD.text <*> column HD.text
|
decodeSettings = HD.rowList $ (,) <$> column HD.text <*> column HD.text
|
||||||
|
|||||||
Vendored
+9
@@ -21,6 +21,15 @@ ALTER ROLE postgrest_test_authenticator SET pgrst."db_pre_request" = 'test.custo
|
|||||||
ALTER ROLE postgrest_test_authenticator SET pgrst."db_max_rows" = '1000';
|
ALTER ROLE postgrest_test_authenticator SET pgrst."db_max_rows" = '1000';
|
||||||
ALTER ROLE postgrest_test_authenticator SET pgrst."db_extra_search_path" = 'public, extensions';
|
ALTER ROLE postgrest_test_authenticator SET pgrst."db_extra_search_path" = 'public, extensions';
|
||||||
|
|
||||||
|
-- override with database specific setting
|
||||||
|
ALTER ROLE postgrest_test_authenticator IN DATABASE :DBNAME SET pgrst."jwt_secret" = 'OVERRIDEREALLYREALLYREALLYREALLYVERYSAFE';
|
||||||
|
ALTER ROLE postgrest_test_authenticator IN DATABASE :DBNAME SET pgrst."db_extra_search_path" = 'public, extensions, private';
|
||||||
|
|
||||||
|
-- other database settings that should be ignored
|
||||||
|
DROP DATABASE IF EXISTS other;
|
||||||
|
CREATE DATABASE other;
|
||||||
|
ALTER ROLE postgrest_test_authenticator IN DATABASE other SET pgrst."db_max_rows" = '1111';
|
||||||
|
|
||||||
-- non-reloadable configs for io tests
|
-- non-reloadable configs for io tests
|
||||||
ALTER ROLE postgrest_test_authenticator SET pgrst."server_host" = 'ignored';
|
ALTER ROLE postgrest_test_authenticator SET pgrst."server_host" = 'ignored';
|
||||||
ALTER ROLE postgrest_test_authenticator SET pgrst."server_port" = 'ignored';
|
ALTER ROLE postgrest_test_authenticator SET pgrst."server_port" = 'ignored';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
db-anon-role = "postgrest_test_anonymous"
|
db-anon-role = "postgrest_test_anonymous"
|
||||||
db-channel = "postgrest"
|
db-channel = "postgrest"
|
||||||
db-channel-enabled = true
|
db-channel-enabled = true
|
||||||
db-extra-search-path = "public,extensions"
|
db-extra-search-path = "public,extensions,private"
|
||||||
db-max-rows = 1000
|
db-max-rows = 1000
|
||||||
db-pool = 1
|
db-pool = 1
|
||||||
db-pool-timeout = 100
|
db-pool-timeout = 100
|
||||||
@@ -14,7 +14,7 @@ db-tx-end = "commit-allow-override"
|
|||||||
db-uri = "<REPLACED_WITH_DB_URI>"
|
db-uri = "<REPLACED_WITH_DB_URI>"
|
||||||
jwt-aud = "https://example.org"
|
jwt-aud = "https://example.org"
|
||||||
jwt-role-claim-key = ".\"a\".\"role\""
|
jwt-role-claim-key = ".\"a\".\"role\""
|
||||||
jwt-secret = "REALLYREALLYREALLYREALLYVERYSAFE"
|
jwt-secret = "OVERRIDEREALLYREALLYREALLYREALLYVERYSAFE"
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-server-proxy-uri = "https://example.org/api"
|
openapi-server-proxy-uri = "https://example.org/api"
|
||||||
|
|||||||
@@ -309,10 +309,10 @@ def test_read_db_setting(defaultenv):
|
|||||||
"PGRST_DB_LOAD_GUC_CONFIG": "true",
|
"PGRST_DB_LOAD_GUC_CONFIG": "true",
|
||||||
}
|
}
|
||||||
with run(env=env) as postgrest:
|
with run(env=env) as postgrest:
|
||||||
uri = "/rpc/get_guc_value?name=pgrst.db_max_rows"
|
uri = "/rpc/get_guc_value?name=pgrst.jwt_secret"
|
||||||
response = postgrest.session.get(uri)
|
response = postgrest.session.get(uri)
|
||||||
|
|
||||||
assert response.text == '"1000"'
|
assert response.text == '"OVERRIDEREALLYREALLYREALLYREALLYVERYSAFE"'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|||||||
Reference in New Issue
Block a user