From 60faa4b5e313052cfc4dfac3b595f77b4354ba34 Mon Sep 17 00:00:00 2001 From: Guillermo Negrete <101662148+zgnegrete@users.noreply.github.com> Date: Tue, 10 Oct 2023 11:32:14 -0300 Subject: [PATCH] Chore: Enabling role assignation for superset internal ZFE-78488 Fix: Adding sm to find role ZFE-78488 Fix: Moving into external assets url ZFE-78488 Fix: Moving into external assets url ZFE-78488 Fix: Movig api host to correct config ZFE-78488 Fix: Commit role change ZFE-78488 Fix: Skip role admin internal validation ZFE-78488 Fix: Removing commit of the user ZFE-78488 Fix: Adding logs ZFE-78488 Adding logs ZFE-78488 Adding logs ZFE-78488 Adding logs ZFE-78488 Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Adding table permission to read Commenting out datasource specific access ZFE-78488 --- bi_superset/bi_cli/bi_cli_security_manager.py | 39 +++++++++++++++++++ bi_superset/bi_custom_security_manager.py | 4 +- .../services/user_service.py | 33 ++++++++++------ bi_superset/superset_config.py | 19 ++++----- superset-frontend/webpack.config.js | 2 +- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/bi_superset/bi_cli/bi_cli_security_manager.py b/bi_superset/bi_cli/bi_cli_security_manager.py index cf6676ad3c787..a5bc37df4d968 100644 --- a/bi_superset/bi_cli/bi_cli_security_manager.py +++ b/bi_superset/bi_cli/bi_cli_security_manager.py @@ -116,6 +116,45 @@ def loads_data_sources_access(self): index=True, index_label="id", ) + # TODO: COMMENTING OUT TILL WE HAVE DECIDE ON HOW TO HANDLE INTERNAL ACCESS + # if access method is internal + # if AccessMethod.is_internal(self._access_method): + # from superset.connectors.sqla.models import SqlaTable + + # permission_name = "datasource_access" + # session = self.get_session() + # # iterate over res_df + # for row in res_df.to_dict(orient="records"): + # # role + # role_to_find = row["role_name"] + # if "admin" == role_to_find: + # continue + + # role = self.find_role(row["role_name"]) + # if role is None: + # logging.warning(f"Role {role_to_find} does not exist.") + # continue + # table_name = row["table_name"] + # table_schema = row["table_schema"] + # logging.info(f"Getting Table {table_schema} {table_name}") + # dataset = ( + # session.query(SqlaTable) + # .filter( + # SqlaTable.table_name == table_name, + # SqlaTable.schema == table_schema, + # ) + # .one_or_none() + # ) + # if dataset is None: + # logging.warning( + # f"Dataset {table_schema}.{table_name} does not exist." + # ) + # continue + # dataset_permission_view = self.find_permission_view_menu( + # permission_name, dataset.get_perm() + # ) + # self.add_permission_role(role, dataset_permission_view) + # session.commit() def loads_roles_per_job_title(self): """ diff --git a/bi_superset/bi_custom_security_manager.py b/bi_superset/bi_custom_security_manager.py index d3408d4366079..5c9a509140279 100644 --- a/bi_superset/bi_custom_security_manager.py +++ b/bi_superset/bi_custom_security_manager.py @@ -53,7 +53,8 @@ def auth_user_oauth(self, userinfo): if not zf_user.is_active: return None - if (AccessMethod.is_internal(self._access_method) + if ( + AccessMethod.is_internal(self._access_method) and zf_user.is_internal_user is False ): return None @@ -61,4 +62,3 @@ def auth_user_oauth(self, userinfo): userService = UserService(self._access_method, self._access_origin, self) user = userService.update_roles_rls(user, zf_user) return user - diff --git a/bi_superset/bi_security_manager/services/user_service.py b/bi_superset/bi_security_manager/services/user_service.py index acb82570c67d2..3e1a28a7da4a0 100644 --- a/bi_superset/bi_security_manager/services/user_service.py +++ b/bi_superset/bi_security_manager/services/user_service.py @@ -4,11 +4,11 @@ from bi_superset.bi_security_manager.models.user import User as ZFUser from bi_superset.bi_security_manager.models.access_method import AccessMethod from bi_superset.bi_security_manager.models.access_origin import AccessOrigin + logger = logging.getLogger(__name__) class UserService: - def __init__(self, access_method, access_origin, sm): self._access_method = access_method self._access_origin = access_origin @@ -42,7 +42,8 @@ def check_and_update_user_rls(self, zf_user: ZFUser) -> bool: if rls is None: # Only applied to enteprise role of the current user enterprise_role = self.sm.find_role( - zf_user.superset_role_name(self._access_origin)) + zf_user.superset_role_name(self._access_origin) + ) self.add_rls( enterprise_id=zf_user.enterprise_id, roles=[enterprise_role], @@ -63,10 +64,14 @@ def get_and_update_user_roles(self, user, zf_user: ZFUser): Checks current user info against user_info from oauth_user_info this will update user role """ - if user.roles == "Admin" and AccessOrigin.is_from_superset_ui(self._access_origin): + if user.roles == "Admin" and AccessOrigin.is_from_superset_ui( + self._access_origin + ): return user - if zf_user.is_internal_user and AccessOrigin.is_from_superset_ui(self._access_origin): + if zf_user.is_internal_user and AccessOrigin.is_from_superset_ui( + self._access_origin + ): if AccessMethod.is_external(self._access_method): role = self.sm.find_role("Admin") else: @@ -82,23 +87,27 @@ def get_and_update_user_roles(self, user, zf_user: ZFUser): ) user_role_job_title = query.one_or_none() - # comment due that is not viable to use yet - # role = self.find_role(user_role_job_title.role_name) - role = self.sm.find_role("zerofox_internal") - user.roles += [role] + logger.info(f"Role: {user_role_job_title.role_name} assigned") + search_role_name = user_role_job_title.role_name + if "admin" == search_role_name.lower(): + search_role_name = search_role_name.capitalize() + role = self.sm.find_role(search_role_name) + if role is None: + logger.info("Role Not found") + # role = self.sm.find_role("zerofox_internal") + user.roles = [role] else: # Check if role exists, `view_only enterprise_id`` default_role = self.sm.find_role("view_only") - role = self.sm.find_role( - zf_user.superset_role_name(self._access_origin)) + role = self.sm.find_role(zf_user.superset_role_name(self._access_origin)) if role is None: # If not copy from default role permissions # Creates new roles role = self.sm.add_role( - zf_user.superset_role_name( - self._access_origin), default_role.permissions + zf_user.superset_role_name(self._access_origin), + default_role.permissions, ) # Assign it to current user user.roles = [default_role, role] diff --git a/bi_superset/superset_config.py b/bi_superset/superset_config.py index f453577492c7c..092057b6f117a 100644 --- a/bi_superset/superset_config.py +++ b/bi_superset/superset_config.py @@ -74,14 +74,14 @@ def get_env_variable(var_name: str, default: Optional[str] = None) -> str: DASHBOARD_RBAC = True # Enable embedded Configuration ENABLE_PROXY_FIX = True - DEFAULT_HTTP_HEADERS={'X-Frame-Options': 'ALLOWALL'} - OVERRIDE_HTTP_HEADERS={'X-Frame-Options': 'ALLOWALL'} + DEFAULT_HTTP_HEADERS = {"X-Frame-Options": "ALLOWALL"} + OVERRIDE_HTTP_HEADERS = {"X-Frame-Options": "ALLOWALL"} ENABLE_CORS = True CORS_OPTIONS = { - 'supports_credentials': True, - 'allow_headers': ['*'], - 'resources':['*'], - 'origins': [''] + "supports_credentials": True, + "allow_headers": ["*"], + "resources": ["*"], + "origins": [""], } WTF_CSRF_ENABLED = False @@ -92,13 +92,14 @@ def get_env_variable(var_name: str, default: Optional[str] = None) -> str: GUEST_TOKEN_JWT_SECRET = get_env_variable("GUEST_TOKEN_JWT_SECRET", None) GUEST_TOKEN_JWT_ALGO = "HS256" GUEST_TOKEN_HEADER_NAME = "X-GuestToken" - GUEST_TOKEN_JWT_EXP_SECONDS = 60*60 # 1 hour + GUEST_TOKEN_JWT_EXP_SECONDS = 60 * 60 # 1 hour ZF_JWT_PUBLIC_SECRET = get_env_variable("ZF_JWT_PUBLIC_SECRET", None) -STATIC_ASSETS_PREFIX = f'{os.environ.get("ZF_DASHBOARD_HOST")}/spa_bff/superset' -BQ_DATASET = os.getenv("BQ_DATASET", None) + STATIC_ASSETS_PREFIX = f'{os.environ.get("ZF_DASHBOARD_HOST")}/spa_bff/superset' ZF_API_HOST = os.getenv("ZF_API_HOST", "https://api-qa.zerofox.com") +BQ_DATASET = os.getenv("BQ_DATASET", None) + FEATURE_FLAGS = { "ENABLE_TEMPLATE_PROCESSING": True, "ESTIMATE_QUERY_COST": True, diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js index c807554954b6c..ac8a7f0cafe2c 100644 --- a/superset-frontend/webpack.config.js +++ b/superset-frontend/webpack.config.js @@ -52,7 +52,7 @@ const { } = parsedArgs; const isDevMode = mode !== 'production'; const isDevServer = process.argv[1].includes('webpack-dev-server'); -const ASSET_BASE_URL = process.env.ASSET_BASE_URL || 'http://localhost:8000/spa_bff/superset'; +const ASSET_BASE_URL = process.env.ASSET_BASE_URL; const output = { path: BUILD_DIR,