diff --git a/scripts-available/CDB_FederatedServer.sql b/scripts-available/CDB_FederatedServer.sql index af96f9f..b385dc5 100644 --- a/scripts-available/CDB_FederatedServer.sql +++ b/scripts-available/CDB_FederatedServer.sql @@ -357,7 +357,14 @@ BEGIN IF (db_role IS NULL) THEN RAISE EXCEPTION 'User role "%" cannot be NULL', username; END IF; - EXECUTE format('GRANT %I TO %I', server_role_name, db_role); + BEGIN + EXECUTE format('GRANT %I TO %I', server_role_name, db_role); + EXCEPTION + WHEN insufficient_privilege THEN + RAISE EXCEPTION 'You do not have rights to grant access on "%"', server; + WHEN OTHERS THEN + RAISE EXCEPTION 'Could not grant access on "%" to "%": %', server, db_role, SQLERRM; + END; END $$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE; @@ -375,7 +382,14 @@ BEGIN IF (db_role IS NULL) THEN RAISE EXCEPTION 'User role "%" cannot be NULL', username; END IF; - EXECUTE format('REVOKE %I FROM %I', server_role_name, db_role); + BEGIN + EXECUTE format('REVOKE %I FROM %I', server_role_name, db_role); + EXCEPTION + WHEN insufficient_privilege THEN + RAISE EXCEPTION 'You do not have rights to revoke access on "%"', server; + WHEN OTHERS THEN + RAISE EXCEPTION 'Could not revoke access on "%" to "%": %', server, db_role, SQLERRM; + END; END $$ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE; diff --git a/test/CDB_FederatedServerTables.sql b/test/CDB_FederatedServerTables.sql index 50663d5..ed8dc4b 100644 --- a/test/CDB_FederatedServerTables.sql +++ b/test/CDB_FederatedServerTables.sql @@ -285,14 +285,69 @@ DROP TABLE localtable; -- Test permissions -- =================================================================== --- Try permissions tricks --- Try registering and accessing a table as normal user +\echo '## Registering tables does not work without permissions' +\c contrib_regression cdb_fs_tester +SELECT cartodb.CDB_Federated_Table_Register( + server => 'loopback', + remote_schema => 'remote_schema', + remote_table => 'remote_geom', + id_column => 'id', + geom_column => 'geom', + local_name => 'localtable'); + +\echo '## Listing registered tables does not work without permissions' +Select CDB_Federated_Server_List_Registered_Tables(server => 'loopback', remote_schema => 'remote_schema'); --- Try register with one user and reading it with other --- Try register with one user and deleting it with another +\echo '## Registering tables works with granted permissions' +\c contrib_regression postgres +SELECT cartodb.CDB_Federated_Server_Grant_Access(server := 'loopback', db_role := 'cdb_fs_tester'::name); +\c contrib_regression cdb_fs_tester +SELECT cartodb.CDB_Federated_Table_Register( + server => 'loopback', + remote_schema => 'remote_schema', + remote_table => 'remote_geom', + id_column => 'id', + geom_column => 'geom', + local_name => 'localtable'); +\echo '## Listing registered tables works with granted permissions' +Select CDB_Federated_Server_List_Registered_Tables(server => 'loopback', remote_schema => 'remote_schema'); + +\echo '## Selecting from a registered table with granted permissions works' +Select cartodb_id, ST_AsText(the_geom) from localtable; + +\echo '## Selecting from a registered table without permissions does not work' +\c contrib_regression cdb_fs_tester2 +Select cartodb_id, ST_AsText(the_geom) from localtable; + +\echo '## Deleting a registered table without permissions does not work' +SELECT CDB_Federated_Table_Unregister( + server => 'loopback', + remote_schema => 'remote_schema', + remote_table => 'remote_geom' + ); + +\echo '## Only the owner can grant permissions over the server' +SELECT cartodb.CDB_Federated_Server_Grant_Access(server := 'loopback', db_role := 'cdb_fs_tester2'::name); + +\echo '## Everything works for a different user when granted permissions' +\c contrib_regression postgres +SELECT cartodb.CDB_Federated_Server_Grant_Access(server := 'loopback', db_role := 'cdb_fs_tester2'::name); +\c contrib_regression cdb_fs_tester2 +Select CDB_Federated_Server_List_Registered_Tables(server => 'loopback', remote_schema => 'remote_schema'); +Select cartodb_id, ST_AsText(the_geom) from localtable; + +\echo '## A different user can unregister a table' +SELECT CDB_Federated_Table_Unregister( + server => 'loopback', + remote_schema => 'remote_schema', + remote_table => 'remote_geom' + ); +Select CDB_Federated_Server_List_Registered_Tables(server => 'loopback', remote_schema => 'remote_schema'); +\echo '## Only the owner can revoke permissions over the server' +SELECT cartodb.CDB_Federated_Server_Revoke_Access(server := 'loopback', db_role := 'cdb_fs_tester'::name); -- =================================================================== -- Cleanup diff --git a/test/CDB_FederatedServerTables_expect b/test/CDB_FederatedServerTables_expect index a81614b..4026c19 100644 --- a/test/CDB_FederatedServerTables_expect +++ b/test/CDB_FederatedServerTables_expect @@ -61,4 +61,41 @@ CREATE VIEW ERROR: Could not import table "remote_geom" as "localtable2": "localtable2" already exists DROP VIEW DROP TABLE +## Registering tables does not work without permissions +You are now connected to database "contrib_regression" as user "cdb_fs_tester". +ERROR: Not enough permissions to access the server "loopback" +## Listing registered tables does not work without permissions +ERROR: Not enough permissions to access the server "loopback" +## Registering tables works with granted permissions +You are now connected to database "contrib_regression" as user "postgres". + +You are now connected to database "contrib_regression" as user "cdb_fs_tester". + +## Listing registered tables works with granted permissions +(remote_geom2,public.different_name) +(remote_geom,public.localtable) +## Selecting from a registered table with granted permissions works +1|POINT(1 1) +2|POINT(2 2) +## Selecting from a registered table without permissions does not work +You are now connected to database "contrib_regression" as user "cdb_fs_tester2". +ERROR: permission denied for view localtable +## Deleting a registered table without permissions does not work +ERROR: Not enough permissions to access the server "loopback" +## Only the owner can grant permissions over the server +ERROR: You do not have rights to grant access on "loopback" +## Everything works for a different user when granted permissions +You are now connected to database "contrib_regression" as user "postgres". + +You are now connected to database "contrib_regression" as user "cdb_fs_tester2". +(remote_geom2,public.different_name) +(remote_geom,public.localtable) +1|POINT(1 1) +2|POINT(2 2) +## A different user can unregister a table +NOTICE: drop cascades to view localtable + +(remote_geom2,public.different_name) +## Only the owner can revoke permissions over the server +ERROR: You do not have rights to revoke access on "loopback" D1| diff --git a/test/CDB_FederatedServer_expect b/test/CDB_FederatedServer_expect index c411d34..f21f2cc 100644 --- a/test/CDB_FederatedServer_expect +++ b/test/CDB_FederatedServer_expect @@ -48,7 +48,7 @@ You are now connected to database "contrib_regression" as user "postgres". ## Granting access to a user works 9.5| ERROR: Server "does not exist" does not exist -ERROR: role "does not exist" does not exist +ERROR: Could not grant access on "myRemote3" to "does not exist": role "does not exist" does not exist ## Granting access again raises a notice NOTICE: role "cdb_fs_tester" is already a member of role "cdb_fs_role_95b63382aabca4433e7bd9cba6c30368" 9.8|