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 <[email protected]>
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"],
         }
 

Reply via email to