diff --git a/CHANGELOG.md b/CHANGELOG.md index be2d36c77..870d74f7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. From versio ## Unreleased +### Fixed + +- Fix login with uppercase and mixed case role names by @taimoorzaeem in #4678 + ## [14.10] - 2026-04-16 ### Added diff --git a/nix/tools/withTools.nix b/nix/tools/withTools.nix index 2f6afe4c4..4ec6109bf 100644 --- a/nix/tools/withTools.nix +++ b/nix/tools/withTools.nix @@ -25,7 +25,7 @@ let "ARG_OPTIONAL_SINGLE([fixtures], [f], [SQL file to load fixtures from])" "ARG_POSITIONAL_SINGLE([command], [Command to run])" "ARG_LEFTOVERS([command arguments])" - "ARG_USE_ENV([PGUSER], [postgrest_test_authenticator], [Authenticator PG role])" + "ARG_USE_ENV([PGUSER], [Postgrest_Test_Authenticator], [Authenticator PG role])" # user is written in mixed case to implicitly test that it is being properly quoted in schema cache queries "ARG_USE_ENV([PGDATABASE], [postgres], [PG database name])" "ARG_USE_ENV([PGRST_DB_SCHEMAS], [test], [Schema to expose])" "ARG_USE_ENV([PGTZ], [utc], [Timezone to use])" diff --git a/src/PostgREST/Config/Database.hs b/src/PostgREST/Config/Database.hs index aff4b5b8a..8b8661098 100644 --- a/src/PostgREST/Config/Database.hs +++ b/src/PostgREST/Config/Database.hs @@ -101,7 +101,7 @@ queryDbSettings preConfFunc prepared = SELECT setdatabase as database, unnest(setconfig) as setting FROM pg_catalog.pg_db_role_setting - WHERE setrole = CURRENT_USER::regrole::oid + WHERE setrole = quote_ident(CURRENT_USER)::regrole::oid AND setdatabase IN (0, (SELECT oid FROM pg_catalog.pg_database WHERE datname = CURRENT_CATALOG)) ), kv_settings AS ( @@ -142,7 +142,7 @@ queryRoleSettings pgVer prepared = select r.rolname, unnest(r.rolconfig) as setting from pg_auth_members m join pg_roles r on r.oid = m.roleid - where member = current_user::regrole::oid + where member = quote_ident(current_user)::regrole::oid ), kv_settings AS ( SELECT @@ -167,7 +167,7 @@ queryRoleSettings pgVer prepared = |] hasParameterPrivilege - | pgVer >= pgVersion150 = "or has_parameter_privilege(current_user::regrole::oid, ps.name, 'set')" + | pgVer >= pgVersion150 = "or has_parameter_privilege(quote_ident(current_user)::regrole::oid, ps.name, 'set')" | otherwise = "" processRows :: [(Text, Maybe Text, [(Text, Text)])] -> (RoleSettings, RoleIsolationLvl) diff --git a/test/io/fixtures/big_schema.sql b/test/io/fixtures/big_schema.sql index 6984164a6..559b434df 100644 --- a/test/io/fixtures/big_schema.sql +++ b/test/io/fixtures/big_schema.sql @@ -11399,7 +11399,7 @@ $$; DROP ROLE IF EXISTS postgrest_test_anonymous; CREATE ROLE postgrest_test_anonymous; -GRANT postgrest_test_anonymous TO :PGUSER; +GRANT postgrest_test_anonymous TO :"PGUSER"; GRANT USAGE ON SCHEMA apflora TO postgrest_test_anonymous; GRANT USAGE ON SCHEMA fuzzysearch TO postgrest_test_anonymous; diff --git a/test/io/fixtures/load.sql b/test/io/fixtures/load.sql index cbb70f6a1..bda30ac91 100644 --- a/test/io/fixtures/load.sql +++ b/test/io/fixtures/load.sql @@ -4,7 +4,7 @@ set check_function_bodies = false; -- to allow conditionals based on the pg vers set search_path to public; CREATE ROLE postgrest_test_anonymous; -ALTER ROLE :PGUSER SET pgrst.db_anon_role = 'postgrest_test_anonymous'; +ALTER ROLE :"PGUSER" SET pgrst.db_anon_role = 'postgrest_test_anonymous'; CREATE ROLE postgrest_test_author; @@ -21,14 +21,14 @@ alter role postgrest_test_w_superuser_settings set log_min_messages = 'fatal'; DO $do$BEGIN IF (SELECT current_setting('server_version_num')::INT >= 150000) THEN ALTER ROLE postgrest_test_w_superuser_settings SET log_min_duration_sample = 12345; - GRANT SET ON PARAMETER log_min_duration_sample to postgrest_test_authenticator; + GRANT SET ON PARAMETER log_min_duration_sample to "Postgrest_Test_Authenticator"; END IF; END$do$; GRANT postgrest_test_anonymous, postgrest_test_author, postgrest_test_serializable, postgrest_test_repeatable_read, - postgrest_test_w_superuser_settings TO :PGUSER; + postgrest_test_w_superuser_settings TO :"PGUSER"; CREATE SCHEMA v1; GRANT USAGE ON SCHEMA v1 TO postgrest_test_anonymous; @@ -57,7 +57,7 @@ $$ language sql; create function change_max_rows_config(val int, notify bool default false) returns void as $_$ begin execute format($$ - alter role postgrest_test_authenticator set pgrst.db_max_rows = %L; + alter role "Postgrest_Test_Authenticator" set pgrst.db_max_rows = %L; $$, val); if notify then perform pg_notify('pgrst', 'reload config'); @@ -66,13 +66,13 @@ end $_$ volatile security definer language plpgsql ; create function reset_max_rows_config() returns void as $_$ begin - alter role postgrest_test_authenticator reset pgrst.db_max_rows; + alter role "Postgrest_Test_Authenticator" reset pgrst.db_max_rows; end $_$ volatile security definer language plpgsql ; create function change_db_schema_and_full_reload(schemas text) returns void as $_$ begin execute format($$ - alter role postgrest_test_authenticator set pgrst.db_schemas = %L; + alter role "Postgrest_Test_Authenticator" set pgrst.db_schemas = %L; $$, schemas); perform pg_notify('pgrst', 'reload config'); perform pg_notify('pgrst', 'reload schema'); @@ -80,14 +80,14 @@ end $_$ volatile security definer language plpgsql ; create function v1.reset_db_schema_config() returns void as $_$ begin - alter role postgrest_test_authenticator reset pgrst.db_schemas; + alter role "Postgrest_Test_Authenticator" reset pgrst.db_schemas; perform pg_notify('pgrst', 'reload config'); perform pg_notify('pgrst', 'reload schema'); end $_$ volatile security definer language plpgsql ; create function invalid_role_claim_key_reload() returns void as $_$ begin - alter role postgrest_test_authenticator set pgrst.jwt_role_claim_key = 'test'; + alter role "Postgrest_Test_Authenticator" set pgrst.jwt_role_claim_key = 'test'; perform pg_notify('pgrst', 'reload config'); end $_$ volatile security definer language plpgsql ; @@ -100,7 +100,7 @@ $_$ language sql; create function reset_invalid_role_claim_key() returns void as $_$ begin - alter role postgrest_test_authenticator reset pgrst.jwt_role_claim_key; + alter role "Postgrest_Test_Authenticator" reset pgrst.jwt_role_claim_key; perform pg_notify('pgrst', 'reload config'); end $_$ volatile security definer language plpgsql ; @@ -235,12 +235,12 @@ $$ language sql; create function change_db_schemas_config() returns void as $_$ begin - alter role postgrest_test_authenticator set pgrst.db_schemas = 'test'; + alter role "Postgrest_Test_Authenticator" set pgrst.db_schemas = 'test'; end $_$ volatile security definer language plpgsql; create function reset_db_schemas_config() returns void as $_$ begin - alter role postgrest_test_authenticator reset pgrst.db_schemas; + alter role "Postgrest_Test_Authenticator" reset pgrst.db_schemas; end $_$ volatile security definer language plpgsql ; create function test.get_current_schema() returns text as $$ diff --git a/test/io/fixtures/replica.sql b/test/io/fixtures/replica.sql index deffbec06..bf765fdb3 100644 --- a/test/io/fixtures/replica.sql +++ b/test/io/fixtures/replica.sql @@ -13,7 +13,7 @@ create table replica.items as select x as id from generate_series(1, 10) x; DROP ROLE IF EXISTS postgrest_test_anonymous; CREATE ROLE postgrest_test_anonymous; -GRANT postgrest_test_anonymous TO :PGUSER; +GRANT postgrest_test_anonymous TO :"PGUSER"; GRANT USAGE ON SCHEMA replica TO postgrest_test_anonymous; diff --git a/test/load/fixtures.sql b/test/load/fixtures.sql index 3622dcf78..75bd6a8bb 100644 --- a/test/load/fixtures.sql +++ b/test/load/fixtures.sql @@ -1,7 +1,7 @@ CREATE ROLE postgrest_test_anonymous; CREATE ROLE postgrest_test_author; -GRANT postgrest_test_anonymous TO :PGUSER; -GRANT postgrest_test_author TO :PGUSER; +GRANT postgrest_test_anonymous TO :"PGUSER"; +GRANT postgrest_test_author TO :"PGUSER"; CREATE SCHEMA test; -- PUT+PATCH target needs one record and column to modify diff --git a/test/observability/fixtures/roles.sql b/test/observability/fixtures/roles.sql index e0a938b60..ef6f444ee 100644 --- a/test/observability/fixtures/roles.sql +++ b/test/observability/fixtures/roles.sql @@ -2,4 +2,4 @@ DROP ROLE IF EXISTS postgrest_test_anonymous, postgrest_test_author; CREATE ROLE postgrest_test_anonymous; CREATE ROLE postgrest_test_author; -GRANT postgrest_test_anonymous, postgrest_test_author TO :PGUSER; +GRANT postgrest_test_anonymous, postgrest_test_author TO :"PGUSER"; diff --git a/test/spec/fixtures/roles.sql b/test/spec/fixtures/roles.sql index 3590c6edb..f1b7e1ca7 100644 --- a/test/spec/fixtures/roles.sql +++ b/test/spec/fixtures/roles.sql @@ -4,4 +4,4 @@ CREATE ROLE postgrest_test_default_role; CREATE ROLE postgrest_test_author; CREATE ROLE postgrest_test_superuser WITH SUPERUSER; -GRANT postgrest_test_anonymous, postgrest_test_default_role, postgrest_test_author, postgrest_test_superuser TO :PGUSER; +GRANT postgrest_test_anonymous, postgrest_test_default_role, postgrest_test_author, postgrest_test_superuser TO :"PGUSER";