pgadmin4/web/pgadmin/browser/server_groups/servers/utils.py

180 lines
5.2 KiB
Python
Raw Normal View History

##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
2018-01-05 04:42:49 -06:00
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
"""Server helper utilities"""
def parse_priv_from_db(db_privileges):
"""
Common utility function to parse privileges retrieved from database.
"""
acl = {
'grantor': db_privileges['grantor'],
'grantee': db_privileges['grantee'],
2016-06-21 08:21:06 -05:00
'privileges': []
}
privileges = []
for idx, priv in enumerate(db_privileges['privileges']):
privileges.append({
"privilege_type": priv,
"privilege": True,
"with_grant": db_privileges['grantable'][idx]
2016-06-21 08:21:06 -05:00
})
acl['privileges'] = privileges
return acl
2016-06-21 08:21:06 -05:00
def parse_priv_to_db(str_privileges, allowed_acls=[]):
"""
Common utility function to parse privileges before sending to database.
"""
from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER
driver = get_driver(PG_DEFAULT_DRIVER)
db_privileges = {
'c': 'CONNECT',
'C': 'CREATE',
'T': 'TEMPORARY',
'a': 'INSERT',
'r': 'SELECT',
'w': 'UPDATE',
'd': 'DELETE',
'D': 'TRUNCATE',
'x': 'REFERENCES',
't': 'TRIGGER',
'U': 'USAGE',
'X': 'EXECUTE'
2016-06-21 08:21:06 -05:00
}
privileges = []
Resolved few issues (with some improvements) with existing nodes. This commit takes care of the following issues/improvements. * Adding missing imports for unauthorised in database module * Node under Servers Nodes (i.e. Databases, tablespaces, roles nodes) need to be inherited from PGChildNodeView (and, not from NodeView) for adding server version check for their children. * Adding statistics for database, and tablespaces in its node (not, yet in UI) * Renaming the camel case methods with proper name. (i.e. getSQL -> get_sql, getNewSQL -> get_new_sql, etc.) * Fixed the functions going beyond the text limit (column: 80) in Databases, Roles & Tablespaces modules. * Fixed the node method of Database module, which was not tested ever. * We do not need separate SQL template for fetching the name (i.e. get_name.sql), using the 'nodes.sql' for the same. * Optimise the query for fetching ACLs for the database node, we didn't require to join certain tables, while fetching only the ACLs. * Introduced the list of the ACLs (regular and default ACLs for different type) supported by each version [Databases Module]. * Renamed the templates 'get_nodes.sql' to' nodes.sql' to make it consistent with other modules. * Removed the checks for the authentication table use, as we don't need to expose the password to the users (even the encrypted MD5). Using the pg_roles view always for fetching roles/users information now. * Resolved some typos in unreachable (specially the exceptions catchment area.) * Logging the exception in the application. * Using qtLiteral, qtIdent properly in the templates (do not assume about the types of data.) * Using tsid as identifier instead of did for the tablespaces. * Using nodes method of tablespace view for fetching individual node information. * Removing the hardcoded node information from the 'parse_priv_to_db' function, and pass on allowed ACLs by the caller nodes. * Using 'nodes.sql' to fetch name of the template instead of writing that in the delete.sql template, which is definitely wrong place to fetch the name of the object. [Tablespace Module]
2016-02-22 00:14:24 -06:00
allowed_acls_len = len(allowed_acls)
for priv in str_privileges:
priv_with_grant = []
priv_without_grant = []
Resolved few issues (with some improvements) with existing nodes. This commit takes care of the following issues/improvements. * Adding missing imports for unauthorised in database module * Node under Servers Nodes (i.e. Databases, tablespaces, roles nodes) need to be inherited from PGChildNodeView (and, not from NodeView) for adding server version check for their children. * Adding statistics for database, and tablespaces in its node (not, yet in UI) * Renaming the camel case methods with proper name. (i.e. getSQL -> get_sql, getNewSQL -> get_new_sql, etc.) * Fixed the functions going beyond the text limit (column: 80) in Databases, Roles & Tablespaces modules. * Fixed the node method of Database module, which was not tested ever. * We do not need separate SQL template for fetching the name (i.e. get_name.sql), using the 'nodes.sql' for the same. * Optimise the query for fetching ACLs for the database node, we didn't require to join certain tables, while fetching only the ACLs. * Introduced the list of the ACLs (regular and default ACLs for different type) supported by each version [Databases Module]. * Renamed the templates 'get_nodes.sql' to' nodes.sql' to make it consistent with other modules. * Removed the checks for the authentication table use, as we don't need to expose the password to the users (even the encrypted MD5). Using the pg_roles view always for fetching roles/users information now. * Resolved some typos in unreachable (specially the exceptions catchment area.) * Logging the exception in the application. * Using qtLiteral, qtIdent properly in the templates (do not assume about the types of data.) * Using tsid as identifier instead of did for the tablespaces. * Using nodes method of tablespace view for fetching individual node information. * Removing the hardcoded node information from the 'parse_priv_to_db' function, and pass on allowed ACLs by the caller nodes. * Using 'nodes.sql' to fetch name of the template instead of writing that in the delete.sql template, which is definitely wrong place to fetch the name of the object. [Tablespace Module]
2016-02-22 00:14:24 -06:00
if isinstance(priv['privileges'], dict) \
and 'changed' in priv['privileges']:
tmp = []
for p in priv['privileges']['changed']:
tmp_p = {'privilege_type': p['privilege_type'],
'privilege': False,
'with_grant': False}
if 'with_grant' in p:
tmp_p['privilege'] = True
tmp_p['with_grant'] = p['with_grant']
if 'privilege' in p:
tmp_p['privilege'] = p['privilege']
tmp.append(tmp_p)
priv['privileges'] = tmp
for privilege in priv['privileges']:
Resolved few issues (with some improvements) with existing nodes. This commit takes care of the following issues/improvements. * Adding missing imports for unauthorised in database module * Node under Servers Nodes (i.e. Databases, tablespaces, roles nodes) need to be inherited from PGChildNodeView (and, not from NodeView) for adding server version check for their children. * Adding statistics for database, and tablespaces in its node (not, yet in UI) * Renaming the camel case methods with proper name. (i.e. getSQL -> get_sql, getNewSQL -> get_new_sql, etc.) * Fixed the functions going beyond the text limit (column: 80) in Databases, Roles & Tablespaces modules. * Fixed the node method of Database module, which was not tested ever. * We do not need separate SQL template for fetching the name (i.e. get_name.sql), using the 'nodes.sql' for the same. * Optimise the query for fetching ACLs for the database node, we didn't require to join certain tables, while fetching only the ACLs. * Introduced the list of the ACLs (regular and default ACLs for different type) supported by each version [Databases Module]. * Renamed the templates 'get_nodes.sql' to' nodes.sql' to make it consistent with other modules. * Removed the checks for the authentication table use, as we don't need to expose the password to the users (even the encrypted MD5). Using the pg_roles view always for fetching roles/users information now. * Resolved some typos in unreachable (specially the exceptions catchment area.) * Logging the exception in the application. * Using qtLiteral, qtIdent properly in the templates (do not assume about the types of data.) * Using tsid as identifier instead of did for the tablespaces. * Using nodes method of tablespace view for fetching individual node information. * Removing the hardcoded node information from the 'parse_priv_to_db' function, and pass on allowed ACLs by the caller nodes. * Using 'nodes.sql' to fetch name of the template instead of writing that in the delete.sql template, which is definitely wrong place to fetch the name of the object. [Tablespace Module]
2016-02-22 00:14:24 -06:00
if privilege['privilege_type'] not in db_privileges:
continue
if privilege['privilege_type'] not in allowed_acls:
continue
if privilege['with_grant']:
priv_with_grant.append(
2016-06-21 08:21:06 -05:00
db_privileges[privilege['privilege_type']]
)
elif privilege['privilege']:
priv_without_grant.append(
2016-06-21 08:21:06 -05:00
db_privileges[privilege['privilege_type']]
)
# If we have all acl then just return all
2016-08-22 06:30:16 -05:00
if len(priv_with_grant) == allowed_acls_len > 1:
priv_with_grant = ['ALL']
2016-08-22 06:30:16 -05:00
if len(priv_without_grant) == allowed_acls_len > 1:
priv_without_grant = ['ALL']
# Appending and returning all ACL
Resolved few issues (with some improvements) with existing nodes. This commit takes care of the following issues/improvements. * Adding missing imports for unauthorised in database module * Node under Servers Nodes (i.e. Databases, tablespaces, roles nodes) need to be inherited from PGChildNodeView (and, not from NodeView) for adding server version check for their children. * Adding statistics for database, and tablespaces in its node (not, yet in UI) * Renaming the camel case methods with proper name. (i.e. getSQL -> get_sql, getNewSQL -> get_new_sql, etc.) * Fixed the functions going beyond the text limit (column: 80) in Databases, Roles & Tablespaces modules. * Fixed the node method of Database module, which was not tested ever. * We do not need separate SQL template for fetching the name (i.e. get_name.sql), using the 'nodes.sql' for the same. * Optimise the query for fetching ACLs for the database node, we didn't require to join certain tables, while fetching only the ACLs. * Introduced the list of the ACLs (regular and default ACLs for different type) supported by each version [Databases Module]. * Renamed the templates 'get_nodes.sql' to' nodes.sql' to make it consistent with other modules. * Removed the checks for the authentication table use, as we don't need to expose the password to the users (even the encrypted MD5). Using the pg_roles view always for fetching roles/users information now. * Resolved some typos in unreachable (specially the exceptions catchment area.) * Logging the exception in the application. * Using qtLiteral, qtIdent properly in the templates (do not assume about the types of data.) * Using tsid as identifier instead of did for the tablespaces. * Using nodes method of tablespace view for fetching individual node information. * Removing the hardcoded node information from the 'parse_priv_to_db' function, and pass on allowed ACLs by the caller nodes. * Using 'nodes.sql' to fetch name of the template instead of writing that in the delete.sql template, which is definitely wrong place to fetch the name of the object. [Tablespace Module]
2016-02-22 00:14:24 -06:00
privileges.append({
'grantee': driver.qtIdent(None, priv['grantee'])
if priv['grantee'] != 'PUBLIC' else 'PUBLIC',
Resolved few issues (with some improvements) with existing nodes. This commit takes care of the following issues/improvements. * Adding missing imports for unauthorised in database module * Node under Servers Nodes (i.e. Databases, tablespaces, roles nodes) need to be inherited from PGChildNodeView (and, not from NodeView) for adding server version check for their children. * Adding statistics for database, and tablespaces in its node (not, yet in UI) * Renaming the camel case methods with proper name. (i.e. getSQL -> get_sql, getNewSQL -> get_new_sql, etc.) * Fixed the functions going beyond the text limit (column: 80) in Databases, Roles & Tablespaces modules. * Fixed the node method of Database module, which was not tested ever. * We do not need separate SQL template for fetching the name (i.e. get_name.sql), using the 'nodes.sql' for the same. * Optimise the query for fetching ACLs for the database node, we didn't require to join certain tables, while fetching only the ACLs. * Introduced the list of the ACLs (regular and default ACLs for different type) supported by each version [Databases Module]. * Renamed the templates 'get_nodes.sql' to' nodes.sql' to make it consistent with other modules. * Removed the checks for the authentication table use, as we don't need to expose the password to the users (even the encrypted MD5). Using the pg_roles view always for fetching roles/users information now. * Resolved some typos in unreachable (specially the exceptions catchment area.) * Logging the exception in the application. * Using qtLiteral, qtIdent properly in the templates (do not assume about the types of data.) * Using tsid as identifier instead of did for the tablespaces. * Using nodes method of tablespace view for fetching individual node information. * Removing the hardcoded node information from the 'parse_priv_to_db' function, and pass on allowed ACLs by the caller nodes. * Using 'nodes.sql' to fetch name of the template instead of writing that in the delete.sql template, which is definitely wrong place to fetch the name of the object. [Tablespace Module]
2016-02-22 00:14:24 -06:00
'with_grant': priv_with_grant,
'without_grant': priv_without_grant
2016-06-21 08:21:06 -05:00
})
return privileges
def tokenize_options(options_from_db, option_name, option_value):
"""
This function will tokenize the string stored in database
e.g. database store the value as below
key1=value1, key2=value2, key3=value3, ....
This function will extract key and value from above string
Args:
options_from_db: Options from database
option_name: Option Name
option_value: Option Value
Returns:
Tokenized options
"""
options = []
if options_from_db is not None:
option_str = options_from_db.split(',')
for fdw_option in option_str:
k, v = fdw_option.split('=', 1)
options.append({option_name: k, option_value: v})
return options
def validate_options(options, option_name, option_value):
"""
This function will filter validated options
and sets flag to use in sql template if there are any
valid options
Args:
options: List of options
option_name: Option Name
option_value: Option Value
Returns:
Flag, Filtered options
"""
valid_options = []
is_valid_options = False
for option in options:
# If option name is valid
if option_name in option and \
option[option_name] is not None and \
option[option_name] != '' and \
len(option[option_name].strip()) > 0:
# If option value is valid
if option_value in option and \
option[option_value] is not None and \
option[option_value] != '' and \
len(option[option_value].strip()) > 0:
# Do nothing here
pass
else:
# Set empty string if no value provided
option[option_value] = ''
valid_options.append(option)
if len(valid_options) > 0:
is_valid_options = True
return is_valid_options, valid_options