You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by am...@apache.org on 2021/03/22 12:42:44 UTC

[superset] branch feat/dashboard_extra_jwt created (now 38c678d)

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

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


      at 38c678d  start of dashboard jwt manager

This branch includes the following new commits:

     new 38c678d  start of dashboard jwt manager

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[superset] 01/01: start of dashboard jwt manager

Posted by am...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 38c678da61f35a8c8b74473375d250d164468c8e
Author: amitmiran137 <am...@nielsen.com>
AuthorDate: Thu Mar 18 13:20:35 2021 +0200

    start of dashboard jwt manager
---
 superset/app.py                         |  7 ++++++-
 superset/extensions.py                  |  2 ++
 superset/utils/dashboard_jwt_manager.py | 36 +++++++++++++++++++++++++++++++++
 superset/views/core.py                  | 15 +++++++++++++-
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/superset/app.py b/superset/app.py
index 432d3fb..38d499f 100644
--- a/superset/app.py
+++ b/superset/app.py
@@ -40,7 +40,7 @@ from superset.extensions import (
     manifest_processor,
     migrate,
     results_backend_manager,
-    talisman,
+    talisman, dashboard_jwt_manager,
 )
 from superset.security import SupersetSecurityManager
 from superset.typing import FlaskResponse
@@ -530,6 +530,7 @@ class SupersetAppInitializer:
         self.configure_data_sources()
         self.configure_auth_provider()
         self.configure_async_queries()
+        self.configure_dashboard_jwt()
 
         # Hook that provides administrators a handle on the Flask APP
         # after initialization
@@ -694,3 +695,7 @@ class SupersetAppInitializer:
 
     def setup_bundle_manifest(self) -> None:
         manifest_processor.init_app(self.flask_app)
+
+    def configure_dashboard_jwt(self):
+        if feature_flag_manager.is_feature_enabled("DASHBOARD_RBAC"):
+            dashboard_jwt_manager.init_app(self.flask_app)
diff --git a/superset/extensions.py b/superset/extensions.py
index 8f5bc6d..098471f 100644
--- a/superset/extensions.py
+++ b/superset/extensions.py
@@ -29,6 +29,7 @@ from werkzeug.local import LocalProxy
 
 from superset.utils.async_query_manager import AsyncQueryManager
 from superset.utils.cache_manager import CacheManager
+from superset.utils.dashboard_jwt_manager import DashboardJwtManager
 from superset.utils.feature_flag_manager import FeatureFlagManager
 from superset.utils.machine_auth import MachineAuthProviderFactory
 
@@ -100,6 +101,7 @@ APP_DIR = os.path.dirname(__file__)
 appbuilder = AppBuilder(update_perms=False)
 async_query_manager = AsyncQueryManager()
 cache_manager = CacheManager()
+dashboard_jwt_manager = DashboardJwtManager()
 celery_app = celery.Celery()
 csrf = CSRFProtect()
 db = SQLA()
diff --git a/superset/utils/dashboard_jwt_manager.py b/superset/utils/dashboard_jwt_manager.py
new file mode 100644
index 0000000..8a629e7
--- /dev/null
+++ b/superset/utils/dashboard_jwt_manager.py
@@ -0,0 +1,36 @@
+import json
+from typing import Dict, Any
+
+import jwt
+from flask import Flask
+
+
+class DashboardJwtDataObject:
+    id_or_slug: int
+    dataset_ids: [int]
+
+    def __init__(self, id: int, dataset_ids: [int]) -> None:
+        super().__init__()
+        self.id_or_slug = id
+        self.dataset_ids = dataset_ids
+
+
+class DashboardJwtManager:
+
+    def __init__(self) -> None:
+        super().__init__()
+        self._jwt_secret: str
+
+    def init_app(self, app: Flask) -> None:
+        config = app.config
+
+        self._jwt_secret = config["DASHBOARD_JWT_SECRET"]
+
+    def generate_jwt(self, data: DashboardJwtDataObject) -> str:
+        encoded_jwt = jwt.encode(data.__dict__, self._jwt_secret, algorithm="HS256")
+        return encoded_jwt.decode("utf-8")
+
+    def parse_jwt(self, token: str) -> Dict[str, Any]:
+        data = jwt.decode(token, self._jwt_secret, algorithms=["HS256"])
+        #todo validate data
+        return data
diff --git a/superset/views/core.py b/superset/views/core.py
index 2c390c4..aa561f9 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -84,7 +84,8 @@ from superset.exceptions import (
     SupersetTemplateParamsErrorException,
     SupersetTimeoutException,
 )
-from superset.extensions import async_query_manager, cache_manager
+from superset.extensions import async_query_manager, cache_manager, \
+    dashboard_jwt_manager
 from superset.jinja_context import get_template_processor
 from superset.models.core import Database, FavStar, Log
 from superset.models.dashboard import Dashboard
@@ -102,6 +103,8 @@ from superset.utils import core as utils
 from superset.utils.async_query_manager import AsyncQueryTokenException
 from superset.utils.cache import etag_cache
 from superset.utils.core import ReservedUrlParameters
+from superset.utils.dashboard_jwt_manager import DashboardJwtManager, \
+    DashboardJwtDataObject
 from superset.utils.dates import now_as_float
 from superset.utils.decorators import check_dashboard_access
 from superset.views.base import (
@@ -1866,6 +1869,8 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
             if key not in [param.value for param in utils.ReservedUrlParameters]
         }
 
+
+
         bootstrap_data = {
             "user_id": g.user.get_id(),
             "common": common_bootstrap_payload(),
@@ -1880,6 +1885,14 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
                 "superset_can_csv": superset_can_csv,
                 "slice_can_edit": slice_can_edit,
             },
+            "extra_jwt": dashboard_jwt_manager
+                .generate_jwt(DashboardJwtDataObject(dashboard.id,
+                                                     list(
+                                                         map(
+                                                             lambda
+                                                             datasource: datasource.id,
+                                                             dashboard.datasources))
+                                                     )),
             "datasources": data["datasources"],
         }