diff --git a/scripts-available/CDB_Groups.sql b/scripts-available/CDB_Groups.sql index 41687fa..cdc771a 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 CREATE OR REPLACE -FUNCTION cartodb.CDB_Group_AddMember(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_AddMember_API(group_name, username); + foreach username in 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 +-- Removes users from a group CREATE OR REPLACE -FUNCTION cartodb.CDB_Group_RemoveMember(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_RemoveMember_API(group_name, username); + foreach username in 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 5287802..136a969 100644 --- a/scripts-available/CDB_Groups_API.sql +++ b/scripts-available/CDB_Groups_API.sql @@ -5,6 +5,12 @@ -- Requires configuration parameter. Example: SELECT cartodb.CDB_Conf_SetConf('groups_api', '{ "host": "127.0.0.1", "port": 3000, "timeout": 10, "username": "extension", "password": "elephant" }'); ---------------------------------- +-- TODO: delete this development cleanup before final merge +DROP FUNCTION IF EXISTS cartodb.CDB_Group_AddMember(group_name text, username text); +DROP FUNCTION IF EXISTS cartodb.CDB_Group_RemoveMember(group_name text, username text); +DROP FUNCTION IF EXISTS cartodb._CDB_Group_AddMember_API(group_name text, username text); +DROP FUNCTION IF EXISTS cartodb._CDB_Group_RemoveMember_API(group_name text, username text); + -- Sends the create group request CREATE OR REPLACE FUNCTION cartodb._CDB_Group_CreateGroup_API(group_name text, group_role text) @@ -45,27 +51,28 @@ $$ $$ LANGUAGE 'plpythonu' VOLATILE SECURITY DEFINER; CREATE OR REPLACE -FUNCTION cartodb._CDB_Group_AddMember_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) 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_RemoveMember_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) + 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 56a5b0d..7e54307 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_AddMember('group_a', 'cdb_testmember_1')" + sql "SELECT cartodb.CDB_Group_AddUsers('group_a', ARRAY['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_RemoveMember('group_a', 'cdb_testmember_1')" + sql "SELECT cartodb.CDB_Group_RemoveUsers('group_a', ARRAY['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_AddMember('group_a', 'cdb_testmember_2');" fails - sql cdb_testmember_1 "SELECT cartodb.CDB_Group_RemoveMember('group_a', 'cdb_testmember_1');" fails + sql cdb_testmember_1 "SELECT cartodb.CDB_Group_AddUsers('group_a', ARRAY['cdb_testmember_2']);" fails + sql cdb_testmember_1 "SELECT cartodb.CDB_Group_RemoveUsers('group_a', ARRAY['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_AddMember('group_x', 'cdb_testmember_1');" - sql cdb_org_admin "SELECT cartodb.CDB_Group_RemoveMember('group_x', 'cdb_testmember_1');" + sql cdb_org_admin "SELECT cartodb.CDB_Group_AddUsers('group_x', ARRAY['cdb_testmember_1', 'cdb_testmember_2']);" + sql cdb_org_admin "SELECT cartodb.CDB_Group_RemoveUsers('group_x', ARRAY['cdb_testmember_1', 'cdb_testmember_2']);" # TODO: workaround superadmin limitation sql "SELECT cartodb.CDB_Group_DropGroup('group_x');" }