This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 4c5e6ca  Add HTTP Basic Auth for Druid (Issue #4776) (#6795)
4c5e6ca is described below

commit 4c5e6ca2083245425d7ad0d29935a0e3f466e81c
Author: Don Bowman <[email protected]>
AuthorDate: Mon Mar 25 19:20:13 2019 -0400

    Add HTTP Basic Auth for Druid (Issue #4776) (#6795)
    
    * Add HTTP Basic Auth for Druid (Issue #4776)
    
    This should resolve [Issue 
#4776](https://github.com/apache/incubator-superset/issues/4776)
    
    Add HTTP Basic Auth to the Druid Broker.
    
    Signed-off-by: Don Bowman <[email protected]>
    
    * Encrypt broker password in database
    
    Signed-off-by: Don Bowman <[email protected]>
    
    * Merge from master, new migration needed
    
    Signed-off-by: Don Bowman <[email protected]>
    
    * Do not expose hashed druid basic auth password
    
    * docs: add description_columns for druid basic auth
---
 superset/connectors/druid/models.py                | 13 ++++--
 superset/connectors/druid/views.py                 | 15 ++++++-
 superset/migrations/versions/45e7da7cfeba_.py      | 38 ++++++++++++++++++
 .../versions/e553e78e90c5_add_druid_auth_py_py.py  | 46 ++++++++++++++++++++++
 4 files changed, 108 insertions(+), 4 deletions(-)

diff --git a/superset/connectors/druid/models.py 
b/superset/connectors/druid/models.py
index 144d400..8440a25 100644
--- a/superset/connectors/druid/models.py
+++ b/superset/connectors/druid/models.py
@@ -45,6 +45,7 @@ from sqlalchemy import (
     Boolean, Column, DateTime, ForeignKey, Integer, String, Table, Text, 
UniqueConstraint,
 )
 from sqlalchemy.orm import backref, relationship
+from sqlalchemy_utils import EncryptedType
 
 from superset import conf, db, security_manager
 from superset.connectors.base.models import BaseColumn, BaseDatasource, 
BaseMetric
@@ -102,9 +103,11 @@ class DruidCluster(Model, AuditMixinNullable, ImportMixin):
     broker_endpoint = Column(String(255), default='druid/v2')
     metadata_last_refreshed = Column(DateTime)
     cache_timeout = Column(Integer)
+    broker_user = Column(String(255))
+    broker_pass = Column(EncryptedType(String(255), conf.get('SECRET_KEY')))
 
     export_fields = ('cluster_name', 'broker_host', 'broker_port',
-                     'broker_endpoint', 'cache_timeout')
+                     'broker_endpoint', 'cache_timeout', 'broker_user')
     update_from_object_fields = export_fields
     export_children = ['datasources']
 
@@ -139,16 +142,20 @@ class DruidCluster(Model, AuditMixinNullable, 
ImportMixin):
         cli = PyDruid(
             self.get_base_url(self.broker_host, self.broker_port),
             self.broker_endpoint)
+        if self.broker_user and self.broker_pass:
+            cli.set_basic_auth_credentials(self.broker_user, self.broker_pass)
         return cli
 
     def get_datasources(self):
         endpoint = self.get_base_broker_url() + '/datasources'
-        return json.loads(requests.get(endpoint).text)
+        auth = requests.auth.HTTPBasicAuth(self.broker_user, self.broker_pass)
+        return json.loads(requests.get(endpoint, auth=auth).text)
 
     def get_druid_version(self):
         endpoint = self.get_base_url(
             self.broker_host, self.broker_port) + '/status'
-        return json.loads(requests.get(endpoint).text)['version']
+        auth = requests.auth.HTTPBasicAuth(self.broker_user, self.broker_pass)
+        return json.loads(requests.get(endpoint, auth=auth).text)['version']
 
     @property
     @utils.memoized
diff --git a/superset/connectors/druid/views.py 
b/superset/connectors/druid/views.py
index 0981dc3..4b05d70 100644
--- a/superset/connectors/druid/views.py
+++ b/superset/connectors/druid/views.py
@@ -167,7 +167,8 @@ class DruidClusterModelView(SupersetModelView, DeleteMixin, 
YamlExportMixin):  #
 
     add_columns = [
         'verbose_name', 'broker_host', 'broker_port',
-        'broker_endpoint', 'cache_timeout', 'cluster_name',
+        'broker_user', 'broker_pass', 'broker_endpoint',
+        'cache_timeout', 'cluster_name',
     ]
     edit_columns = add_columns
     list_columns = ['cluster_name', 'metadata_last_refreshed']
@@ -176,6 +177,8 @@ class DruidClusterModelView(SupersetModelView, DeleteMixin, 
YamlExportMixin):  #
         'cluster_name': _('Cluster'),
         'broker_host': _('Broker Host'),
         'broker_port': _('Broker Port'),
+        'broker_user': _('Broker Username'),
+        'broker_pass': _('Broker Password'),
         'broker_endpoint': _('Broker Endpoint'),
         'verbose_name': _('Verbose Name'),
         'cache_timeout': _('Cache Timeout'),
@@ -186,6 +189,16 @@ class DruidClusterModelView(SupersetModelView, 
DeleteMixin, YamlExportMixin):  #
             'Duration (in seconds) of the caching timeout for this cluster. '
             'A timeout of 0 indicates that the cache never expires. '
             'Note this defaults to the global timeout if undefined.'),
+        'broker_user': _(
+            'Druid supports basic authentication. See '
+            '[auth](http://druid.io/docs/latest/design/auth.html) and '
+            'druid-basic-security extension',
+        ),
+        'broker_pass': _(
+            'Druid supports basic authentication. See '
+            '[auth](http://druid.io/docs/latest/design/auth.html) and '
+            'druid-basic-security extension',
+        ),
     }
 
     def pre_add(self, cluster):
diff --git a/superset/migrations/versions/45e7da7cfeba_.py 
b/superset/migrations/versions/45e7da7cfeba_.py
new file mode 100644
index 0000000..ec475a5
--- /dev/null
+++ b/superset/migrations/versions/45e7da7cfeba_.py
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""empty message
+
+Revision ID: 45e7da7cfeba
+Revises: ('e553e78e90c5', 'c82ee8a39623')
+Create Date: 2019-02-16 17:44:44.493427
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '45e7da7cfeba'
+down_revision = ('e553e78e90c5', 'c82ee8a39623')
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    pass
+
+
+def downgrade():
+    pass
diff --git a/superset/migrations/versions/e553e78e90c5_add_druid_auth_py_py.py 
b/superset/migrations/versions/e553e78e90c5_add_druid_auth_py_py.py
new file mode 100644
index 0000000..bb17479
--- /dev/null
+++ b/superset/migrations/versions/e553e78e90c5_add_druid_auth_py_py.py
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""add_druid_auth_py.py
+
+Revision ID: e553e78e90c5
+Revises: 18dc26817ad2
+Create Date: 2019-02-01 16:07:04.268023
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'e553e78e90c5'
+down_revision = '18dc26817ad2'
+
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy_utils  import EncryptedType
+
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('clusters', sa.Column('broker_pass', EncryptedType(), 
nullable=True))
+    op.add_column('clusters', sa.Column('broker_user', sa.String(length=255), 
nullable=True))
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('clusters', 'broker_user')
+    op.drop_column('clusters', 'broker_pass')
+    # ### end Alembic commands ###

Reply via email to