cartodb-postgresql/scripts-available/CDB_Groups_API.sql

258 lines
8.8 KiB
MySQL
Raw Normal View History

----------------------------------
-- GROUP METADATA API FUNCTIONS
--
-- Meant to be used by CDB_Group_* functions to sync data with the editor.
2019-05-31 21:29:28 +08:00
-- Requires configuration parameter. Example: SELECT @extschema@.CDB_Conf_SetConf('groups_api', '{ "host": "127.0.0.1", "port": 3000, "timeout": 10, "username": "extension", "password": "elephant" }');
----------------------------------
2015-08-14 20:03:53 +08:00
2019-05-31 21:29:28 +08:00
DROP FUNCTION IF EXISTS @extschema@.CDB_Group_AddMember(group_name text, username text);
DROP FUNCTION IF EXISTS @extschema@.CDB_Group_RemoveMember(group_name text, username text);
DROP FUNCTION IF EXISTS @extschema@._CDB_Group_AddMember_API(group_name text, username text);
DROP FUNCTION IF EXISTS @extschema@._CDB_Group_RemoveMember_API(group_name text, username text);
2015-09-07 16:35:32 +08:00
-- Sends the create group request
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_CreateGroup_API(group_name text, group_role text)
RETURNS VOID AS
$$
import string
2015-09-04 02:41:19 +08:00
url = '/api/v1/databases/{0}/groups'
2015-08-18 14:10:02 +08:00
body = '{ "name": "%s", "database_role": "%s" }' % (group_name, group_role)
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('POST', '%s', '%s', '{200, 409}') as response_status" % (url, body)
2015-08-18 16:44:10 +08:00
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_DropGroup_API(group_name text)
RETURNS VOID AS
$$
import string
2019-10-22 23:48:46 +08:00
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
2019-10-22 23:48:46 +08:00
url = '/api/v1/databases/{0}/groups/%s' % (pathname2url(group_name))
2015-09-04 02:41:19 +08:00
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('DELETE', '%s', '', '{204, 404}') as response_status" % url
2015-08-18 16:44:10 +08:00
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
2015-08-17 17:49:31 +08:00
2015-08-17 19:37:34 +08:00
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_RenameGroup_API(old_group_name text, new_group_name text, new_group_role text)
2015-08-17 19:37:34 +08:00
RETURNS VOID AS
$$
import string
2019-10-22 23:48:46 +08:00
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
2015-08-17 19:37:34 +08:00
2019-10-22 23:48:46 +08:00
url = '/api/v1/databases/{0}/groups/%s' % (pathname2url(old_group_name))
2015-08-18 14:10:02 +08:00
body = '{ "name": "%s", "database_role": "%s" }' % (new_group_name, new_group_role)
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('PUT', '%s', '%s', '{200, 409}') as response_status" % (url, body)
2015-08-18 16:44:10 +08:00
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
2015-08-17 19:37:34 +08:00
2015-08-17 21:05:09 +08:00
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_AddUsers_API(group_name text, usernames text[])
2015-08-17 21:05:09 +08:00
RETURNS VOID AS
$$
import string
2019-10-22 23:48:46 +08:00
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
2015-08-17 21:05:09 +08:00
2019-10-22 23:48:46 +08:00
url = '/api/v1/databases/{0}/groups/%s/users' % (pathname2url(group_name))
body = "{ \"users\": [\"%s\"] }" % "\",\"".join(usernames)
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('POST', '%s', '%s', '{200, 409}') as response_status" % (url, body)
2015-08-18 16:44:10 +08:00
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
2015-08-17 21:05:09 +08:00
2015-08-17 21:20:15 +08:00
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_RemoveUsers_API(group_name text, usernames text[])
2015-08-17 21:20:15 +08:00
RETURNS VOID AS
$$
import string
2019-10-22 23:48:46 +08:00
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
2015-08-17 21:20:15 +08:00
2019-10-22 23:48:46 +08:00
url = '/api/v1/databases/{0}/groups/%s/users' % (pathname2url(group_name))
body = "{ \"users\": [\"%s\"] }" % "\",\"".join(usernames)
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('DELETE', '%s', '%s', '{200, 404}') as response_status" % (url, body)
2015-08-18 16:44:10 +08:00
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
2015-08-17 21:20:15 +08:00
2015-08-17 17:49:31 +08:00
DO LANGUAGE 'plpgsql' $$
BEGIN
2015-08-19 17:20:06 +08:00
-- Needed for dropping type
2019-05-31 21:29:28 +08:00
DROP FUNCTION IF EXISTS @extschema@._CDB_Group_API_Conf();
DROP TYPE IF EXISTS @extschema@._CDB_Group_API_Params;
2015-08-17 17:49:31 +08:00
END
$$;
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_Table_GrantPermission_API(group_name text, username text, table_name text, access text)
RETURNS VOID AS
$$
import string
2019-10-22 23:48:46 +08:00
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
2019-10-22 23:48:46 +08:00
url = '/api/v1/databases/{0}/groups/%s/permission/%s/tables/%s' % (pathname2url(group_name), username, table_name)
body = '{ "access": "%s" }' % access
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('PUT', '%s', '%s', '{200, 409}') as response_status" % (url, body)
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
DO LANGUAGE 'plpgsql' $$
BEGIN
-- Needed for dropping type
2019-05-31 21:29:28 +08:00
DROP FUNCTION IF EXISTS @extschema@._CDB_Group_API_Conf();
DROP TYPE IF EXISTS @extschema@._CDB_Group_API_Params;
END
$$;
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_Table_RevokeAllPermission_API(group_name text, username text, table_name text)
RETURNS VOID AS
$$
import string
2019-10-22 23:48:46 +08:00
try:
from urllib import pathname2url
except:
from urllib.request import pathname2url
2019-10-22 23:48:46 +08:00
url = '/api/v1/databases/{0}/groups/%s/permission/%s/tables/%s' % (pathname2url(group_name), username, table_name)
2019-05-31 21:29:28 +08:00
query = "select @extschema@._CDB_Group_API_Request('DELETE', '%s', '', '{200, 404}') as response_status" % url
plpy.execute(query)
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@'
2019-10-04 00:51:28 +08:00
VOLATILE
PARALLEL UNSAFE
SECURITY DEFINER
SET search_path = pg_temp;
DO LANGUAGE 'plpgsql' $$
BEGIN
-- Needed for dropping type
2019-05-31 21:29:28 +08:00
DROP FUNCTION IF EXISTS @extschema@._CDB_Group_API_Conf();
DROP TYPE IF EXISTS @extschema@._CDB_Group_API_Params;
END
$$;
2019-05-31 21:29:28 +08:00
CREATE TYPE @extschema@._CDB_Group_API_Params AS (
2015-08-17 17:49:31 +08:00
host text,
port int,
timeout int,
2015-08-17 18:26:38 +08:00
auth text
2015-08-17 17:49:31 +08:00
);
-- This must be explicitally extracted because "composite types are currently not supported".
-- See http://www.postgresql.org/docs/9.3/static/plpython-database.html.
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_API_Conf()
RETURNS @extschema@._CDB_Group_API_Params AS
2015-08-17 17:49:31 +08:00
$$
2019-05-31 21:29:28 +08:00
conf = plpy.execute("SELECT @extschema@.CDB_Conf_GetConf('groups_api') conf")[0]['conf']
2015-08-17 17:49:31 +08:00
if conf is None:
return None
else:
import json
params = json.loads(conf)
2019-05-31 21:29:28 +08:00
auth = 'Basic %s' % plpy.execute("SELECT @extschema@._CDB_Group_API_Auth('%s', '%s') as auth" % (params['username'], params['password']))[0]['auth']
2015-08-17 18:26:38 +08:00
return { "host": params['host'], "port": params['port'], 'timeout': params['timeout'], 'auth': auth }
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@' VOLATILE PARALLEL UNSAFE;
2015-08-17 17:49:31 +08:00
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_API_Auth(username text, password text)
2015-08-17 17:49:31 +08:00
RETURNS TEXT AS
$$
import sys
2015-08-17 17:49:31 +08:00
import base64
data_to_encode = '%s:%s' % (username, password)
2020-02-12 02:31:37 +08:00
if sys.version_info[0] < 3:
2020-02-12 17:09:07 +08:00
data_encoded = base64.encodestring(data_to_encode)
2020-02-12 02:31:37 +08:00
else:
2020-02-12 17:09:07 +08:00
data_encoded = base64.b64encode(data_to_encode.encode()).decode()
data_encoded = data_encoded.replace('\n', '')
return data_encoded
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@' VOLATILE PARALLEL UNSAFE;
2015-08-18 14:10:02 +08:00
2015-08-19 17:08:05 +08:00
-- url must contain a '%s' placeholder that will be replaced by current_database, for security reasons.
2015-08-18 14:10:02 +08:00
CREATE OR REPLACE
2019-05-31 21:29:28 +08:00
FUNCTION @extschema@._CDB_Group_API_Request(method text, url text, body text, valid_return_codes int[])
2015-08-18 14:10:02 +08:00
RETURNS int AS
$$
python_v2 = True
try:
import httplib as client
except:
from http import client
2020-02-12 17:09:07 +08:00
python_v2 = False
2015-08-18 14:10:02 +08:00
2019-05-31 21:29:28 +08:00
params = plpy.execute("select c.host, c.port, c.timeout, c.auth from @extschema@._CDB_Group_API_Conf() c;")[0]
2015-08-18 14:10:02 +08:00
if params['host'] is None:
return None
2015-09-22 01:01:40 +08:00
headers = { 'Authorization': params['auth'], 'Content-Type': 'application/json', 'X-Forwarded-Proto': 'https' }
2015-08-18 14:10:02 +08:00
retry = 3
last_err = None
while retry > 0:
try:
if python_v2:
conn = SD['groups_api_client'] = client.HTTPConnection(params['host'], params['port'], False, params['timeout'])
else:
conn = SD['groups_api_client'] = client.HTTPConnection(params['host'], port=params['port'], timeout=params['timeout'])
database_name = plpy.execute("select current_database();")[0]['current_database']
conn.request(method, url.format(database_name), body, headers)
response = conn.getresponse()
2015-08-18 17:53:38 +08:00
assert response.status in valid_return_codes
2015-08-18 14:10:02 +08:00
return response.status
except Exception as err:
retry -= 1
last_err = err
plpy.warning('Retrying after: ' + str(err))
conn = SD['groups_api_client'] = None
2015-08-18 14:10:02 +08:00
if last_err is not None:
plpy.error('Fatal Group API error: ' + str(last_err))
raise last_err
2015-08-18 16:44:10 +08:00
return None
2019-12-27 00:48:12 +08:00
$$ LANGUAGE '@@plpythonu@@' VOLATILE PARALLEL UNSAFE;
2019-05-31 21:29:28 +08:00
revoke all on function @extschema@._CDB_Group_API_Request(text, text, text, int[]) from public;