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

beto pushed a commit to branch improve_perms
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 25200430bfe2195761869f480a5f92c6cfdff4b0
Author: Beto Dealmeida <[email protected]>
AuthorDate: Thu May 11 10:45:02 2023 -0700

    feat: split database information
---
 .../src/features/databases/DatabaseModal/index.tsx |  1 +
 superset-frontend/src/views/CRUD/hooks.ts          |  7 +-
 superset/constants.py                              |  1 +
 superset/databases/api.py                          | 24 +++++--
 superset/databases/schemas.py                      | 83 ++++++++++++++++++++++
 5 files changed, 111 insertions(+), 5 deletions(-)

diff --git a/superset-frontend/src/features/databases/DatabaseModal/index.tsx 
b/superset-frontend/src/features/databases/DatabaseModal/index.tsx
index 4a80612369..059d106fdb 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/index.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/index.tsx
@@ -542,6 +542,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> 
= ({
     'database',
     t('database'),
     addDangerToast,
+    'connection',
   );
 
   const [tabKey, setTabKey] = useState<string>(DEFAULT_TAB_KEY);
diff --git a/superset-frontend/src/views/CRUD/hooks.ts 
b/superset-frontend/src/views/CRUD/hooks.ts
index 91af5817b4..65aae1d928 100644
--- a/superset-frontend/src/views/CRUD/hooks.ts
+++ b/superset-frontend/src/views/CRUD/hooks.ts
@@ -224,6 +224,7 @@ export function useSingleViewResource<D extends object = 
any>(
   resourceName: string,
   resourceLabel: string, // resourceLabel for translations
   handleErrorMsg: (errorMsg: string) => void,
+  path_suffix = '',
 ) {
   const [state, setState] = useState<SingleViewResourceState<D>>({
     loading: false,
@@ -242,8 +243,12 @@ export function useSingleViewResource<D extends object = 
any>(
         loading: true,
       });
 
+      const endpoint =
+        path_suffix !== ''
+          ? `/api/v1/${resourceName}/${resourceID}/{path_suffix}`
+          : `/api/v1/${resourceName}/${resourceID}`;
       return SupersetClient.get({
-        endpoint: `/api/v1/${resourceName}/${resourceID}`,
+        endpoint,
       })
         .then(
           ({ json = {} }) => {
diff --git a/superset/constants.py b/superset/constants.py
index 958592b62f..e4bad9f8aa 100644
--- a/superset/constants.py
+++ b/superset/constants.py
@@ -154,6 +154,7 @@ MODEL_API_RW_METHOD_PERMISSION_MAP = {
     "add_objects": "write",
     "delete_object": "write",
     "copy_dash": "write",
+    "get_connection": "write",
 }
 
 EXTRA_FORM_DATA_APPEND_KEYS = {
diff --git a/superset/databases/api.py b/superset/databases/api.py
index 95b5089652..0540bf37a8 100644
--- a/superset/databases/api.py
+++ b/superset/databases/api.py
@@ -61,6 +61,7 @@ from superset.databases.filters import DatabaseFilter, 
DatabaseUploadEnabledFilt
 from superset.databases.schemas import (
     database_schemas_query_schema,
     database_tables_query_schema,
+    DatabaseConnectionSchema,
     DatabaseFunctionNamesResponse,
     DatabasePostSchema,
     DatabasePutSchema,
@@ -122,6 +123,7 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
         "validate_sql",
         "delete_ssh_tunnel",
         "schemas_access_for_file_upload",
+        "get_connection",
     }
     resource_name = "database"
     class_permission_name = "Database"
@@ -144,12 +146,8 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
         "driver",
         "force_ctas_schema",
         "impersonate_user",
-        "masked_encrypted_extra",
         "extra",
-        "parameters",
-        "parameters_schema",
         "server_cert",
-        "sqlalchemy_uri",
         "is_managed_externally",
         "engine_information",
     ]
@@ -237,6 +235,24 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
         ValidateSQLResponse,
     )
 
+    @expose("/<int:pk>/connection", methods=("GET",))
+    @protect()
+    @safe
+    def get_connection(self, pk: int) -> Response:
+        """Get database connection info."""
+        database = DatabaseDAO.find_by_id(pk)
+        database_connection_schema = DatabaseConnectionSchema()
+        response = {
+            "id": pk,
+            "result": database_connection_schema.dump(database, many=False),
+        }
+        try:
+            if ssh_tunnel := DatabaseDAO.get_ssh_tunnel(pk):
+                response["result"]["ssh_tunnel"] = ssh_tunnel.data
+            return self.response(200, **response)
+        except SupersetException as ex:
+            return self.response(ex.status, message=ex.message)
+
     @expose("/<int:pk>", methods=("GET",))
     @protect()
     @safe
diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py
index e1e38667c0..00e8c3ca53 100644
--- a/superset/databases/schemas.py
+++ b/superset/databases/schemas.py
@@ -880,3 +880,86 @@ class DatabaseSchemaAccessForFileUploadResponse(Schema):
             "information"
         },
     )
+
+
+class DatabaseConnectionSchema(Schema):
+    """
+    Schema with database connection information.
+
+    This is only for admins (who have ``can_create`` on ``Database``).
+    """
+
+    allow_ctas = fields.Boolean(metadata={"description": 
allow_ctas_description})
+    allow_cvas = fields.Boolean(metadata={"description": 
allow_cvas_description})
+    allow_dml = fields.Boolean(metadata={"description": allow_dml_description})
+    allow_file_upload = fields.Boolean(
+        metadata={"description": allow_file_upload_description}
+    )
+    allow_run_async = fields.Boolean(
+        metadata={"description": allow_run_async_description}
+    )
+    backend = fields.String(
+        allow_none=True, metadata={"description": "SQLAlchemy engine to use"}
+    )
+    cache_timeout = fields.Integer(
+        metadata={"description": cache_timeout_description}, allow_none=True
+    )
+    configuration_method = fields.String(
+        metadata={"description": configuration_method_description},
+    )
+    database_name = fields.String(
+        metadata={"description": database_name_description},
+        allow_none=True,
+        validate=Length(1, 250),
+    )
+    driver = fields.String(
+        allow_none=True, metadata={"description": "SQLAlchemy driver to use"}
+    )
+    engine_information = fields.Dict(keys=fields.String(), values=fields.Raw())
+    expose_in_sqllab = fields.Boolean(
+        metadata={"description": expose_in_sqllab_description}
+    )
+    extra = fields.String(
+        metadata={"description": extra_description}, validate=extra_validator
+    )
+    force_ctas_schema = fields.String(
+        metadata={"description": force_ctas_schema_description},
+        allow_none=True,
+        validate=Length(0, 250),
+    )
+    id = fields.Integer(metadata={"description": "Database ID (for updates)"})
+    impersonate_user = fields.Boolean(
+        metadata={"description": impersonate_user_description}
+    )
+    is_managed_externally = fields.Boolean(allow_none=True, dump_default=False)
+    server_cert = fields.String(
+        metadata={"description": server_cert_description},
+        allow_none=True,
+        validate=server_cert_validator,
+    )
+    uuid = fields.String(required=False)
+    ssh_tunnel = fields.Nested(DatabaseSSHTunnel, allow_none=True)
+    masked_encrypted_extra = fields.String(
+        metadata={"description": encrypted_extra_description},
+        validate=encrypted_extra_validator,
+        allow_none=True,
+    )
+    parameters = fields.Dict(
+        keys=fields.String(),
+        values=fields.Raw(),
+        metadata={"description": "DB-specific parameters for configuration"},
+    )
+    parameters_schema = fields.Dict(
+        keys=fields.String(),
+        values=fields.Raw(),
+        metadata={
+            "description": (
+                "JSONSchema for configuring the database by "
+                "parameters instead of SQLAlchemy URI"
+            ),
+        },
+    )
+    sqlalchemy_uri = fields.String(
+        metadata={"description": sqlalchemy_uri_description},
+        validate=[Length(1, 1024), sqlalchemy_uri_validator],
+    )

Reply via email to