Skip to content

Commit

Permalink
feat: security, user group support
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgaspar committed Feb 3, 2025
1 parent 9e5876d commit 0c48c57
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
33 changes: 28 additions & 5 deletions superset/security/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
"List Roles",
"ResetPasswordView",
"RoleModelView",
"UserGroupModelView",
"Row Level Security",
"Row Level Security Filters",
"RowLevelSecurityFiltersModelView",
Expand Down Expand Up @@ -731,14 +732,36 @@ def user_view_menu_names(self, permission_name: str) -> set[str]:
)

if not g.user.is_anonymous:
# filter by user id
view_menu_names = (
base_query.join(assoc_user_role)
.join(self.user_model)
from sqlalchemy.orm import aliased
from flask_appbuilder.security.sqla.models import assoc_user_group, assoc_group_role

user_group = aliased(assoc_user_group)
group_role = aliased(assoc_group_role)

# Query to fetch permissions via groups' roles
view_menu_names_group_roles = (
self.get_session.query(self.viewmenu_model.name)
.join(self.permissionview_model, self.viewmenu_model.id == self.permissionview_model.view_menu_id)
.join(self.permission_model, self.permission_model.id == self.permissionview_model.permission_id)
.join(assoc_permissionview_role, assoc_permissionview_role.c.permission_view_id == self.permissionview_model.id)
.join(self.role_model, self.role_model.id == assoc_permissionview_role.c.role_id)
.join(group_role, group_role.c.role_id == self.role_model.id)
.join(self.group_model, self.group_model.id == group_role.c.group_id)
.join(user_group, user_group.c.group_id == self.group_model.id)
.join(self.user_model, self.user_model.id == user_group.c.user_id)
.filter(self.user_model.id == get_user_id())
.filter(self.permission_model.name == permission_name)
).all()
return {s.name for s in view_menu_names}
return {s.name for s in view_menu_names_group_roles}

# filter by user id
# view_menu_names_user_roles = (
# base_query.join(assoc_user_role)
# .join(self.user_model)
# .filter(self.user_model.id == get_user_id())
# .filter(self.permission_model.name == permission_name)
# ).all()
# return {s.name for s in view_menu_names}

# Properly treat anonymous user
if public_role := self.get_public_role():
Expand Down
4 changes: 2 additions & 2 deletions superset/views/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ def bootstrap_user_data(user: User, include_perms: bool = False) -> dict[str, An
def get_permissions(
user: User,
) -> tuple[dict[str, list[tuple[str]]], DefaultDict[str, list[str]]]:
if not user.roles:
raise AttributeError("User object does not have roles")
if not user.roles and not user.groups:
raise AttributeError("User object does not have roles or groups")

data_permissions = defaultdict(set)
roles_permissions = security_manager.get_user_roles_permissions(user)
Expand Down

0 comments on commit 0c48c57

Please sign in to comment.