diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/acl.sql new file mode 100644 index 00000000..48e2a95b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/acl.sql @@ -0,0 +1,35 @@ +SELECT + 'datacl' AS deftype, COALESCE(gt.rolname, 'PUBLIC') AS grantee, + g.rolname AS grantor, array_agg(privilege_type) AS privileges, + array_agg(is_grantable) AS grantable +FROM + (SELECT + d.grantee, d.grantor, d.is_grantable, + CASE d.privilege_type + WHEN 'CONNECT' THEN 'c' + WHEN 'CREATE' THEN 'C' + WHEN 'DELETE' THEN 'd' + WHEN 'EXECUTE' THEN 'X' + WHEN 'INSERT' THEN 'a' + WHEN 'REFERENCES' THEN 'x' + WHEN 'SELECT' THEN 'r' + WHEN 'TEMPORARY' THEN 'T' + WHEN 'TRIGGER' THEN 't' + WHEN 'TRUNCATE' THEN 'D' + WHEN 'UPDATE' THEN 'w' + WHEN 'USAGE' THEN 'U' + ELSE 'UNKNOWN' + END AS privilege_type + FROM + (SELECT + (d).grantee AS grantee, (d).grantor AS grantor, + (d).is_grantable AS is_grantable, + (d).privilege_type AS privilege_type + FROM + (SELECT aclexplode(db.datacl) AS d FROM pg_database db + WHERE db.oid = {{ did|qtLiteral }}::OID) a + ) d + ) d + LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid) + LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid) +GROUP BY g.rolname, gt.rolname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/defacl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/defacl.sql new file mode 100644 index 00000000..aa08b56b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/defacl.sql @@ -0,0 +1,34 @@ +SELECT + CASE (a.deftype) + WHEN 'r' THEN 'deftblacl' + WHEN 'S' THEN 'defseqacl' + WHEN 'f' THEN 'deffuncacl' + WHEN 'T' THEN 'deftypeacl' + END AS deftype, + COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname grantor, array_agg(a.privilege_type) as privileges, array_agg(a.is_grantable) as grantable +FROM + (SELECT + (acl).grantee as grantee, (acl).grantor AS grantor, (acl).is_grantable AS is_grantable, + CASE (acl).privilege_type + WHEN 'CONNECT' THEN 'c' + WHEN 'CREATE' THEN 'C' + WHEN 'DELETE' THEN 'd' + WHEN 'EXECUTE' THEN 'X' + WHEN 'INSERT' THEN 'a' + WHEN 'REFERENCES' THEN 'x' + WHEN 'SELECT' THEN 'r' + WHEN 'TEMPORARY' THEN 'T' + WHEN 'TRIGGER' THEN 't' + WHEN 'TRUNCATE' THEN 'D' + WHEN 'UPDATE' THEN 'w' + WHEN 'USAGE' THEN 'U' + ELSE 'UNKNOWN' + END AS privilege_type, + defaclobjtype as deftype + FROM + (SELECT defaclobjtype, aclexplode(defaclacl) as acl FROM pg_catalog.pg_default_acl dacl + WHERE dacl.defaclnamespace = 0::OID) d) a + LEFT JOIN pg_catalog.pg_roles g ON (a.grantor = g.oid) + LEFT JOIN pg_catalog.pg_roles gt ON (a.grantee = gt.oid) +GROUP BY g.rolname, gt.rolname, a.deftype +ORDER BY a.deftype diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_ctypes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_ctypes.sql new file mode 100644 index 00000000..46246ef6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_ctypes.sql @@ -0,0 +1,5 @@ +SELECT DISTINCT(datctype) AS cname +FROM pg_database +UNION +SELECT DISTINCT(datcollate) AS cname +FROM pg_database \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_variables.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_variables.sql new file mode 100644 index 00000000..d76d02b3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/get_variables.sql @@ -0,0 +1,5 @@ + SELECT rl.*, r.rolname AS user_name, db.datname as db_name +FROM pg_db_role_setting AS rl + LEFT JOIN pg_roles AS r ON rl.setrole = r.oid + LEFT JOIN pg_database AS db ON rl.setdatabase = db.oid +WHERE setdatabase = {{did}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql new file mode 100644 index 00000000..a251ebd5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/9.1_plus/properties.sql @@ -0,0 +1,43 @@ +SELECT + db.oid AS did, db.datname AS name, db.dattablespace AS spcoid, + spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding, + pg_get_userbyid(datdba) AS datowner, datcollate, datctype, datconnlimit, + has_database_privilege(db.oid, 'CREATE') AS cancreate, + current_setting('default_tablespace') AS default_tablespace, + descr.description AS comments, db.datistemplate AS is_template, + {### Default ACL for Tables ###} + (SELECT array_to_string(ARRAY( + SELECT array_to_string(defaclacl::text[], ', ') + FROM pg_default_acl + WHERE defaclobjtype = 'r' AND defaclnamespace = 0::OID + ), ', ')) AS tblacl, + {### Default ACL for Sequnces ###} + (SELECT array_to_string(ARRAY( + SELECT array_to_string(defaclacl::text[], ', ') + FROM pg_default_acl + WHERE defaclobjtype = 'S' AND defaclnamespace = 0::OID + ), ', ')) AS seqacl, + {### Default ACL for Functions ###} + (SELECT array_to_string(ARRAY( + SELECT array_to_string(defaclacl::text[], ', ') + FROM pg_default_acl + WHERE defaclobjtype = 'f' AND defaclnamespace = 0::OID + ), ', ')) AS funcacl, + array_to_string(datacl::text[], ', ') AS acl +FROM pg_database db + LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID + LEFT OUTER JOIN pg_shdescription descr ON ( + db.oid=descr.objoid AND descr.classoid='pg_database'::regclass + ) +WHERE {% if did %} +db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %} +db.datname = {{ name|qtLiteral }}::text{% else %} +db.oid > {{ last_system_oid|qtLiteral }}::OID +{% endif %}{% endif %} +{% if db_restrictions %} + +AND +db.datname in ({{db_restrictions}}) +{% endif %} + +ORDER BY datname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/acl.sql index 48e2a95b..226f4b22 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/acl.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/acl.sql @@ -4,7 +4,9 @@ SELECT array_agg(is_grantable) AS grantable FROM (SELECT - d.grantee, d.grantor, d.is_grantable, + d.grantee, + d.grantor, + d.is_grantable, CASE d.privilege_type WHEN 'CONNECT' THEN 'c' WHEN 'CREATE' THEN 'C' @@ -22,14 +24,36 @@ FROM END AS privilege_type FROM (SELECT - (d).grantee AS grantee, (d).grantor AS grantor, - (d).is_grantable AS is_grantable, - (d).privilege_type AS privilege_type - FROM - (SELECT aclexplode(db.datacl) AS d FROM pg_database db - WHERE db.oid = {{ did|qtLiteral }}::OID) a + u_grantor.oid AS grantor, + grantee.oid AS grantee, + pr.type AS privilege_type, + aclcontains(c.datacl, makeaclitem(grantee.oid, u_grantor.oid, pr.type, true)) AS is_grantable + FROM pg_database c, pg_authid u_grantor, ( + SELECT pg_authid.oid, pg_authid.rolname + FROM pg_authid + UNION ALL + SELECT 0::oid AS oid, 'PUBLIC') grantee(oid, rolname), + ( SELECT 'SELECT' + UNION ALL + SELECT 'INSERT' + UNION ALL + SELECT 'UPDATE' + UNION ALL + SELECT 'DELETE' + UNION ALL + SELECT 'TRUNCATE' + UNION ALL + SELECT 'REFERENCES' + UNION ALL + SELECT 'TRIGGER') pr(type) + WHERE aclcontains(c.datacl, makeaclitem(grantee.oid, u_grantor.oid, pr.type, false)) + AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR pg_has_role(grantee.oid, 'USAGE'::text) + OR grantee.rolname = 'PUBLIC'::name) + AND c.oid = {{ did|qtLiteral }}::OID ) d ) d LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid) LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid) GROUP BY g.rolname, gt.rolname; + + diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/defacl.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/defacl.sql index aa08b56b..191e40cc 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/defacl.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/defacl.sql @@ -1,34 +1,7 @@ SELECT - CASE (a.deftype) - WHEN 'r' THEN 'deftblacl' - WHEN 'S' THEN 'defseqacl' - WHEN 'f' THEN 'deffuncacl' - WHEN 'T' THEN 'deftypeacl' - END AS deftype, - COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname grantor, array_agg(a.privilege_type) as privileges, array_agg(a.is_grantable) as grantable -FROM - (SELECT - (acl).grantee as grantee, (acl).grantor AS grantor, (acl).is_grantable AS is_grantable, - CASE (acl).privilege_type - WHEN 'CONNECT' THEN 'c' - WHEN 'CREATE' THEN 'C' - WHEN 'DELETE' THEN 'd' - WHEN 'EXECUTE' THEN 'X' - WHEN 'INSERT' THEN 'a' - WHEN 'REFERENCES' THEN 'x' - WHEN 'SELECT' THEN 'r' - WHEN 'TEMPORARY' THEN 'T' - WHEN 'TRIGGER' THEN 't' - WHEN 'TRUNCATE' THEN 'D' - WHEN 'UPDATE' THEN 'w' - WHEN 'USAGE' THEN 'U' - ELSE 'UNKNOWN' - END AS privilege_type, - defaclobjtype as deftype - FROM - (SELECT defaclobjtype, aclexplode(defaclacl) as acl FROM pg_catalog.pg_default_acl dacl - WHERE dacl.defaclnamespace = 0::OID) d) a - LEFT JOIN pg_catalog.pg_roles g ON (a.grantor = g.oid) - LEFT JOIN pg_catalog.pg_roles gt ON (a.grantee = gt.oid) -GROUP BY g.rolname, gt.rolname, a.deftype -ORDER BY a.deftype + '' AS deftype, + '' AS grantee, + '' AS grantor, + '' AS grantor, + '' AS privileges, + '' AS grantable diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_ctypes.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_ctypes.sql index 46246ef6..523db309 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_ctypes.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_ctypes.sql @@ -1,5 +1,3 @@ -SELECT DISTINCT(datctype) AS cname -FROM pg_database +SELECT current_setting('lc_ctype') as cname UNION -SELECT DISTINCT(datcollate) AS cname -FROM pg_database \ No newline at end of file +SELECT current_setting('lc_collate') as cname diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_variables.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_variables.sql index d76d02b3..d5384c64 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_variables.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/get_variables.sql @@ -1,5 +1,2 @@ - SELECT rl.*, r.rolname AS user_name, db.datname as db_name -FROM pg_db_role_setting AS rl - LEFT JOIN pg_roles AS r ON rl.setrole = r.oid - LEFT JOIN pg_database AS db ON rl.setdatabase = db.oid -WHERE setdatabase = {{did}} +SELECT NULL +WHERE false diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql index a251ebd5..5db9b882 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/sql/default/properties.sql @@ -1,28 +1,19 @@ SELECT db.oid AS did, db.datname AS name, db.dattablespace AS spcoid, spcname, datallowconn, pg_encoding_to_char(encoding) AS encoding, - pg_get_userbyid(datdba) AS datowner, datcollate, datctype, datconnlimit, + pg_get_userbyid(datdba) AS datowner, + (select current_setting('lc_collate')) as datcollate, + (select current_setting('lc_ctype')) as datctype, + datconnlimit, has_database_privilege(db.oid, 'CREATE') AS cancreate, current_setting('default_tablespace') AS default_tablespace, descr.description AS comments, db.datistemplate AS is_template, {### Default ACL for Tables ###} - (SELECT array_to_string(ARRAY( - SELECT array_to_string(defaclacl::text[], ', ') - FROM pg_default_acl - WHERE defaclobjtype = 'r' AND defaclnamespace = 0::OID - ), ', ')) AS tblacl, + '' AS tblacl, {### Default ACL for Sequnces ###} - (SELECT array_to_string(ARRAY( - SELECT array_to_string(defaclacl::text[], ', ') - FROM pg_default_acl - WHERE defaclobjtype = 'S' AND defaclnamespace = 0::OID - ), ', ')) AS seqacl, + '' AS seqacl, {### Default ACL for Functions ###} - (SELECT array_to_string(ARRAY( - SELECT array_to_string(defaclacl::text[], ', ') - FROM pg_default_acl - WHERE defaclobjtype = 'f' AND defaclnamespace = 0::OID - ), ', ')) AS funcacl, + '' AS funcacl, array_to_string(datacl::text[], ', ') AS acl FROM pg_database db LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID diff --git a/web/pgadmin/feature_tests/query_tool_tests.py b/web/pgadmin/feature_tests/query_tool_tests.py index 4122ddf3..63c29d04 100644 --- a/web/pgadmin/feature_tests/query_tool_tests.py +++ b/web/pgadmin/feature_tests/query_tool_tests.py @@ -53,16 +53,22 @@ class QueryToolFeatureTest(BaseFeatureTest): # explain query with verbose and cost print("Explain query with verbose and cost... ", file=sys.stderr, end="") - self._query_tool_explain_with_verbose_and_cost() - print("OK.", file=sys.stderr) - self._clear_query_tool() + if self._test_explain_plan_feature(): + self._query_tool_explain_with_verbose_and_cost() + print("OK.", file=sys.stderr) + self._clear_query_tool() + else: + print("Skipped.", file=sys.stderr) # explain analyze query with buffers and timing print("Explain analyze query with buffers and timing... ", file=sys.stderr, end="") - self._query_tool_explain_analyze_with_buffers_and_timing() - print("OK.", file=sys.stderr) - self._clear_query_tool() + if self._test_explain_plan_feature(): + self._query_tool_explain_analyze_with_buffers_and_timing() + print("OK.", file=sys.stderr) + self._clear_query_tool() + else: + print("Skipped.", file=sys.stderr) # auto commit disabled. print("Auto commit disabled... ", file=sys.stderr, end="") @@ -567,3 +573,12 @@ SELECT 1, pg_sleep(300)""" self.page.find_by_xpath( '//div[contains(@class, "sql-editor-message") and contains(string(), "canceling statement due to user request")]' ) + + def _test_explain_plan_feature(self): + connection = test_utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port'], + self.server['sslmode']) + return connection.server_version > 90100 diff --git a/web/pgadmin/feature_tests/xss_checks_roles_control_test.py b/web/pgadmin/feature_tests/xss_checks_roles_control_test.py index e73826f7..1120cad5 100644 --- a/web/pgadmin/feature_tests/xss_checks_roles_control_test.py +++ b/web/pgadmin/feature_tests/xss_checks_roles_control_test.py @@ -21,6 +21,10 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest): ] def before(self): + with test_utils.Database(self.server) as (connection, _): + if connection.server_version < 90100: + self.skipTest("Membership is not present in pgAdmin below PG v9.1") + # Some test function is needed for debugger test_utils.create_role(self.server, "postgres", "test_role") diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py index 5dc0d128..b934e907 100644 --- a/web/regression/python_test_utils/test_utils.py +++ b/web/regression/python_test_utils/test_utils.py @@ -302,15 +302,19 @@ def create_role(server, db_name, role_name="test_role"): old_isolation_level = connection.isolation_level connection.set_isolation_level(0) pg_cursor = connection.cursor() - pg_cursor.execute(''' + sql_query = ''' CREATE USER "%s" WITH LOGIN NOSUPERUSER INHERIT CREATEDB NOCREATEROLE - NOREPLICATION ''' % (role_name) + if connection.server_version > 90100: + sql_query += '\nNOREPLICATION' + + pg_cursor.execute( + sql_query ) connection.set_isolation_level(old_isolation_level) connection.commit()