You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jo...@apache.org on 2020/09/10 23:23:57 UTC

[incubator-superset] branch master updated: fix: Making the database read-only (#10823)

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

johnbodley 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 a3e2e65  fix: Making the database read-only (#10823)
a3e2e65 is described below

commit a3e2e65121fadc8ca507c490eb5a3b26d8153041
Author: John Bodley <45...@users.noreply.github.com>
AuthorDate: Thu Sep 10 16:23:24 2020 -0700

    fix: Making the database read-only (#10823)
    
    Co-authored-by: John Bodley <jo...@airbnb.com>
---
 superset-frontend/src/components/TableSelector.jsx   |  3 +++
 .../src/datasource/DatasourceEditor.jsx              | 20 +++++++++-----------
 superset/connectors/base/views.py                    | 15 +++++++++++++++
 superset/connectors/druid/views.py                   | 17 ++++++++++++++---
 superset/connectors/sqla/views.py                    |  6 +++---
 5 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/superset-frontend/src/components/TableSelector.jsx b/superset-frontend/src/components/TableSelector.jsx
index 7c27c43..395c6be 100644
--- a/superset-frontend/src/components/TableSelector.jsx
+++ b/superset-frontend/src/components/TableSelector.jsx
@@ -53,6 +53,7 @@ const propTypes = {
   onChange: PropTypes.func,
   clearable: PropTypes.bool,
   handleError: PropTypes.func.isRequired,
+  isDatabaseSelectEnabled: PropTypes.bool,
 };
 
 const defaultProps = {
@@ -67,6 +68,7 @@ const defaultProps = {
   sqlLabMode: true,
   formMode: false,
   clearable: true,
+  isDatabaseSelectEnabled: true,
 };
 
 export default class TableSelector extends React.PureComponent {
@@ -313,6 +315,7 @@ export default class TableSelector extends React.PureComponent {
         optionRenderer={this.renderDatabaseOption}
         mutator={this.dbMutator}
         placeholder={t('Select a database')}
+        isDisabled={!this.props.isDatabaseSelectEnabled}
         autoSelect
       />,
     );
diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx b/superset-frontend/src/datasource/DatasourceEditor.jsx
index fca3661..608232a 100644
--- a/superset-frontend/src/datasource/DatasourceEditor.jsx
+++ b/superset-frontend/src/datasource/DatasourceEditor.jsx
@@ -457,15 +457,13 @@ export class DatasourceEditor extends React.PureComponent {
                 onSchemaChange={schema =>
                   this.onDatasourcePropChange('schema', schema)
                 }
-                onDbChange={database =>
-                  this.onDatasourcePropChange('database', database)
-                }
                 onTableChange={table =>
                   this.onDatasourcePropChange('datasource_name', table)
                 }
                 sqlLabMode={false}
                 clearable={false}
                 handleError={this.props.addDangerToast}
+                isDatabaseSelectEnabled={false}
               />
             }
             description={t(
@@ -748,6 +746,14 @@ export class DatasourceEditor extends React.PureComponent {
     return (
       <DatasourceContainer>
         {this.renderErrors()}
+        <div className="m-t-10">
+          <Alert bsStyle="warning">
+            <strong>{t('Be careful.')} </strong>
+            {t(
+              'Changing these settings will affect all charts using this dataset, including charts owned by other people.',
+            )}
+          </Alert>
+        </div>
         <Tabs
           id="table-tabs"
           onSelect={this.handleTabSelect}
@@ -830,14 +836,6 @@ export class DatasourceEditor extends React.PureComponent {
           <Tab eventKey={4} title={t('Settings')}>
             {activeTabKey === 4 && (
               <div>
-                <div className="m-t-10">
-                  <Alert bsStyle="warning">
-                    <strong>{t('Be careful.')} </strong>
-                    {t(
-                      'Changing these settings will affect all charts using this dataset, including charts owned by other people.',
-                    )}
-                  </Alert>
-                </div>
                 <Col md={6}>
                   <FormContainer>{this.renderSettingsFieldset()}</FormContainer>
                 </Col>
diff --git a/superset/connectors/base/views.py b/superset/connectors/base/views.py
index 150c05c..ae5013e 100644
--- a/superset/connectors/base/views.py
+++ b/superset/connectors/base/views.py
@@ -14,13 +14,28 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+from typing import Any
+
 from flask import Markup
+from flask_appbuilder.fieldwidgets import BS3TextFieldWidget
 
 from superset.connectors.base.models import BaseDatasource
 from superset.exceptions import SupersetException
 from superset.views.base import SupersetModelView
 
 
+class BS3TextFieldROWidget(  # pylint: disable=too-few-public-methods
+    BS3TextFieldWidget
+):
+    """
+    Custom read only text field widget.
+    """
+
+    def __call__(self, field: Any, **kwargs: Any) -> Markup:
+        kwargs["readonly"] = "true"
+        return super().__call__(field, **kwargs)
+
+
 class DatasourceModelView(SupersetModelView):
     def pre_delete(self, item: BaseDatasource) -> None:
         if item.slices:
diff --git a/superset/connectors/druid/views.py b/superset/connectors/druid/views.py
index 4c2fbf9..112bcd1 100644
--- a/superset/connectors/druid/views.py
+++ b/superset/connectors/druid/views.py
@@ -25,10 +25,11 @@ from flask_appbuilder.fieldwidgets import Select2Widget
 from flask_appbuilder.models.sqla.interface import SQLAInterface
 from flask_appbuilder.security.decorators import has_access
 from flask_babel import lazy_gettext as _
+from wtforms import StringField
 from wtforms.ext.sqlalchemy.fields import QuerySelectField
 
 from superset import db, security_manager
-from superset.connectors.base.views import DatasourceModelView
+from superset.connectors.base.views import BS3TextFieldROWidget, DatasourceModelView
 from superset.connectors.connector_registry import ConnectorRegistry
 from superset.connectors.druid import models
 from superset.constants import RouteMethod
@@ -98,7 +99,7 @@ class DruidColumnInlineView(CompactCRUDMixin, SupersetModelView):
     add_form_extra_fields = {
         "datasource": QuerySelectField(
             "Datasource",
-            query_factory=lambda: db.session().query(models.DruidDatasource),
+            query_factory=lambda: db.session.query(models.DruidDatasource),
             allow_blank=True,
             widget=Select2Widget(extra_classes="readonly"),
         )
@@ -179,7 +180,7 @@ class DruidMetricInlineView(CompactCRUDMixin, SupersetModelView):
     add_form_extra_fields = {
         "datasource": QuerySelectField(
             "Datasource",
-            query_factory=lambda: db.session().query(models.DruidDatasource),
+            query_factory=lambda: db.session.query(models.DruidDatasource),
             allow_blank=True,
             widget=Select2Widget(extra_classes="readonly"),
         )
@@ -333,6 +334,16 @@ class DruidDatasourceModelView(DatasourceModelView, DeleteMixin, YamlExportMixin
         "changed_by_": _("Changed By"),
         "modified": _("Modified"),
     }
+    edit_form_extra_fields = {
+        "cluster": QuerySelectField(
+            "Cluster",
+            query_factory=lambda: db.session.query(models.DruidCluster),
+            widget=Select2Widget(extra_classes="readonly"),
+        ),
+        "datasource_name": StringField(
+            "Datasource Name", widget=BS3TextFieldROWidget()
+        ),
+    }
 
     def pre_add(self, item: "DruidDatasourceModelView") -> None:
         with db.session.no_autoflush:
diff --git a/superset/connectors/sqla/views.py b/superset/connectors/sqla/views.py
index 23f4c1c..a1e28e4 100644
--- a/superset/connectors/sqla/views.py
+++ b/superset/connectors/sqla/views.py
@@ -160,7 +160,7 @@ class TableColumnInlineView(  # pylint: disable=too-many-ancestors
     add_form_extra_fields = {
         "table": QuerySelectField(
             "Table",
-            query_factory=lambda: db.session().query(models.SqlaTable),
+            query_factory=lambda: db.session.query(models.SqlaTable),
             allow_blank=True,
             widget=Select2Widget(extra_classes="readonly"),
         )
@@ -232,7 +232,7 @@ class SqlMetricInlineView(  # pylint: disable=too-many-ancestors
     add_form_extra_fields = {
         "table": QuerySelectField(
             "Table",
-            query_factory=lambda: db.session().query(models.SqlaTable),
+            query_factory=lambda: db.session.query(models.SqlaTable),
             allow_blank=True,
             widget=Select2Widget(extra_classes="readonly"),
         )
@@ -393,7 +393,7 @@ class TableModelView(  # pylint: disable=too-many-ancestors
     edit_form_extra_fields = {
         "database": QuerySelectField(
             "Database",
-            query_factory=lambda: db.session().query(models.Database),
+            query_factory=lambda: db.session.query(models.Database),
             widget=Select2Widget(extra_classes="readonly"),
         )
     }