subzerocloud / subzero-cli

Tooling to aid development of subZero/PostgREST based backend APIs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Migrations missing grants after update from 0.1.40 to 0.2.1

oakgary opened this issue · comments

important grant statements are missing

migration generated on 0.1.40 looks somewhat like this:

START TRANSACTION;

SET search_path = data, pg_catalog;

ALTER TABLE test_table
	ADD COLUMN test character varying;


SET search_path = api, pg_catalog;

DROP VIEW test_table;

CREATE VIEW test_table AS
	SELECT test_table.id,
    test_table.test
   FROM data.test_table;

ALTER VIEW test_table OWNER TO api;

REVOKE ALL ON TABLE test_table FROM anonymous;
GRANT SELECT ON TABLE test_table TO anonymous;
REVOKE ALL ON TABLE test_table FROM member;
GRANT SELECT ON TABLE test_table TO member;

COMMIT TRANSACTION;

migration generated on 0.2.1 looks somewhat like this:

BEGIN;

SET search_path = data, pg_catalog;

ALTER TABLE test_table
	ADD COLUMN test character varying;


SET search_path = api, pg_catalog;

DROP VIEW test_table;

CREATE VIEW test_table AS
	SELECT test_table.id,
    test_table.test
   FROM data.test_table;

ALTER VIEW test_table OWNER TO api;

COMMIT;

to get the old way back with 2.1 you just need to add --with-privileges flag when generating the migrations

Usage: subzero-migrations add [options] <name>
Adds a new sqitch migration
Options:
  -n, --note <note>                                  Add sqitch migration note
  -d, --no-diff                                      Add empty sqitch migration (no diff)
  --diff-tool <diff-tool>                            Use apgdiff, migra for diffing
  --with-privileges                                  Include grant/revoke commands (experimental)
  --include-beginning <"file1.sql, file2.sql, ...">  Include specific sql scripts at the beginning of the migration
  --include-end <"file1.sql, file2.sql, ...">        Include specific sql scripts at the end of the migration
  --dry-run                                          Don not create migrations files, only output the diff
  --debug                                            Verbose output and leaves the temporary files (used to create the migration) in place
  --db-uri <uri>                                     Diff against a database schema (By default we diff src/ and migrations/deploy/ directories)
  --db-docker-image <image>                          Docker image used for temp postgres
  -h, --help                                         output usage information

the reasoning was this: privileges are a very sensitive area so when doing drop/create view, they need to recreated and i do not 100% trust apgdiff output 🙂 + the migration becomes littered with grant statements.

the clean solution i came up with is: do not have the privileges at all when diffing, and after diffing is done, you can include your custom sql file that "resets" all the clean permissions at the end of each migration so that you can be 100% sure the permissions are correct

these features, while live, are not documented yet, working on a lot of features now

so if you basically have a file similar to this one https://github.com/subzerocloud/subzero-starter-kit/blob/subzero_container/db/src/authorization/privileges.sql that contains all the privileges ( plus some revoke statements at the beginning )

you can do subzero migrations add --include-end 'db/src/authorization/privileges.sql' new_migration and you will get a new migration diff with that file included at the end in order to reset the permissions
13:07
plus there is the new diff tool migra which generates i think nicer diffs

I'll leave this open until i can document the new features / methods

until i update the docs and the starter kit, this might be useful
in the provileges.sql file (that would get included on each migration) this snippet is useful to remove all privileges from application roles

-- Reseting all privileges for application roles (start from a clean slate)
-- we use a convinience function here since PostgreSQL does not have a specific statement
do $$
declare
    r text;
    s text;
    -- list roles which need resetting here
    role_list text[] = '{webuser, anonymous, api}';
    -- list schemas for which to reset privileges
    schema_list text[] = '{api, data, request, response, settings}';
begin
    foreach r in array role_list loop 
        foreach s in array schema_list loop 
            execute format('revoke all privileges on all tables    in schema %I from %I', s, r);
            execute format('revoke all privileges on all sequences in schema %I from %I', s, r);
            execute format('revoke all privileges on all functions in schema %I from %I', s, r);
            execute format('revoke all privileges on                  schema %I from %I', s, r);
        end loop;
    end loop;
end$$;