CDB_CONF and create and drop group api calls

This commit is contained in:
Juan Ignacio Sánchez Lara 2015-08-14 13:55:52 +02:00
parent a0aac4e9c9
commit d4bcb97f9b
4 changed files with 99 additions and 21 deletions

View File

@ -1,34 +1,34 @@
-- This will trigger NOTICE if CDB_CONF already exists
DO LANGUAGE 'plpgsql' $$
BEGIN
CREATE TABLE IF NOT EXISTS CDB_CONF ( PARAM TEXT PRIMARY KEY, VALUE TEXT NOT NULL );
CREATE TABLE IF NOT EXISTS cartodb.CDB_CONF ( PARAM TEXT PRIMARY KEY, CONF TEXT NOT NULL );
END
$$;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Conf_SetParam(param text, value text)
FUNCTION cartodb.CDB_Conf_SetConf(param text, conf text)
RETURNS void AS $$
BEGIN
PERFORM cartodb.CDB_Conf_RemoveParam(param);
EXECUTE 'INSERT INTO CDB_CONF (PARAM, VALUE) VALUES ($1, $2);' USING param, value;
PERFORM cartodb.CDB_Conf_RemoveConf(param);
EXECUTE 'INSERT INTO cartodb.CDB_CONF (PARAM, CONF) VALUES ($1, $2);' USING param, conf;
END
$$ LANGUAGE PLPGSQL VOLATILE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Conf_RemoveParam(param text)
FUNCTION cartodb.CDB_Conf_RemoveConf(param text)
RETURNS void AS $$
BEGIN
EXECUTE 'DELETE FROM CDB_CONF WHERE PARAM = $1;' USING param;
EXECUTE 'DELETE FROM cartodb.CDB_CONF WHERE PARAM = $1;' USING param;
END
$$ LANGUAGE PLPGSQL VOLATILE;
CREATE OR REPLACE
FUNCTION cartodb.CDB_Conf_GetParam(param text)
FUNCTION cartodb.CDB_Conf_GetConf(param text)
RETURNS TEXT AS $$
DECLARE
value TEXT;
conf TEXT;
BEGIN
EXECUTE 'SELECT VALUE FROM CDB_CONF WHERE PARAM = $1;' INTO value USING param;
RETURN value;
EXECUTE 'SELECT CONF FROM cartodb.CDB_CONF WHERE PARAM = $1;' INTO conf USING param;
RETURN conf;
END
$$ LANGUAGE PLPGSQL STABLE;

View File

@ -3,9 +3,11 @@ CREATE OR REPLACE
FUNCTION cartodb.CDB_Group_CreateGroup(group_name text)
RETURNS VOID AS $$
DECLARE
cdb_group_role TEXT;
group_role TEXT;
BEGIN
EXECUTE 'CREATE ROLE "' || cdb_group_role || '" NOLOGIN;';
group_role := cartodb._CDB_Group_GroupRole(group_name);
PERFORM cartodb._CDB_Group_CreateGroup_API(current_database(), group_name, group_role);
EXECUTE 'CREATE ROLE "' || group_role || '" NOLOGIN;';
END
$$ LANGUAGE PLPGSQL VOLATILE;
@ -21,6 +23,7 @@ DECLARE
cdb_group_role TEXT;
BEGIN
cdb_group_role := cartodb._CDB_Group_GroupRole(group_name);
PERFORM cartodb._CDB_Group_DropGroup_API(current_database(), group_name);
EXECUTE 'DROP OWNED BY "' || cdb_group_role || '"';
EXECUTE 'DROP ROLE IF EXISTS "' || cdb_group_role || '"';
END
@ -110,16 +113,18 @@ FUNCTION cartodb._CDB_Group_GroupRole(group_name text)
RETURNS TEXT AS $$
DECLARE
group_role TEXT;
max_length constant INTEGER := 60;
prefix TEXT;
max_length constant INTEGER := 63;
BEGIN
IF group_name !~ '^[a-zA-Z_][a-zA-Z0-9_]*$'
THEN
RAISE EXCEPTION 'Group name (%) must be a valid identifier. See http://www.postgresql.org/docs/9.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS', group_name;
END IF;
group_role := current_database() || '_g_' || group_name;
prefix = cartodb._CDB_Group_ShortDatabaseName() || '_g_';
group_role := prefix || group_name;
IF LENGTH(group_role) > max_length
THEN
RAISE EXCEPTION 'Group name should be shorter. Resulting role must have less than % characters, but it is longer: %', max_length, group_role;
RAISE EXCEPTION 'Group name must be shorter. It can''t have more than % characters, but it is longer (%): %', max_length - LENGTH(prefix), length(group_name), group_name;
END IF;
RETURN group_role;
END
@ -138,3 +143,15 @@ BEGIN
RETURN user_role;
END
$$ LANGUAGE PLPGSQL IMMUTABLE;
-- Database names are too long, we need a shorter version for composing role names
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_ShortDatabaseName()
RETURNS TEXT AS $$
DECLARE
short_database_name TEXT;
BEGIN
EXECUTE 'SELECT md5(current_database())' INTO short_database_name;
RETURN short_database_name;
END
$$ LANGUAGE PLPGSQL IMMUTABLE;

View File

@ -0,0 +1,55 @@
-- Sends the create group request
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_CreateGroup_API(database_name text, group_name text, group_role text)
RETURNS VOID AS
$$
import httplib
import base64
import string
import json
try:
conf = plpy.execute("SELECT cartodb.CDB_Conf_GetConf('groups_api') conf")[0]['conf']
if conf is None:
return
params = json.loads(conf)
client = httplib.HTTPConnection(params['host'], params['port'], False, params['timeout'])
url = '/api/v1/databases/%s/groups' % database_name
body = '{ "name": "%s", "database_role": "%s" }' % (group_name, group_role)
auth = base64.encodestring('%s:%s' % (params['username'], params['password'])).replace('\n', '')
headers = { 'Authorization': ('Basic %s' % auth), 'Content-Type': 'application/json' }
client.request('POST', url, body, headers)
response = client.getresponse()
assert response.status == 200
except Exception as err:
plpy.warning('group creation error: ' + str(err))
raise err
$$ LANGUAGE 'plpythonu' VOLATILE;
CREATE OR REPLACE
FUNCTION cartodb._CDB_Group_DropGroup_API(database_name text, group_name text)
RETURNS VOID AS
$$
import httplib
import base64
import string
import json
try:
conf = plpy.execute("SELECT cartodb.CDB_Conf_GetConf('groups_api') conf")[0]['conf']
if conf is None:
return
params = json.loads(conf)
client = httplib.HTTPConnection(params['host'], params['port'], False, params['timeout'])
url = '/api/v1/databases/%s/groups/%s' % (database_name, group_name)
auth = base64.encodestring('%s:%s' % (params['username'], params['password'])).replace('\n', '')
headers = { 'Authorization': ('Basic %s' % auth), 'Content-Type': 'application/json' }
client.request('DELETE', url, '', headers)
response = client.getresponse()
assert response.status == 200
except Exception as err:
plpy.warning('group creation error: ' + str(err))
raise err
$$ LANGUAGE 'plpythonu' VOLATILE;

View File

@ -159,9 +159,11 @@ function create_table() {
function setup() {
${CMD} -c "CREATE DATABASE ${DATABASE}"
sql "CREATE SCHEMA cartodb;"
sql "CREATE EXTENSION plpythonu;"
sql "GRANT USAGE ON SCHEMA cartodb TO public;"
log_info "########################### BOOTSTRAP ###########################"
${CMD} -d ${DATABASE} -f scripts-available/CDB_Conf.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Organizations.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Groups.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Groups_API.sql
@ -378,21 +380,18 @@ function test_user_can_read_when_it_has_permission_after_organization_permission
}
function test_cdb_querytables_returns_schema_and_table_name() {
sql "CREATE EXTENSION plpythonu;"
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
sql cdb_testmember_1 "select * from CDB_QueryTables('select * from foo');" should "{cdb_testmember_1.foo}"
}
function test_cdb_querytables_returns_schema_and_table_name_for_several_schemas() {
sql "CREATE EXTENSION plpythonu;"
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
sql postgres "select * from CDB_QueryTables('select * from cdb_testmember_1.foo, cdb_testmember_2.bar');" should "{cdb_testmember_1.foo,cdb_testmember_2.bar}"
}
function test_cdb_querytables_does_not_return_functions_as_part_of_the_resultset() {
sql "CREATE EXTENSION plpythonu;"
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
sql postgres "select * from CDB_QueryTables('select * from cdb_testmember_1.foo, cdb_testmember_2.bar, plainto_tsquery(''foo'')');" should "{cdb_testmember_1.foo,cdb_testmember_2.bar}"
@ -519,9 +518,9 @@ function test_org_admin_cant_grant_permissions_on_tables_he_does_not_own() {
}
function test_valid_group_names() {
sql "select cartodb._CDB_Group_GroupRole('group_1$_a');"
sql "select cartodb._CDB_Group_GroupRole('GROUP_1$_A');"
sql "select cartodb._CDB_Group_GroupRole('_group_1$_a');"
sql postgres "select cartodb._CDB_Group_GroupRole('group_1$_a');"
sql postgres "select cartodb._CDB_Group_GroupRole('GROUP_1$_A');"
sql postgres "select cartodb._CDB_Group_GroupRole('_group_1$_a');"
}
function test_not_valid_group_names() {
@ -538,6 +537,13 @@ function test_administrator_name_generation() {
sql postgres "select cartodb._CDB_Organization_Admin_Role_Name();"
}
function test_conf() {
sql postgres "SELECT cartodb.CDB_Conf_SetConf('test_conf', 'test_val')"
sql postgres "SELECT cartodb.CDB_Conf_GetConf('test_conf')" should 'test_val'
sql postgres "SELECT cartodb.CDB_Conf_RemoveConf('test_conf')"
sql postgres "SELECT cartodb.CDB_Conf_GetConf('test_conf')" should ''
}
#################################################### TESTS END HERE ####################################################