From 59d144d91d69299ce0fa8c6f301ad93dcbef28cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Ignacio=20S=C3=A1nchez=20Lara?= Date: Mon, 7 Sep 2015 10:35:04 +0200 Subject: [PATCH] Batch add/remove users support --- scripts-available/CDB_Groups.sql | 34 +++++++++++++++++----------- scripts-available/CDB_Groups_API.sql | 11 +++++---- test/organization/test.sh | 12 +++++----- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/scripts-available/CDB_Groups.sql b/scripts-available/CDB_Groups.sql index 06d4d03..253e72c 100644 --- a/scripts-available/CDB_Groups.sql +++ b/scripts-available/CDB_Groups.sql @@ -50,37 +50,45 @@ BEGIN END $$ LANGUAGE PLPGSQL VOLATILE; --- Adds a user to a group +-- Adds users to a group, comma-separated CREATE OR REPLACE -FUNCTION cartodb.CDB_Group_AddUser(group_name text, username text) +FUNCTION cartodb.CDB_Group_AddUsers(group_name text, usernames text) RETURNS VOID AS $$ DECLARE group_role TEXT; user_role TEXT; + username TEXT; BEGIN group_role := cartodb._CDB_Group_GroupRole(group_name); - user_role := cartodb._CDB_User_RoleFromUsername(username); - IF(group_role IS NULL OR user_role IS NULL) - THEN - RAISE EXCEPTION 'Group role (%) and user role (%) must be already existing', group_role, user_role; - END IF; - EXECUTE format('GRANT %I TO %I', group_role, user_role); - PERFORM cartodb._CDB_Group_AddUser_API(group_name, username); + foreach username in array string_to_array(usernames, ',') + loop + user_role := cartodb._CDB_User_RoleFromUsername(username); + IF(group_role IS NULL OR user_role IS NULL) + THEN + RAISE EXCEPTION 'Group role (%) and user role (%) must be already existing', group_role, user_role; + END IF; + EXECUTE format('GRANT %I TO %I', group_role, user_role); + end loop; + PERFORM cartodb._CDB_Group_AddUsers_API(group_name, usernames); END $$ LANGUAGE PLPGSQL VOLATILE; -- Removes a user from a group CREATE OR REPLACE -FUNCTION cartodb.CDB_Group_RemoveUser(group_name text, username text) +FUNCTION cartodb.CDB_Group_RemoveUsers(group_name text, usernames text) RETURNS VOID AS $$ DECLARE group_role TEXT; user_role TEXT; + username TEXT; BEGIN group_role := cartodb._CDB_Group_GroupRole(group_name); - user_role := cartodb._CDB_User_RoleFromUsername(username); - EXECUTE format('REVOKE %I FROM %I', group_role, user_role); - PERFORM cartodb._CDB_Group_RemoveUser_API(group_name, username); + foreach username in array string_to_array(usernames, ',') + loop + user_role := cartodb._CDB_User_RoleFromUsername(username); + EXECUTE format('REVOKE %I FROM %I', group_role, user_role); + end loop; + PERFORM cartodb._CDB_Group_RemoveUsers_API(group_name, usernames); END $$ LANGUAGE PLPGSQL VOLATILE; diff --git a/scripts-available/CDB_Groups_API.sql b/scripts-available/CDB_Groups_API.sql index db3ad0e..79eb057 100644 --- a/scripts-available/CDB_Groups_API.sql +++ b/scripts-available/CDB_Groups_API.sql @@ -45,27 +45,28 @@ $$ $$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER; CREATE OR REPLACE -FUNCTION cartodb._CDB_Group_AddUser_API(group_name text, username text) +FUNCTION cartodb._CDB_Group_AddUsers_API(group_name text, usernames text) RETURNS VOID AS $$ import string import urllib url = '/api/v1/databases/{0}/groups/%s/users' % (urllib.pathname2url(group_name)) - body = '{ "username": "%s" }' % username + body = "{ \"users\": [\"%s\"] }" % "\",\"".join(usernames.split(',')) query = "select cartodb._CDB_Group_API_Request('POST', '%s', '%s', '{200, 409}') as response_status" % (url, body) plpy.execute(query) $$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER; CREATE OR REPLACE -FUNCTION cartodb._CDB_Group_RemoveUser_API(group_name text, username text) +FUNCTION cartodb._CDB_Group_RemoveUsers_API(group_name text, usernames text) RETURNS VOID AS $$ import string import urllib - url = '/api/v1/databases/{0}/groups/%s/users/%s' % (urllib.pathname2url(group_name), username) - query = "select cartodb._CDB_Group_API_Request('DELETE', '%s', '', '{200, 404}') as response_status" % url + url = '/api/v1/databases/{0}/groups/%s/users' % (urllib.pathname2url(group_name)) + body = "{ \"users\": [\"%s\"] }" % "\",\"".join(usernames.split(',')) + query = "select cartodb._CDB_Group_API_Request('DELETE', '%s', '%s', '{200, 404}') as response_status" % (url, body) plpy.execute(query) $$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER; diff --git a/test/organization/test.sh b/test/organization/test.sh index 5d55115..17ec967 100644 --- a/test/organization/test.sh +++ b/test/organization/test.sh @@ -187,7 +187,7 @@ function setup() { sql "SELECT cartodb.CDB_Group_CreateGroup('group_a_tmp')" sql "SELECT cartodb.CDB_Group_RenameGroup('group_a_tmp', 'group_a')" - sql "SELECT cartodb.CDB_Group_AddUser('group_a', 'cdb_testmember_1')" + sql "SELECT cartodb.CDB_Group_AddUsers('group_a', 'cdb_testmember_1')" sql "SELECT cartodb.CDB_Group_CreateGroup('group_b')" } @@ -203,7 +203,7 @@ function tear_down() { sql "select cartodb.CDB_Group_DropGroup('group_b')" - sql "SELECT cartodb.CDB_Group_RemoveUser('group_a', 'cdb_testmember_1')" + sql "SELECT cartodb.CDB_Group_RemoveUsers('group_a', 'cdb_testmember_1')" sql "select cartodb.CDB_Group_DropGroup('group_a')" sql "SELECT cartodb.CDB_Organization_RemoveAdmin('cdb_org_admin');" @@ -474,8 +474,8 @@ function test_group_management_functions_cant_be_used_by_normal_members() { sql cdb_testmember_1 "SELECT cartodb.CDB_Group_CreateGroup('group_x_1');" fails sql cdb_testmember_1 "SELECT cartodb.CDB_Group_RenameGroup('group_a', 'group_x_2');" fails sql cdb_testmember_1 "SELECT cartodb.CDB_Group_DropGroup('group_a');" fails - sql cdb_testmember_1 "SELECT cartodb.CDB_Group_AddUser('group_a', 'cdb_testmember_2');" fails - sql cdb_testmember_1 "SELECT cartodb.CDB_Group_RemoveUser('group_a', 'cdb_testmember_1');" fails + sql cdb_testmember_1 "SELECT cartodb.CDB_Group_AddUsers('group_a', 'cdb_testmember_2');" fails + sql cdb_testmember_1 "SELECT cartodb.CDB_Group_RemoveUsers('group_a', 'cdb_testmember_1');" fails } function test_group_permission_functions_cant_be_used_by_normal_members() { @@ -496,8 +496,8 @@ function test_group_permission_functions_cant_be_used_by_normal_members() { function test_group_management_functions_can_be_used_by_org_admin() { sql cdb_org_admin "SELECT cartodb.CDB_Group_CreateGroup('group_x_tmp');" sql cdb_org_admin "SELECT cartodb.CDB_Group_RenameGroup('group_x_tmp', 'group_x');" - sql cdb_org_admin "SELECT cartodb.CDB_Group_AddUser('group_x', 'cdb_testmember_1');" - sql cdb_org_admin "SELECT cartodb.CDB_Group_RemoveUser('group_x', 'cdb_testmember_1');" + sql cdb_org_admin "SELECT cartodb.CDB_Group_AddUsers('group_x', 'cdb_testmember_1');" + sql cdb_org_admin "SELECT cartodb.CDB_Group_RemoveUsers('group_x', 'cdb_testmember_1');" # TODO: workaround superadmin limitation sql "SELECT cartodb.CDB_Group_DropGroup('group_x');" }