From a08c94ed835e07fa883a58c5f908c4ea55719408 Mon Sep 17 00:00:00 2001 From: aliyoge Date: Tue, 8 Aug 2023 17:59:19 +0800 Subject: [PATCH] Fix the 'role does not exist' error caused by uppercase characters in user --- META.json | 4 +- pgsodium.control | 2 +- sql/pgsodium--3.1.8--3.1.9.sql | 127 +++++++++++++++++++++++++++++++++ test/pgsodium_schema.sql | 6 +- 4 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 sql/pgsodium--3.1.8--3.1.9.sql diff --git a/META.json b/META.json index 312d544..11e9ce8 100644 --- a/META.json +++ b/META.json @@ -2,7 +2,7 @@ "name": "pgsodium", "abstract": "Postgres extension for libsodium functions", "description": "pgsodium is a PostgreSQL extension that exposes modern libsodium based cryptographic functions to SQL.", - "version": "3.1.8", + "version": "3.1.9", "maintainer": [ "Michel Pelletier " ], @@ -13,7 +13,7 @@ "abstract": "Postgres extension for libsodium functions", "file": "src/pgsodium.h", "docfile": "README.md", - "version": "3.1.8" + "version": "3.1.9" } }, "prereqs": { diff --git a/pgsodium.control b/pgsodium.control index a2b80c9..e104f77 100644 --- a/pgsodium.control +++ b/pgsodium.control @@ -1,5 +1,5 @@ # pgsodium extension comment = 'Postgres extension for libsodium functions' -default_version = '3.1.8' +default_version = '3.1.9' relocatable = false schema = pgsodium diff --git a/sql/pgsodium--3.1.8--3.1.9.sql b/sql/pgsodium--3.1.8--3.1.9.sql new file mode 100644 index 0000000..946e820 --- /dev/null +++ b/sql/pgsodium--3.1.8--3.1.9.sql @@ -0,0 +1,127 @@ +CREATE OR REPLACE FUNCTION pgsodium.create_mask_view(relid oid, subid integer, debug boolean = false) + RETURNS void AS + $$ +DECLARE + m record; + body text; + source_name text; + view_owner regrole = quote_ident(session_user); + rule pgsodium.masking_rule; + privs aclitem[]; + priv record; +BEGIN + SELECT DISTINCT * INTO STRICT rule FROM pgsodium.masking_rule WHERE attrelid = relid AND attnum = subid; + + source_name := relid::regclass::text; + + BEGIN + SELECT relacl INTO STRICT privs FROM pg_catalog.pg_class WHERE oid = rule.view_name::regclass::oid; + EXCEPTION + WHEN undefined_table THEN + SELECT relacl INTO STRICT privs FROM pg_catalog.pg_class WHERE oid = relid; + END; + + body = format( + $c$ + DROP VIEW IF EXISTS %1$s; + CREATE VIEW %1$s %5$s AS SELECT %2$s + FROM %3$s; + ALTER VIEW %1$s OWNER TO %4$s; + $c$, + rule.view_name, + pgsodium.decrypted_columns(relid), + source_name, + view_owner, + CASE WHEN rule.security_invoker THEN 'WITH (security_invoker=true)' ELSE '' END + ); + IF debug THEN + RAISE NOTICE '%', body; + END IF; + EXECUTE body; + + FOR priv IN SELECT * FROM pg_catalog.aclexplode(privs) LOOP + body = format( + $c$ + GRANT %s ON %s TO %s; + $c$, + priv.privilege_type, + rule.view_name, + priv.grantee::regrole::text + ); + IF debug THEN + RAISE NOTICE '%', body; + END IF; + EXECUTE body; + END LOOP; + + FOR m IN SELECT * FROM pgsodium.mask_columns where attrelid = relid LOOP + IF m.key_id IS NULL AND m.key_id_column is NULL THEN + CONTINUE; + ELSE + body = format( + $c$ + DROP FUNCTION IF EXISTS %1$s."%2$s_encrypt_secret_%3$s"() CASCADE; + + CREATE OR REPLACE FUNCTION %1$s."%2$s_encrypt_secret_%3$s"() + RETURNS TRIGGER + LANGUAGE plpgsql + AS $t$ + BEGIN + %4$s; + RETURN new; + END; + $t$; + + ALTER FUNCTION %1$s."%2$s_encrypt_secret_%3$s"() OWNER TO %5$s; + + DROP TRIGGER IF EXISTS "%2$s_encrypt_secret_trigger_%3$s" ON %6$s; + + CREATE TRIGGER "%2$s_encrypt_secret_trigger_%3$s" + BEFORE INSERT OR UPDATE OF "%3$s" ON %6$s + FOR EACH ROW + EXECUTE FUNCTION %1$s."%2$s_encrypt_secret_%3$s" (); + $c$, + rule.relnamespace, + rule.relname, + m.attname, + pgsodium.encrypted_column(relid, m), + view_owner, + source_name + ); + if debug THEN + RAISE NOTICE '%', body; + END IF; + EXECUTE body; + END IF; + END LOOP; + + raise notice 'about to masking role % %', source_name, rule.view_name; + PERFORM pgsodium.mask_role(oid::regrole, source_name, rule.view_name) + FROM pg_roles WHERE pgsodium.has_mask(oid::regrole, source_name); + + RETURN; +END + $$ + LANGUAGE plpgsql + VOLATILE + SET search_path='pg_catalog' +; + +CREATE OR REPLACE FUNCTION pgsodium.update_masks(debug boolean = false) +RETURNS void AS + $$ +BEGIN + PERFORM pgsodium.update_mask(objoid, debug) + FROM pg_catalog.pg_seclabel sl + JOIN pg_catalog.pg_class cl ON (cl.oid = sl.objoid) + WHERE label ilike 'ENCRYPT%' + AND cl.relowner = quote_ident(session_user)::regrole::oid + AND provider = 'pgsodium' + AND objoid::regclass != 'pgsodium.key'::regclass + ; + RETURN; +END +$$ + LANGUAGE plpgsql + SET search_path='' +; diff --git a/test/pgsodium_schema.sql b/test/pgsodium_schema.sql index 7399464..d0215a7 100644 --- a/test/pgsodium_schema.sql +++ b/test/pgsodium_schema.sql @@ -8,7 +8,7 @@ SELECT cmp_ok(current_setting('server_version_num')::int, '>=', 130000, format(' ---- EXTENSION VERSION -SELECT results_eq('SELECT pgsodium.version()', $$VALUES ('3.1.8'::text)$$, 'Version of pgsodium is 3.1.8'); +SELECT results_eq('SELECT pgsodium.version()', $$VALUES ('3.1.9'::text)$$, 'Version of pgsodium is 3.1.9'); ---- EXTENSION OBJECTS @@ -972,7 +972,7 @@ SELECT function_privs_are('pgsodium'::name, proname, proargtypes::regtype[]::tex AND oidvectortypes(proargtypes) = 'pgsodium.key_type, text, bytea, bytea, uuid, bytea, timestamp with time zone, text'; SELECT unnest(ARRAY[ - is(md5(prosrc), 'a34e96732392101c6e438288325151c0', + is(md5(prosrc), '7e3170fe45138d02f95bf359888989f6', format('Function pgsodium.%s(%s) body should match checksum', proname, pg_get_function_identity_arguments(oid)) ), @@ -5674,7 +5674,7 @@ SELECT function_privs_are('pgsodium'::name, proname, proargtypes::regtype[]::tex AND oidvectortypes(proargtypes) = 'oid, boolean'; SELECT unnest(ARRAY[ - is(md5(prosrc), 'd87941beba33c2ac540f35d69dfa2a41', + is(md5(prosrc), '39caa73f199458415294723190fdb94b', format('Function pgsodium.%s(%s) body should match checksum', proname, pg_get_function_identity_arguments(oid)) ),