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

amitmiran pushed a commit to branch feat/on_import_set_self_as_owner
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 919b7b6006463679dfdf500ed57afce5a4a74c90
Author: amitmiran137 <[email protected]>
AuthorDate: Mon Jun 21 19:30:57 2021 +0300

    feat(import): requester as owner option
---
 .../src/components/ImportModal/index.tsx           | 24 ++++++++++++++
 superset-frontend/src/views/CRUD/hooks.ts          |  5 +++
 superset/charts/commands/importers/v1/__init__.py  | 12 +++++--
 superset/charts/commands/importers/v1/utils.py     |  7 +++-
 superset/commands/importers/v1/__init__.py         | 13 ++++++--
 superset/commands/importers/v1/examples.py         |  8 ++++-
 superset/config.py                                 |  2 +-
 superset/dashboards/api.py                         |  8 +++--
 .../dashboards/commands/importers/v1/__init__.py   | 37 ++++++++++++++++++----
 superset/dashboards/commands/importers/v1/utils.py |  8 ++++-
 .../databases/commands/importers/v1/__init__.py    | 19 +++++++++--
 superset/databases/commands/importers/v1/utils.py  |  7 +++-
 .../datasets/commands/importers/v1/__init__.py     | 19 +++++++++--
 superset/datasets/commands/importers/v1/utils.py   |  3 ++
 .../commands/importers/v1/__init__.py              | 12 +++++--
 15 files changed, 157 insertions(+), 27 deletions(-)

diff --git a/superset-frontend/src/components/ImportModal/index.tsx 
b/superset-frontend/src/components/ImportModal/index.tsx
index 193d3c5..e157544 100644
--- a/superset-frontend/src/components/ImportModal/index.tsx
+++ b/superset-frontend/src/components/ImportModal/index.tsx
@@ -26,6 +26,7 @@ import Modal from 'src/components/Modal';
 import { Upload } from 'src/common/components';
 import { useImportResource } from 'src/views/CRUD/hooks';
 import { ImportResourceName } from 'src/views/CRUD/types';
+import Checkbox from '../Checkbox';
 
 export const StyledIcon = styled(Icon)`
   margin: auto ${({ theme }) => theme.gridUnit * 2}px auto 0;
@@ -135,6 +136,10 @@ const ImportModelsModal: 
FunctionComponent<ImportModelsModalProps> = ({
     false,
   );
   const [confirmedOverwrite, setConfirmedOverwrite] = useState<boolean>(false);
+  const [
+    confirmedRequesterAsOwner,
+    setConfirmedRequesterAsOwner,
+  ] = useState<boolean>(false);
   const [fileList, setFileList] = useState<UploadFile[]>([]);
   const [importingModel, setImportingModel] = useState<boolean>(false);
 
@@ -144,6 +149,7 @@ const ImportModelsModal: 
FunctionComponent<ImportModelsModalProps> = ({
     setPasswords({});
     setNeedsOverwriteConfirm(false);
     setConfirmedOverwrite(false);
+    setConfirmedRequesterAsOwner(false);
     setImportingModel(false);
   };
 
@@ -188,6 +194,7 @@ const ImportModelsModal: 
FunctionComponent<ImportModelsModalProps> = ({
       fileList[0].originFileObj,
       passwords,
       confirmedOverwrite,
+      confirmedRequesterAsOwner,
     ).then(result => {
       if (result) {
         addSuccessToast(t('The import was successful'));
@@ -269,6 +276,22 @@ const ImportModelsModal: 
FunctionComponent<ImportModelsModalProps> = ({
     );
   };
 
+  const renderRequesterAsOwner = () => (
+    <>
+      <StyledInputContainer>
+        <div className="confirm-requester-as-owner">
+          {confirmOverwriteMessage}
+        </div>
+        <div className="control-label">{t('Set My User as owner')}</div>
+        <Checkbox
+          data-test="requester-as-owner-modal-input"
+          onChange={(val?: boolean) => setConfirmedRequesterAsOwner(val)}
+          checked={confirmedRequesterAsOwner}
+        />
+      </StyledInputContainer>
+    </>
+  );
+
   // Show/hide
   if (isHidden && show) {
     setIsHidden(false);
@@ -308,6 +331,7 @@ const ImportModelsModal: 
FunctionComponent<ImportModelsModalProps> = ({
       </StyledInputContainer>
       {renderPasswordFields()}
       {renderOverwriteConfirmation()}
+      {renderRequesterAsOwner()}
     </Modal>
   );
 };
diff --git a/superset-frontend/src/views/CRUD/hooks.ts 
b/superset-frontend/src/views/CRUD/hooks.ts
index 785d608..ecd99b6 100644
--- a/superset-frontend/src/views/CRUD/hooks.ts
+++ b/superset-frontend/src/views/CRUD/hooks.ts
@@ -394,6 +394,7 @@ export function useImportResource(
       bundle: File,
       databasePasswords: Record<string, string> = {},
       overwrite = false,
+      requesterAsOwner = false,
     ) => {
       // Set loading state
       updateState({
@@ -416,6 +417,10 @@ export function useImportResource(
         formData.append('overwrite', 'true');
       }
 
+      if (requesterAsOwner) {
+        formData.append('requesterAsOwner', 'true');
+      }
+
       return SupersetClient.post({
         endpoint: `/api/v1/${resourceName}/import/`,
         body: formData,
diff --git a/superset/charts/commands/importers/v1/__init__.py 
b/superset/charts/commands/importers/v1/__init__.py
index 0e2b5b3..cc12d68 100644
--- a/superset/charts/commands/importers/v1/__init__.py
+++ b/superset/charts/commands/importers/v1/__init__.py
@@ -48,7 +48,10 @@ class ImportChartsCommand(ImportModelsCommand):
 
     @staticmethod
     def _import(
-        session: Session, configs: Dict[str, Any], overwrite: bool = False
+        session: Session,
+        configs: Dict[str, Any],
+        overwrite: bool = False,
+        requester_as_owner: bool = False,
     ) -> None:
         # discover datasets associated with charts
         dataset_uuids: Set[str] = set()
@@ -95,4 +98,9 @@ class ImportChartsCommand(ImportModelsCommand):
                     }
                 )
                 config["params"].update({"datasource": dataset.uid})
-                import_chart(session, config, overwrite=overwrite)
+                import_chart(
+                    session,
+                    config,
+                    overwrite=overwrite,
+                    requester_as_owner=requester_as_owner,
+                )
diff --git a/superset/charts/commands/importers/v1/utils.py 
b/superset/charts/commands/importers/v1/utils.py
index b3d4237..671bd31 100644
--- a/superset/charts/commands/importers/v1/utils.py
+++ b/superset/charts/commands/importers/v1/utils.py
@@ -24,7 +24,10 @@ from superset.models.slice import Slice
 
 
 def import_chart(
-    session: Session, config: Dict[str, Any], overwrite: bool = False
+    session: Session,
+    config: Dict[str, Any],
+    overwrite: bool = False,
+    requester_as_owner: bool = False,
 ) -> Slice:
     existing = session.query(Slice).filter_by(uuid=config["uuid"]).first()
     if existing:
@@ -36,6 +39,8 @@ def import_chart(
     config["params"] = json.dumps(config["params"])
 
     chart = Slice.import_from_dict(session, config, recursive=False)
+    if requester_as_owner:
+        chart.reset_ownership()
     if chart.id is None:
         session.flush()
 
diff --git a/superset/commands/importers/v1/__init__.py 
b/superset/commands/importers/v1/__init__.py
index b9ea244..b28f28e 100644
--- a/superset/commands/importers/v1/__init__.py
+++ b/superset/commands/importers/v1/__init__.py
@@ -29,7 +29,7 @@ from superset.commands.importers.v1.utils import (
     METADATA_FILE_NAME,
 )
 from superset.dao.base import BaseDAO
-from superset.models.core import Database
+from superset.models.core import Database, logger
 
 
 class ImportModelsCommand(BaseCommand):
@@ -47,11 +47,16 @@ class ImportModelsCommand(BaseCommand):
         self.contents = contents
         self.passwords: Dict[str, str] = kwargs.get("passwords") or {}
         self.overwrite: bool = kwargs.get("overwrite", False)
+        logger.info(f"requesterAsOwner: {kwargs} {args}")
+        self.requester_as_owner: bool = kwargs.get("requester_as_owner", False)
         self._configs: Dict[str, Any] = {}
 
     @staticmethod
     def _import(
-        session: Session, configs: Dict[str, Any], overwrite: bool = False
+        session: Session,
+        configs: Dict[str, Any],
+        overwrite: bool = False,
+        requester_as_owner: bool = False,
     ) -> None:
         raise NotImplementedError("Subclasses MUST implement _import")
 
@@ -64,7 +69,9 @@ class ImportModelsCommand(BaseCommand):
 
         # rollback to prevent partial imports
         try:
-            self._import(db.session, self._configs, self.overwrite)
+            self._import(
+                db.session, self._configs, self.overwrite, 
self.requester_as_owner
+            )
             db.session.commit()
         except Exception:
             db.session.rollback()
diff --git a/superset/commands/importers/v1/examples.py 
b/superset/commands/importers/v1/examples.py
index 2b56ee0..c6092ef 100644
--- a/superset/commands/importers/v1/examples.py
+++ b/superset/commands/importers/v1/examples.py
@@ -76,6 +76,7 @@ class ImportExamplesCommand(ImportModelsCommand):
         session: Session,
         configs: Dict[str, Any],
         overwrite: bool = False,
+        requester_as_owner: bool = False,
         force_data: bool = False,
     ) -> None:
         # import databases
@@ -124,7 +125,12 @@ class ImportExamplesCommand(ImportModelsCommand):
         for file_name, config in configs.items():
             if file_name.startswith("dashboards/"):
                 config = update_id_refs(config, chart_ids)
-                dashboard = import_dashboard(session, config, 
overwrite=overwrite)
+                dashboard = import_dashboard(
+                    session,
+                    config,
+                    overwrite=overwrite,
+                    requester_as_owner=requester_as_owner,
+                )
                 for uuid in find_chart_uuids(config["position"]):
                     chart_id = chart_ids[uuid]
                     if (dashboard.id, chart_id) not in existing_relationships:
diff --git a/superset/config.py b/superset/config.py
index 883f0bc..e262779 100644
--- a/superset/config.py
+++ b/superset/config.py
@@ -361,7 +361,7 @@ DEFAULT_FEATURE_FLAGS: Dict[str, bool] = {
     "DASHBOARD_CROSS_FILTERS": False,
     "DASHBOARD_NATIVE_FILTERS_SET": False,
     "GLOBAL_ASYNC_QUERIES": False,
-    "VERSIONED_EXPORT": False,
+    "VERSIONED_EXPORT": True,
     # Note that: RowLevelSecurityFilter is only given by default to the Admin 
role
     # and the Admin Role does have the all_datasources security permission.
     # But, if users create a specific role with access to 
RowLevelSecurityFilter MVC
diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py
index a581a2d..c1f9fc6 100644
--- a/superset/dashboards/api.py
+++ b/superset/dashboards/api.py
@@ -955,9 +955,13 @@ class DashboardRestApi(BaseSupersetModelRestApi):
             else None
         )
         overwrite = request.form.get("overwrite") == "true"
-
+        requester_as_owner = request.form.get("requesterAsOwner")
+        logger.info(f"import formdata {request.form}")
         command = ImportDashboardsCommand(
-            contents, passwords=passwords, overwrite=overwrite
+            contents,
+            passwords=passwords,
+            overwrite=overwrite,
+            requester_as_owner=requester_as_owner,
         )
         command.run()
         return self.response(200, message="OK")
diff --git a/superset/dashboards/commands/importers/v1/__init__.py 
b/superset/dashboards/commands/importers/v1/__init__.py
index c698e89..7528ecc 100644
--- a/superset/dashboards/commands/importers/v1/__init__.py
+++ b/superset/dashboards/commands/importers/v1/__init__.py
@@ -14,7 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-
 from typing import Any, Dict, List, Set, Tuple
 
 from marshmallow import Schema
@@ -30,7 +29,7 @@ from superset.dashboards.commands.importers.v1.utils import (
     import_dashboard,
     update_id_refs,
 )
-from superset.dashboards.dao import DashboardDAO
+from superset.dashboards.dao import DashboardDAO, logger
 from superset.dashboards.schemas import ImportV1DashboardSchema
 from superset.databases.commands.importers.v1.utils import import_database
 from superset.databases.schemas import ImportV1DatabaseSchema
@@ -58,7 +57,10 @@ class ImportDashboardsCommand(ImportModelsCommand):
     # pylint: disable=too-many-branches, too-many-locals
     @staticmethod
     def _import(
-        session: Session, configs: Dict[str, Any], overwrite: bool = False
+        session: Session,
+        configs: Dict[str, Any],
+        overwrite: bool = False,
+        requester_as_owner: bool = False,
     ) -> None:
         # discover charts associated with dashboards
         chart_uuids: Set[str] = set()
@@ -82,7 +84,12 @@ class ImportDashboardsCommand(ImportModelsCommand):
         database_ids: Dict[str, int] = {}
         for file_name, config in configs.items():
             if file_name.startswith("databases/") and config["uuid"] in 
database_uuids:
-                database = import_database(session, config, overwrite=False)
+                database = import_database(
+                    session,
+                    config,
+                    overwrite=False,
+                    requester_as_owner=requester_as_owner,
+                )
                 database_ids[str(database.uuid)] = database.id
 
         # import datasets with the correct parent ref
@@ -93,7 +100,12 @@ class ImportDashboardsCommand(ImportModelsCommand):
                 and config["database_uuid"] in database_ids
             ):
                 config["database_id"] = database_ids[config["database_uuid"]]
-                dataset = import_dataset(session, config, overwrite=False)
+                dataset = import_dataset(
+                    session,
+                    config,
+                    overwrite=False,
+                    requester_as_owner=requester_as_owner,
+                )
                 dataset_info[str(dataset.uuid)] = {
                     "datasource_id": dataset.id,
                     "datasource_type": "view" if dataset.is_sqllab_view else 
"table",
@@ -109,7 +121,12 @@ class ImportDashboardsCommand(ImportModelsCommand):
             ):
                 # update datasource id, type, and name
                 config.update(dataset_info[config["dataset_uuid"]])
-                chart = import_chart(session, config, overwrite=False)
+                chart = import_chart(
+                    session,
+                    config,
+                    overwrite=False,
+                    requester_as_owner=requester_as_owner,
+                )
                 chart_ids[str(chart.uuid)] = chart.id
 
         # store the existing relationship between dashboards and charts
@@ -122,7 +139,13 @@ class ImportDashboardsCommand(ImportModelsCommand):
         for file_name, config in configs.items():
             if file_name.startswith("dashboards/"):
                 config = update_id_refs(config, chart_ids)
-                dashboard = import_dashboard(session, config, 
overwrite=overwrite)
+                dashboard = import_dashboard(
+                    session,
+                    config,
+                    overwrite=overwrite,
+                    requester_as_owner=requester_as_owner,
+                )
+
                 for uuid in find_chart_uuids(config["position"]):
                     if uuid not in chart_ids:
                         break
diff --git a/superset/dashboards/commands/importers/v1/utils.py 
b/superset/dashboards/commands/importers/v1/utils.py
index 7b2ad91..a8775c4 100644
--- a/superset/dashboards/commands/importers/v1/utils.py
+++ b/superset/dashboards/commands/importers/v1/utils.py
@@ -107,7 +107,10 @@ def update_id_refs(config: Dict[str, Any], chart_ids: 
Dict[str, int]) -> Dict[st
 
 
 def import_dashboard(
-    session: Session, config: Dict[str, Any], overwrite: bool = False
+    session: Session,
+    config: Dict[str, Any],
+    overwrite: bool = False,
+    requester_as_owner: bool = False,
 ) -> Dashboard:
     existing = session.query(Dashboard).filter_by(uuid=config["uuid"]).first()
     if existing:
@@ -126,6 +129,9 @@ def import_dashboard(
                 logger.info("Unable to encode `%s` field: %s", key, value)
 
     dashboard = Dashboard.import_from_dict(session, config, recursive=False)
+    logger.info(f"requester_as_owner: {requester_as_owner}")
+    if requester_as_owner:
+        dashboard.reset_ownership()
     if dashboard.id is None:
         session.flush()
 
diff --git a/superset/databases/commands/importers/v1/__init__.py 
b/superset/databases/commands/importers/v1/__init__.py
index 239bd09..a4d944f 100644
--- a/superset/databases/commands/importers/v1/__init__.py
+++ b/superset/databases/commands/importers/v1/__init__.py
@@ -44,13 +44,21 @@ class ImportDatabasesCommand(ImportModelsCommand):
 
     @staticmethod
     def _import(
-        session: Session, configs: Dict[str, Any], overwrite: bool = False
+        session: Session,
+        configs: Dict[str, Any],
+        overwrite: bool = False,
+        requester_as_owner: bool = False,
     ) -> None:
         # first import databases
         database_ids: Dict[str, int] = {}
         for file_name, config in configs.items():
             if file_name.startswith("databases/"):
-                database = import_database(session, config, 
overwrite=overwrite)
+                database = import_database(
+                    session,
+                    config,
+                    overwrite=overwrite,
+                    requester_as_owner=requester_as_owner,
+                )
                 database_ids[str(database.uuid)] = database.id
 
         # import related datasets
@@ -61,4 +69,9 @@ class ImportDatabasesCommand(ImportModelsCommand):
             ):
                 config["database_id"] = database_ids[config["database_uuid"]]
                 # overwrite=False prevents deleting any non-imported 
columns/metrics
-                import_dataset(session, config, overwrite=False)
+                import_dataset(
+                    session,
+                    config,
+                    overwrite=False,
+                    requester_as_owner=requester_as_owner,
+                )
diff --git a/superset/databases/commands/importers/v1/utils.py 
b/superset/databases/commands/importers/v1/utils.py
index 6e016d0..5392af4 100644
--- a/superset/databases/commands/importers/v1/utils.py
+++ b/superset/databases/commands/importers/v1/utils.py
@@ -24,7 +24,10 @@ from superset.models.core import Database
 
 
 def import_database(
-    session: Session, config: Dict[str, Any], overwrite: bool = False
+    session: Session,
+    config: Dict[str, Any],
+    overwrite: bool = False,
+    requester_as_owner: bool = False,
 ) -> Database:
     existing = session.query(Database).filter_by(uuid=config["uuid"]).first()
     if existing:
@@ -36,6 +39,8 @@ def import_database(
     config["extra"] = json.dumps(config["extra"])
 
     database = Database.import_from_dict(session, config, recursive=False)
+    if requester_as_owner:
+        database.reset_ownership()
     if database.id is None:
         session.flush()
 
diff --git a/superset/datasets/commands/importers/v1/__init__.py 
b/superset/datasets/commands/importers/v1/__init__.py
index e732133..cef94da 100644
--- a/superset/datasets/commands/importers/v1/__init__.py
+++ b/superset/datasets/commands/importers/v1/__init__.py
@@ -44,7 +44,10 @@ class ImportDatasetsCommand(ImportModelsCommand):
 
     @staticmethod
     def _import(
-        session: Session, configs: Dict[str, Any], overwrite: bool = False
+        session: Session,
+        configs: Dict[str, Any],
+        overwrite: bool = False,
+        requester_as_owner: bool = False,
     ) -> None:
         # discover databases associated with datasets
         database_uuids: Set[str] = set()
@@ -56,7 +59,12 @@ class ImportDatasetsCommand(ImportModelsCommand):
         database_ids: Dict[str, int] = {}
         for file_name, config in configs.items():
             if file_name.startswith("databases/") and config["uuid"] in 
database_uuids:
-                database = import_database(session, config, overwrite=False)
+                database = import_database(
+                    session,
+                    config,
+                    overwrite=False,
+                    requester_as_owner=requester_as_owner,
+                )
                 database_ids[str(database.uuid)] = database.id
 
         # import datasets with the correct parent ref
@@ -66,4 +74,9 @@ class ImportDatasetsCommand(ImportModelsCommand):
                 and config["database_uuid"] in database_ids
             ):
                 config["database_id"] = database_ids[config["database_uuid"]]
-                import_dataset(session, config, overwrite=overwrite)
+                import_dataset(
+                    session,
+                    config,
+                    overwrite=overwrite,
+                    requester_as_owner=requester_as_owner,
+                )
diff --git a/superset/datasets/commands/importers/v1/utils.py 
b/superset/datasets/commands/importers/v1/utils.py
index 6b4dbeb..87b0f42 100644
--- a/superset/datasets/commands/importers/v1/utils.py
+++ b/superset/datasets/commands/importers/v1/utils.py
@@ -81,6 +81,7 @@ def import_dataset(
     session: Session,
     config: Dict[str, Any],
     overwrite: bool = False,
+    requester_as_owner: bool = False,
     force_data: bool = False,
 ) -> SqlaTable:
     existing = session.query(SqlaTable).filter_by(uuid=config["uuid"]).first()
@@ -113,6 +114,8 @@ def import_dataset(
 
     # import recursively to include columns and metrics
     dataset = SqlaTable.import_from_dict(session, config, recursive=True, 
sync=sync)
+    if requester_as_owner:
+        dataset.reset_ownership()
     if dataset.id is None:
         session.flush()
 
diff --git a/superset/queries/saved_queries/commands/importers/v1/__init__.py 
b/superset/queries/saved_queries/commands/importers/v1/__init__.py
index 1412dbd..dac0911 100644
--- a/superset/queries/saved_queries/commands/importers/v1/__init__.py
+++ b/superset/queries/saved_queries/commands/importers/v1/__init__.py
@@ -46,7 +46,10 @@ class ImportSavedQueriesCommand(ImportModelsCommand):
 
     @staticmethod
     def _import(
-        session: Session, configs: Dict[str, Any], overwrite: bool = False
+        session: Session,
+        configs: Dict[str, Any],
+        overwrite: bool = False,
+        requester_as_owner: bool = False,
     ) -> None:
         # discover databases associated with saved queries
         database_uuids: Set[str] = set()
@@ -58,7 +61,12 @@ class ImportSavedQueriesCommand(ImportModelsCommand):
         database_ids: Dict[str, int] = {}
         for file_name, config in configs.items():
             if file_name.startswith("databases/") and config["uuid"] in 
database_uuids:
-                database = import_database(session, config, overwrite=False)
+                database = import_database(
+                    session,
+                    config,
+                    overwrite=False,
+                    requester_as_owner=requester_as_owner,
+                )
                 database_ids[str(database.uuid)] = database.id
 
         # import saved queries with the correct parent ref

Reply via email to