public inbox for [email protected]  
help / color / mirror / Atom feed
From: Pradip Parkale <[email protected]>
To: pgadmin-hackers <[email protected]>
Subject: [pgAdmin][RM6201]:SSL Support in subscription.
Date: Fri, 19 Feb 2021 13:08:12 +0530
Message-ID: <CAJ9T6StZuyKV=1bKc6zuegSXh94Ttn0e98vSraEp2dpqXhnFLw@mail.gmail.com> (raw)

Hi Hackers,

Please find the attached patch for SSL support in the subscription. I have
also fixed the issue raised during the testing of logical replication.



-- 
Thanks & Regards,
Pradip Parkale
Software Engineer | EnterpriseDB Corporation


Attachments:

  [application/octet-stream] RM6201.patch (31.9K, 3-RM6201.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index 5daef8120..2f22caf57 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -244,6 +244,7 @@ class ServerModule(sg.ServerGroupPluginModule):
                 user=user_info,
                 in_recovery=in_recovery,
                 wal_pause=wal_paused,
+                host=server.host,
                 is_password_saved=bool(server.save_password),
                 is_tunnel_password_saved=True
                 if server.tunnel_password is not None else False,
@@ -535,6 +536,7 @@ class ServerNode(PGChildNodeView):
                     server_type=server_type,
                     version=manager.version,
                     db=manager.db,
+                    host=server.host,
                     user=manager.user_info if connected else None,
                     in_recovery=in_recovery,
                     wal_pause=wal_paused,
@@ -604,6 +606,7 @@ class ServerNode(PGChildNodeView):
                 user=manager.user_info if connected else None,
                 in_recovery=in_recovery,
                 wal_pause=wal_paused,
+                host=server.host,
                 is_password_saved=bool(server.save_password),
                 is_tunnel_password_saved=True
                 if server.tunnel_password is not None else False,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
index 720d628be..4fe459717 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js
@@ -80,6 +80,7 @@ define('pgadmin.node.publication', [
           evnt_update:true,
           evnt_truncate:true,
           only_table: undefined,
+          publish_via_partition_root: false,
         },
 
         // Default values!
@@ -177,6 +178,20 @@ define('pgadmin.node.publication', [
               return false;
             },
 
+          },{
+            id: 'publish_via_partition_root', label: gettext('Publish via root?'),
+            type: 'switch', group: gettext('With'),
+            extraToggleClasses: 'pg-el-sm-6',
+            controlLabelClassName: 'control-label pg-el-sm-5 pg-el-12',
+            controlsClassName: 'pgadmin-controls pg-el-sm-7 pg-el-12',
+            visible: function(m) {
+              if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
+              && !_.isUndefined(m.node_info.server.version) &&
+                m.node_info.server.version >= 130000)
+                return true;
+              return false;
+            },
+
           }],
         },
         ],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql
index 06c953ba7..0bded27d1 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/11_plus/properties.sql
@@ -2,7 +2,7 @@ SELECT c.oid AS oid, c.pubname AS name,
 pubinsert AS evnt_insert, pubupdate AS evnt_update, pubdelete AS evnt_delete, pubtruncate AS evnt_truncate,
 puballtables AS all_table,
 pga.rolname AS pubowner FROM pg_publication c
-JOIN pg_authid pga ON c.pubowner= pga.oid
+JOIN pg_roles pga ON c.pubowner= pga.oid
 {%  if pbid %}
     WHERE c.oid = {{ pbid }}
 {% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/create.sql
new file mode 100644
index 000000000..4f574127e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/create.sql
@@ -0,0 +1,23 @@
+{% if data.evnt_delete or data.evnt_update or data.evnt_truncate %}
+{% set add_comma_after_insert = 'insert' %}
+{% endif %}
+{% if data.evnt_truncate %}
+{% set add_comma_after_delete = 'delete' %}
+{% endif %}
+{% if data.evnt_delete or data.evnt_truncate%}
+{% set add_comma_after_update = 'update' %}
+{% endif %}
+{% if data.publish_via_partition_root%}
+{% set add_comma_after_truncate = 'truncate' %}
+{% endif %}
+{###  Create PUBLICATION ###}
+CREATE PUBLICATION {{ conn|qtIdent(data.name) }}
+{% if data.all_table %}
+    FOR ALL TABLES
+{% elif data.pubtable %}
+    FOR TABLE {% if data.only_table%}ONLY {% endif %}{% for pub_table in data.pubtable %}{% if loop.index != 1 %}, {% endif %}{{ pub_table }}{% endfor %}
+
+{% endif %}
+{% if data.evnt_insert or data.evnt_update or data.evnt_delete or data.evnt_truncate %}
+    WITH (publish = '{% if data.evnt_insert %}insert{% if add_comma_after_insert == 'insert' %}, {% endif %}{% endif %}{% if data.evnt_update %}update{% if add_comma_after_update == 'update' %}, {% endif %}{% endif %}{% if data.evnt_delete %}delete{% if add_comma_after_delete == 'delete' %}, {% endif %}{% endif %}{% if data.evnt_truncate %}truncate{% endif %}', publish_via_partition_root = {{ data.publish_via_partition_root|lower }});
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/properties.sql
new file mode 100644
index 000000000..1694577f6
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/properties.sql
@@ -0,0 +1,9 @@
+SELECT c.oid AS oid, c.pubname AS name,
+pubinsert AS evnt_insert, pubupdate AS evnt_update, pubdelete AS evnt_delete, pubtruncate AS evnt_truncate,
+puballtables AS all_table,
+pubviaroot AS publish_via_partition_root,
+pga.rolname AS pubowner FROM pg_publication c
+JOIN pg_roles pga ON c.pubowner= pga.oid
+{%  if pbid %}
+    WHERE c.oid = {{ pbid }}
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/update.sql
new file mode 100644
index 000000000..58542ea4b
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/13_plus/update.sql
@@ -0,0 +1,48 @@
+{% if data.evnt_delete or data.evnt_update or data.evnt_truncate %}
+{% set add_comma_after_insert = 'insert' %}
+{% endif %}
+{% if data.evnt_truncate %}
+{% set add_comma_after_delete = 'delete' %}
+{% endif %}
+{% if data.evnt_delete or data.evnt_truncate%}
+{% set add_comma_after_update = 'update' %}
+{% endif %}
+{###  Alter publication owner ###}
+{% if data.pubowner %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+    OWNER TO {{ data.pubowner }};
+
+{% endif %}
+{###  Alter publication event ###}
+{% if (data.evnt_insert is defined and data.evnt_insert != o_data.evnt_insert) or (data.evnt_update is defined and data.evnt_update != o_data.evnt_update) or (data.evnt_delete is defined and data.evnt_delete != o_data.evnt_delete) or (data.evnt_truncate is defined and data.evnt_truncate != o_data.evnt_truncate) %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }} SET
+    (publish = '{% if data.evnt_insert %}insert{% if add_comma_after_insert == 'insert' %}, {% endif %}{% endif %}{% if data.evnt_update %}update{% if add_comma_after_update == 'update' %}, {% endif %}{% endif %}{% if data.evnt_delete %}delete{% if add_comma_after_delete == 'delete' %}, {% endif %}{% endif %}{% if data.evnt_truncate %}truncate{% endif %}');
+
+{% endif %}
+{###  Alter publication partition root ###}
+{% if data.publish_via_partition_root is defined and data.publish_via_partition_root != o_data.publish_via_partition_root%}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }} SET
+    (publish_via_partition_root = {{ data.publish_via_partition_root|lower }});
+
+{% endif %}
+{###  Alter drop publication table ###}
+{% if drop_table %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+    DROP TABLE {% if data.only_table%}ONLY {% endif %}{% for pub_table in drop_table_data %}{% if loop.index != 1 %}, {% endif %}{{ pub_table }}{% endfor %};
+
+{% endif %}
+{###  Alter publication table ###}
+{% if add_table %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+    ADD TABLE {% if data.only_table%}ONLY {% endif %}{% for pub_table in add_table_data %}{% if loop.index != 1 %}, {% endif %}{{ pub_table }}{% endfor %};
+
+{% endif %}
+{###  Alter publication name ###}
+{% if data.name != o_data.name %}
+ALTER PUBLICATION {{ conn|qtIdent(o_data.name) }}
+    RENAME TO {{ conn|qtIdent(data.name) }};
+{% endif %}
+
+
+
+
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql
index 874cf00eb..d804ea071 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/get_all_tables.sql
@@ -3,4 +3,5 @@ FROM information_schema.tables c
 WHERE c.table_type = 'BASE TABLE'
       AND c.table_schema NOT LIKE 'pg\_%'
       AND c.table_schema NOT LIKE 'pgagent'
+	  AND c.table_schema NOT LIKE 'sys'
       AND c.table_schema NOT IN ('information_schema') ORDER BY 1;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql
index 56ac3dac3..8f6edee94 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/publications/templates/publications/sql/default/properties.sql
@@ -2,7 +2,7 @@ SELECT c.oid AS oid, c.pubname AS name,
 pubinsert AS evnt_insert, pubupdate AS evnt_update, pubdelete AS evnt_delete,
 puballtables AS all_table,
 pga.rolname AS pubowner FROM pg_publication c
-JOIN pg_authid pga ON c.pubowner= pga.oid
+JOIN pg_roles pga ON c.pubowner= pga.oid
 {%  if pbid %}
     where c.oid = {{ pbid }}
 {% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py
index f2e72207d..48cc1a1ad 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/__init__.py
@@ -261,8 +261,14 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
                                         self._PROPERTIES_SQL]), did=did)
         status, res = self.conn.execute_dict(sql)
 
+        # Check for permission denied message
+        if 'permission denied' in res:
+            return internal_server_error(
+                errormsg="Access is revoked for normal users")
+
         if not status:
             return internal_server_error(errormsg=res)
+
         return ajax_response(
             response=res['rows'],
             status=200
@@ -680,14 +686,21 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
             host=connection_details['host'],
             database=connection_details['db'],
             user=connection_details['username'],
-            password=connection_details['password'] if
-            connection_details['password'] else None,
+            password=connection_details[
+                'password'] if 'password' in connection_details else None,
             port=connection_details['port'] if
             connection_details['port'] else None,
             passfile=get_complete_file_path(passfile),
             connect_timeout=connection_details['connect_timeout'] if
             'connect_timeout' in connection_details and
-            connection_details['connect_timeout'] else 0
+            connection_details['connect_timeout'] else 0,
+            sslmode=connection_details['sslmode'],
+            sslcert=get_complete_file_path(connection_details['sslcert']),
+            sslkey=get_complete_file_path(connection_details['sslkey']),
+            sslrootcert=get_complete_file_path(
+                connection_details['sslrootcert']),
+            sslcompression=True if connection_details[
+                'sslcompression'] else False,
         )
         # create a cursor
         cur = conn.cursor()
@@ -715,7 +728,9 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
             url_params = {k: v for k, v in request.args.items()}
 
         required_connection_args = ['host', 'port', 'username', 'db',
-                                    'connect_timeout', 'passfile']
+                                    'connect_timeout', 'passfile', 'sslmode',
+                                    'sslcompression', 'sslcert', 'sslkey',
+                                    'sslrootcert', 'sslcrl']
 
         if 'oid' in url_params:
             status, params = self._fetch_properties(did, url_params['oid'])
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
index 6c1b71521..78b530771 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js
@@ -12,6 +12,7 @@ define('pgadmin.node.subscription', [
   'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
   'sources/browser/server_groups/servers/model_validation', 'pgadmin.alertifyjs', 'pgadmin.browser.collection',
 ], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, modelValidation, Alertify) {
+  var SSL_MODES = ['prefer', 'require', 'verify-ca', 'verify-full'];
 
   // Extend the browser's collection class for subscriptions collection
   if (!pgBrowser.Nodes['coll-subscription']) {
@@ -77,7 +78,7 @@ define('pgadmin.node.subscription', [
           name: undefined,
           subowner: undefined,
           pubtable: undefined,
-          connect_timeout: undefined,
+          connect_timeout: 10,
           pub:[],
           enabled:true,
           create_slot: true,
@@ -85,7 +86,18 @@ define('pgadmin.node.subscription', [
           connect:true,
           copy_data_after_refresh:false,
           sync:'off',
-          refresh_pub: undefined,
+          refresh_pub: false,
+          password: '',
+          sslmode: 'prefer',
+          sslcompression: false,
+          sslcert: '',
+          sslkey: '',
+          sslrootcert: '',
+          sslcrl: '',
+          host: '',
+          hostaddr: '',
+          port: 5432,
+          db: 'postgres',
         },
 
         // Default values!
@@ -189,7 +201,7 @@ define('pgadmin.node.subscription', [
           id: 'pub', label: gettext('Publication'), type: 'array', select2: { allowClear: true, multiple: true, width: '92%'},
           group: gettext('Connection'), mode: ['create', 'edit'], controlsClassName: 'pgadmin-controls pg-el-sm-11 pg-el-12',
           deps: ['all_table', 'host', 'port', 'username', 'db', 'password'], disabled: 'isAllConnectionDataEnter',
-          helpMessage: gettext('Click the refresh button to get the publications"'),
+          helpMessage: gettext('Click the refresh button to get the publications'),
           control: Backform.Select2Control.extend({
             defaults: _.extend(Backform.Select2Control.prototype.defaults, {
               select2: {
@@ -280,6 +292,91 @@ define('pgadmin.node.subscription', [
             },
           }),
         },
+        {
+          id: 'sslmode', label: gettext('SSL mode'), control: 'select2', group: gettext('SSL'),
+          select2: {
+            allowClear: false,
+            minimumResultsForSearch: Infinity,
+          },
+          mode: ['properties', 'edit', 'create'],
+          'options': [
+            {label: gettext('Allow'), value: 'allow'},
+            {label: gettext('Prefer'), value: 'prefer'},
+            {label: gettext('Require'), value: 'require'},
+            {label: gettext('Disable'), value: 'disable'},
+            {label: gettext('Verify-CA'), value: 'verify-ca'},
+            {label: gettext('Verify-Full'), value: 'verify-full'},
+          ],
+        },{
+          id: 'sslcert', label: gettext('Client certificate'), type: 'text',
+          group: gettext('SSL'), mode: ['edit', 'create'],
+          disabled: 'isSSL', control: Backform.FileControl,
+          dialog_type: 'select_file', supp_types: ['*'],
+          deps: ['sslmode'],
+        },{
+          id: 'sslkey', label: gettext('Client certificate key'), type: 'text',
+          group: gettext('SSL'), mode: ['edit', 'create'],
+          disabled: 'isSSL', control: Backform.FileControl,
+          dialog_type: 'select_file', supp_types: ['*'],
+          deps: ['sslmode'],
+        },{
+          id: 'sslrootcert', label: gettext('Root certificate'), type: 'text',
+          group: gettext('SSL'), mode: ['edit', 'create'],
+          disabled: 'isSSL', control: Backform.FileControl,
+          dialog_type: 'select_file', supp_types: ['*'],
+          deps: ['sslmode'],
+        },{
+          id: 'sslcrl', label: gettext('Certificate revocation list'), type: 'text',
+          group: gettext('SSL'), mode: ['edit', 'create'],
+          disabled: 'isSSL', control: Backform.FileControl,
+          dialog_type: 'select_file', supp_types: ['*'],
+          deps: ['sslmode'],
+        },{
+          id: 'sslcompression', label: gettext('SSL compression?'), type: 'switch',
+          mode: ['edit', 'create'], group: gettext('SSL'),
+          'options': {'size': 'mini'},
+          deps: ['sslmode'], disabled: 'isSSL',
+        },{
+          id: 'sslcert', label: gettext('Client certificate'), type: 'text',
+          group: gettext('SSL'), mode: ['properties'],
+          deps: ['sslmode'],
+          visible: function(model) {
+            var sslcert = model.get('sslcert');
+            return !_.isUndefined(sslcert) && !_.isNull(sslcert);
+          },
+        },{
+          id: 'sslkey', label: gettext('Client certificate key'), type: 'text',
+          group: gettext('SSL'), mode: ['properties'],
+          deps: ['sslmode'],
+          visible: function(model) {
+            var sslkey = model.get('sslkey');
+            return !_.isUndefined(sslkey) && !_.isNull(sslkey);
+          },
+        },{
+          id: 'sslrootcert', label: gettext('Root certificate'), type: 'text',
+          group: gettext('SSL'), mode: ['properties'],
+          deps: ['sslmode'],
+          visible: function(model) {
+            var sslrootcert = model.get('sslrootcert');
+            return !_.isUndefined(sslrootcert) && !_.isNull(sslrootcert);
+          },
+        },{
+          id: 'sslcrl', label: gettext('Certificate revocation list'), type: 'text',
+          group: gettext('SSL'), mode: ['properties'],
+          deps: ['sslmode'],
+          visible: function(model) {
+            var sslcrl = model.get('sslcrl');
+            return !_.isUndefined(sslcrl) && !_.isNull(sslcrl);
+          },
+        },{
+          id: 'sslcompression', label: gettext('SSL compression?'), type: 'switch',
+          mode: ['properties'], group: gettext('SSL'),
+          'options': {'size': 'mini'},
+          deps: ['sslmode'], visible: function(model) {
+            var sslmode = model.get('sslmode');
+            return _.indexOf(SSL_MODES, sslmode) != -1;
+          },
+        },
         {
           id: 'copy_data_after_refresh', label: gettext('Copy data?'),
           type: 'switch', mode: ['edit'],
@@ -298,8 +395,8 @@ define('pgadmin.node.subscription', [
           id: 'create_slot', label: gettext('Create slot?'),
           type: 'switch', mode: ['create'],
           group: gettext('With'),
-          disabled: 'isDisable',
-          readonly: 'isConnect', deps :['connect'],
+          disabled: 'isSameDB',
+          readonly: 'isConnect', deps :['connect', 'host'],
           helpMessage: gettext('Specifies whether the command should create the replication slot on the publisher.'),
 
         },
@@ -358,13 +455,21 @@ define('pgadmin.node.subscription', [
             return false;
           return true;
         },
+        isSameDB:function(m){
+          if (m.attributes['host'] == m.node_info.server.host){
+            setTimeout( function() {
+              m.set('create_slot', false);
+            }, 10);
+            return true;
+          }
+          return false;
+        },
         isAllConnectionDataEnter: function(m){
           let host = m.get('host'),
             db   = m.get('db'),
             port = m.get('port'),
-            username = m.get('username'),
-            password = m.get('password');
-          if ((!_.isUndefined(host) && host) && (!_.isUndefined(db) && db) && (!_.isUndefined(port) && port) && (!_.isUndefined(username) && username) && (!_.isUndefined(password) && password))
+            username = m.get('username');
+          if ((!_.isUndefined(host) && host) && (!_.isUndefined(db) && db) && (!_.isUndefined(port) && port) && (!_.isUndefined(username) && username))
             return false;
           return true;
         },
@@ -388,8 +493,12 @@ define('pgadmin.node.subscription', [
           }
           return false;
         },
+        isSSL: function(model) {
+          var ssl_mode = model.get('sslmode');
+          return _.indexOf(SSL_MODES, ssl_mode) == -1;
+        },
         sessChanged: function() {
-          if (_.isEqual(_.omit(this.attributes, ['refresh_pub']), _.omit(this.origSessAttrs, ['refresh_pub'])) && !this.isNew())
+          if (!this.isNew() && _.isUndefined(this.attributes['refresh_pub']))
             return false;
           return pgBrowser.DataModel.prototype.sessChanged.apply(this);
         },
@@ -400,7 +509,8 @@ define('pgadmin.node.subscription', [
         validate: function() {
           var msg;
           this.errorModel.clear();
-          var name = this.get('name');
+          var name = this.get('name'),
+            slot_name = this.get('slot_name');
 
           if (_.isUndefined(name) || _.isNull(name) ||
             String(name).replace(/^\s+|\s+$/g, '') == '') {
@@ -409,6 +519,14 @@ define('pgadmin.node.subscription', [
             return msg;
           }
 
+          if (!_.isUndefined(slot_name) && !_.isNull(slot_name)){
+            if(/^[a-zA-Z0-9_]+$/.test(slot_name) == false){
+              msg = gettext('Replication slot name may only contain lower case letters, numbers, and the underscore character.');
+              this.errorModel.set('name', msg);
+              return msg;
+            }
+          }
+
           const validateModel = new modelValidation.ModelValidation(this);
           return validateModel.validate();
         },
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql
index 08c28a1b6..31bf109f5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/create.sql
@@ -12,8 +12,8 @@
 {% endif %}
 
 CREATE SUBSCRIPTION {{ conn|qtIdent(data.name) }}
-{% if data.host or data.port or data.username or data.password  or data.db %}
-    CONNECTION '{% if data.host %}host={{data.host}}{% endif %}{% if data.port %} port={{ data.port }}{% endif %}{% if data.username %} user={{ data.username }}{% endif %}{% if data.db %} dbname={{ data.db }}{% endif %}{% if data.connect_timeout %} connect_timeout={{ data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %}password={{ data.password}}{% endif %}{% endif %}'
+{% if data.host or data.port or data.username or data.password  or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl%}
+    CONNECTION '{% if data.host %}host={{data.host}}{% endif %}{% if data.port %} port={{ data.port }}{% endif %}{% if data.username %} user={{ data.username }}{% endif %}{% if data.db %} dbname={{ data.db }}{% endif %}{% if data.connect_timeout %} connect_timeout={{ data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %}password={{ data.password}}{% endif %}{% endif %}{% if data.sslmode %} sslmode={{ data.sslmode }}{% endif %}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}'
 {% endif %}
 {% if data.pub %}
     PUBLICATION {% for pub in data.pub %}{% if loop.index != 1 %},{% endif %}{{ conn|qtIdent(pub) }}{% endfor %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
index 266525779..af958fcb2 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/properties.sql
@@ -1,18 +1,24 @@
-SELECT  sub.oid AS oid,
-        subname AS name,
-        subpublications AS pub,
-        sub.subsynccommit AS sync,
-        subpublications AS cur_pub,
-        pga.rolname AS subowner,
-        subslotname AS slot_name,
-        subenabled AS enabled,
-		SPLIT_PART(SPLIT_PART(subconninfo,' port',1), '=',2) AS host,
-		SPLIT_PART(SPLIT_PART(subconninfo,'port=',2), ' ',1) AS port,
-		SPLIT_PART(SPLIT_PART(subconninfo,'user=',2), ' ',1) AS username,
-		SPLIT_PART(SPLIT_PART(subconninfo,'dbname=',2), ' ',1) AS db,
-		SPLIT_PART(SPLIT_PART(subconninfo,'connect_timeout=',2), ' ',1) AS connect_timeout,
-		SPLIT_PART(SPLIT_PART(subconninfo,'passfile=',2), ' ',1) AS passfile
-FROM pg_subscription sub JOIN pg_authid pga ON sub.subowner= pga.oid
+SELECT  sub.oid as oid,
+        subname as name,
+        subpublications as pub,
+        sub.subsynccommit as sync,
+        subpublications as cur_pub,
+        pga.rolname as subowner,
+        subslotname as slot_name,
+        subenabled as enabled,
+		SPLIT_PART(SPLIT_PART(subconninfo,' port',1), '=',2) as host,
+		SPLIT_PART(SPLIT_PART(subconninfo,'port=',2), ' ',1) as port,
+		SPLIT_PART(SPLIT_PART(subconninfo,'user=',2), ' ',1) as username,
+		SPLIT_PART(SPLIT_PART(subconninfo,'dbname=',2), ' ',1) as db,
+		SPLIT_PART(SPLIT_PART(subconninfo,'connect_timeout=',2), ' ',1) as connect_timeout,
+		SPLIT_PART(SPLIT_PART(subconninfo,'passfile=',2), ' ',1) as passfile,
+		SPLIT_PART(SPLIT_PART(subconninfo,'sslmode=',2), ' ',1) as sslmode,
+		SPLIT_PART(SPLIT_PART(subconninfo,'sslcompression=',2), ' ',1) as sslcompression,
+		SPLIT_PART(SPLIT_PART(subconninfo,'sslcert=',2), ' ',1) as sslcert,
+		SPLIT_PART(SPLIT_PART(subconninfo,'sslkey=',2), ' ',1) as sslkey,
+		SPLIT_PART(SPLIT_PART(subconninfo,'sslrootcert=',2), ' ',1) as sslrootcert,
+		SPLIT_PART(SPLIT_PART(subconninfo,'sslcrl=',2), ' ',1) as sslcrl
+FROM pg_subscription sub join pg_roles pga on sub.subowner= pga.oid
 WHERE
 {% if subid %}
     sub.oid = {{ subid }};
diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql
index f04a00466..04c435a69 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/templates/subscriptions/sql/default/update.sql
@@ -47,9 +47,9 @@ ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
 
 {% endif %}
 {###  Alter subscription connection info ###}
-{% if data.host or data.port or data.username or data.password  or data.db or  data.connect_timeout or data.passfile %}
+{% if data.host or data.port or data.username or data.password  or data.db or data.connect_timeout or data.passfile or data.sslmode or data.sslcompression or data.sslcert or data.sslkey or data.sslrootcert or data.sslcrl %}
 ALTER SUBSCRIPTION {{ conn|qtIdent(o_data.name) }}
-    CONNECTION 'host={{ o_data.host}} port={{ o_data.port }} user={{ o_data.username }} dbname={{ o_data.db }}{% if data.connect_timeout %} connect_timeout={{ o_data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ o_data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %} password={{ data.password}}{% endif %}{% endif %}';
+    CONNECTION 'host={{ o_data.host}} port={{ o_data.port }} user={{ o_data.username }} dbname={{ o_data.db }}{% if data.connect_timeout %} connect_timeout={{ o_data.connect_timeout }}{% endif %}{% if data.passfile %} passfile={{ o_data.passfile }}{% endif %}{% if data.password %} {% if dummy %}password=xxxxxx{% else %} password={{ data.password}}{% endif %}{% endif %}{% if data.sslmode %} sslmode={{ data.sslmode }}{% endif %}{% if data.sslcompression %} sslcompression={{ data.sslcompression }}{% endif %}{% if data.sslcert %} sslcert={{ data.sslcert }}{% endif %}{% if data.sslkey %} sslkey={{ data.sslkey }}{% endif %}{% if data.sslrootcert %} sslrootcert={{ data.sslrootcert }}{% endif %}{% if data.sslcrl %} sslcrl={{ data.sslcrl }}{% endif %}';
 {% endif %}
 {###  Alter subscription name ###}
 {% if data.name and data.name != o_data.name %}
diff --git a/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js b/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js
index 2e391b5b6..33d073a6b 100644
--- a/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js
+++ b/web/pgadmin/static/js/browser/server_groups/servers/model_validation.js
@@ -40,15 +40,11 @@ export class ModelValidation {
       this.checkForEmpty('username', gettext('Username must be specified.'));
       this.checkForEmpty('port', gettext('Port must be specified.'));
       if(!_.isUndefined(pub)){
-        if (this.model.isNew())
-          this.checkForEmpty('password', gettext('Password must be specified.'));
         this.checkForEmpty('pub', gettext('Publication must be specified.'));
       }
     } else {
       this.checkForEmpty('db', gettext('Maintenance database must be specified.'));
       if(!_.isUndefined(pub)){
-        if (this.model.isNew())
-          this.checkForEmpty('password', gettext('Password must be specified.'));
         this.checkForEmpty('pub', gettext('Publication must be specified.'));
       }
       this.clearHostAddressAndDbErrors();
diff --git a/web/pgadmin/utils/versioned_template_loader.py b/web/pgadmin/utils/versioned_template_loader.py
index ca4f3146c..c4dcc1528 100644
--- a/web/pgadmin/utils/versioned_template_loader.py
+++ b/web/pgadmin/utils/versioned_template_loader.py
@@ -84,7 +84,8 @@ def get_version_mapping_directories(server_type):
             {'name': "default", 'number': 0}
         )
 
-    return ({'name': "12_plus", 'number': 120000},
+    return ({'name': "13_plus", 'number': 130000},
+            {'name': "12_plus", 'number': 120000},
             {'name': "11_plus", 'number': 110000},
             {'name': "10_plus", 'number': 100000},
             {'name': "9.6_plus", 'number': 90600},


view thread (4+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected]
  Subject: Re: [pgAdmin][RM6201]:SSL Support in subscription.
  In-Reply-To: <CAJ9T6StZuyKV=1bKc6zuegSXh94Ttn0e98vSraEp2dpqXhnFLw@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox