Skip to content

Commit 286474c

Browse files
author
Zef Lin
authored
fix: revert permission refactoring PR (#21313)
1 parent 9be4870 commit 286474c

File tree

3 files changed

+24
-244
lines changed

3 files changed

+24
-244
lines changed

superset/security/manager.py

-40
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@
2424
Any,
2525
Callable,
2626
cast,
27-
DefaultDict,
2827
Dict,
2928
List,
3029
NamedTuple,
3130
Optional,
3231
Set,
33-
Tuple,
3432
TYPE_CHECKING,
3533
Union,
3634
)
@@ -2125,41 +2123,3 @@ def is_admin(self) -> bool:
21252123
return current_app.config["AUTH_ROLE_ADMIN"] in [
21262124
role.name for role in self.get_user_roles()
21272125
]
2128-
2129-
def get_permissions(
2130-
self,
2131-
user: User,
2132-
) -> Tuple[Dict[str, List[List[str]]], DefaultDict[str, List[str]]]:
2133-
if not user.roles:
2134-
raise AttributeError("User object does not have roles")
2135-
2136-
roles = defaultdict(list)
2137-
permissions = defaultdict(set)
2138-
2139-
query = (
2140-
self.get_session.query(Role.name, Permission.name, ViewMenu.name)
2141-
.join(assoc_user_role, assoc_user_role.c.role_id == Role.id)
2142-
.join(Role.permissions)
2143-
.join(PermissionView.view_menu)
2144-
.join(PermissionView.permission)
2145-
)
2146-
2147-
if user.is_anonymous:
2148-
public_role = current_app.config.get("AUTH_ROLE_PUBLIC")
2149-
query = query.filter(Role.name == public_role)
2150-
elif self.is_guest_user(user):
2151-
guest_role = current_app.config.get("GUEST_ROLE_NAME")
2152-
query = query.filter(Role.name == guest_role)
2153-
else:
2154-
query = query.filter(assoc_user_role.c.user_id == user.id)
2155-
2156-
rows = query.all()
2157-
for role, permission, view_menu in rows:
2158-
if permission in ("datasource_access", "database_access"):
2159-
permissions[permission].add(view_menu)
2160-
roles[role].append([permission, view_menu])
2161-
2162-
transformed_permissions = defaultdict(list)
2163-
for perm in permissions:
2164-
transformed_permissions[perm] = list(permissions[perm])
2165-
return roles, transformed_permissions

superset/views/utils.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717
import logging
18+
from collections import defaultdict
1819
from functools import wraps
19-
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
20+
from typing import Any, Callable, DefaultDict, Dict, List, Optional, Tuple, Union
2021
from urllib import parse
2122

2223
import msgpack
@@ -93,13 +94,34 @@ def bootstrap_user_data(user: User, include_perms: bool = False) -> Dict[str, An
9394
}
9495

9596
if include_perms:
96-
roles, permissions = security_manager.get_permissions(user)
97+
roles, permissions = get_permissions(user)
9798
payload["roles"] = roles
9899
payload["permissions"] = permissions
99100

100101
return payload
101102

102103

104+
def get_permissions(
105+
user: User,
106+
) -> Tuple[Dict[str, List[List[str]]], DefaultDict[str, List[str]]]:
107+
if not user.roles:
108+
raise AttributeError("User object does not have roles")
109+
110+
roles = defaultdict(list)
111+
permissions = defaultdict(set)
112+
113+
for role in user.roles:
114+
permissions_ = security_manager.get_role_permissions(role)
115+
for permission in permissions_:
116+
if permission[0] in ("datasource_access", "database_access"):
117+
permissions[permission[0]].add(permission[1])
118+
roles[role.name].append([permission[0], permission[1]])
119+
transformed_permissions = defaultdict(list)
120+
for perm in permissions:
121+
transformed_permissions[perm] = list(permissions[perm])
122+
return roles, transformed_permissions
123+
124+
103125
def get_viz(
104126
form_data: FormData,
105127
datasource_type: str,

tests/integration_tests/security_tests.py

-202
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
load_world_bank_dashboard_with_slices,
6161
load_world_bank_data,
6262
)
63-
from .dashboard_utils import get_table
6463

6564
NEW_SECURITY_CONVERGE_VIEWS = (
6665
"Annotation",
@@ -73,159 +72,6 @@
7372
"SavedQuery",
7473
)
7574

76-
GAMMA_ROLE_PERMISSIONS = {
77-
"Gamma": [
78-
["menu_access", "List Users"],
79-
["can_read", "SavedQuery"],
80-
["can_write", "SavedQuery"],
81-
["can_read", "CssTemplate"],
82-
["can_write", "CssTemplate"],
83-
["can_read", "ReportSchedule"],
84-
["can_write", "ReportSchedule"],
85-
["can_read", "AvailableDomains"],
86-
["can_read", "Chart"],
87-
["can_write", "Chart"],
88-
["can_read", "Annotation"],
89-
["can_write", "Annotation"],
90-
["can_read", "Dataset"],
91-
["can_read", "Dashboard"],
92-
["can_write", "Dashboard"],
93-
["can_read", "Database"],
94-
["can_read", "Query"],
95-
["can_this_form_post", "ResetMyPasswordView"],
96-
["can_this_form_get", "ResetMyPasswordView"],
97-
["can_this_form_post", "UserInfoEditView"],
98-
["can_this_form_get", "UserInfoEditView"],
99-
["can_userinfo", "UserDBModelView"],
100-
["resetmypassword", "UserDBModelView"],
101-
["can_get", "OpenApi"],
102-
["can_show", "SwaggerView"],
103-
["can_get", "MenuApi"],
104-
["can_list", "AsyncEventsRestApi"],
105-
["can_read", "AdvancedDataType"],
106-
["can_invalidate", "CacheRestApi"],
107-
["can_export", "Chart"],
108-
["can_read", "DashboardFilterStateRestApi"],
109-
["can_write", "DashboardFilterStateRestApi"],
110-
["can_read", "DashboardPermalinkRestApi"],
111-
["can_write", "DashboardPermalinkRestApi"],
112-
["can_delete_embedded", "Dashboard"],
113-
["can_get_embedded", "Dashboard"],
114-
["can_export", "Dashboard"],
115-
["can_read", "EmbeddedDashboard"],
116-
["can_read", "Explore"],
117-
["can_read", "ExploreFormDataRestApi"],
118-
["can_write", "ExploreFormDataRestApi"],
119-
["can_read", "ExplorePermalinkRestApi"],
120-
["can_write", "ExplorePermalinkRestApi"],
121-
["can_delete", "FilterSets"],
122-
["can_list", "FilterSets"],
123-
["can_edit", "FilterSets"],
124-
["can_add", "FilterSets"],
125-
["can_import_", "ImportExportRestApi"],
126-
["can_export", "ImportExportRestApi"],
127-
["can_export", "SavedQuery"],
128-
["can_show", "DynamicPlugin"],
129-
["can_list", "DynamicPlugin"],
130-
["can_time_range", "Api"],
131-
["can_query_form_data", "Api"],
132-
["can_query", "Api"],
133-
["can_this_form_post", "CsvToDatabaseView"],
134-
["can_this_form_get", "CsvToDatabaseView"],
135-
["can_this_form_post", "ExcelToDatabaseView"],
136-
["can_this_form_get", "ExcelToDatabaseView"],
137-
["can_this_form_post", "ColumnarToDatabaseView"],
138-
["can_this_form_get", "ColumnarToDatabaseView"],
139-
["can_get", "Datasource"],
140-
["can_external_metadata", "Datasource"],
141-
["can_external_metadata_by_name", "Datasource"],
142-
["can_get_value", "KV"],
143-
["can_store", "KV"],
144-
["can_my_queries", "SqlLab"],
145-
["can_created_dashboards", "Superset"],
146-
["can_testconn", "Superset"],
147-
["can_estimate_query_cost", "Superset"],
148-
["can_explore", "Superset"],
149-
["can_fetch_datasource_metadata", "Superset"],
150-
["can_search_queries", "Superset"],
151-
["can_save_dash", "Superset"],
152-
["can_dashboard_permalink", "Superset"],
153-
["can_warm_up_cache", "Superset"],
154-
["can_request_access", "Superset"],
155-
["can_datasources", "Superset"],
156-
["can_available_domains", "Superset"],
157-
["can_dashboard", "Superset"],
158-
["can_annotation_json", "Superset"],
159-
["can_created_slices", "Superset"],
160-
["can_slice_json", "Superset"],
161-
["can_profile", "Superset"],
162-
["can_filter", "Superset"],
163-
["can_validate_sql_json", "Superset"],
164-
["can_slice", "Superset"],
165-
["can_sqllab", "Superset"],
166-
["can_log", "Superset"],
167-
["can_recent_activity", "Superset"],
168-
["can_tables", "Superset"],
169-
["can_fave_slices", "Superset"],
170-
["can_sqllab_viz", "Superset"],
171-
["can_fave_dashboards", "Superset"],
172-
["can_results", "Superset"],
173-
["can_extra_table_metadata", "Superset"],
174-
["can_schemas_access_for_file_upload", "Superset"],
175-
["can_fave_dashboards_by_username", "Superset"],
176-
["can_csv", "Superset"],
177-
["can_add_slices", "Superset"],
178-
["can_explore_json", "Superset"],
179-
["can_sqllab_history", "Superset"],
180-
["can_import_dashboards", "Superset"],
181-
["can_sqllab_table_viz", "Superset"],
182-
["can_stop_query", "Superset"],
183-
["can_favstar", "Superset"],
184-
["can_copy_dash", "Superset"],
185-
["can_queries", "Superset"],
186-
["can_user_slices", "Superset"],
187-
["can_delete", "TableSchemaView"],
188-
["can_post", "TableSchemaView"],
189-
["can_expanded", "TableSchemaView"],
190-
["can_get", "TabStateView"],
191-
["can_post", "TabStateView"],
192-
["can_migrate_query", "TabStateView"],
193-
["can_put", "TabStateView"],
194-
["can_activate", "TabStateView"],
195-
["can_delete", "TabStateView"],
196-
["can_delete_query", "TabStateView"],
197-
["can_get", "TagView"],
198-
["can_tagged_objects", "TagView"],
199-
["can_post", "TagView"],
200-
["can_delete", "TagView"],
201-
["can_suggestions", "TagView"],
202-
["can_read", "SecurityRestApi"],
203-
["menu_access", "List Roles"],
204-
["menu_access", "Action Log"],
205-
["menu_access", "Access requests"],
206-
["menu_access", "Home"],
207-
["menu_access", "Annotation Layers"],
208-
["menu_access", "Plugins"],
209-
["menu_access", "Import Dashboards"],
210-
["menu_access", "Alerts & Report"],
211-
["menu_access", "Dashboards"],
212-
["menu_access", "Charts"],
213-
["menu_access", "SQL Editor"],
214-
["menu_access", "Saved Queries"],
215-
["menu_access", "Query Search"],
216-
["menu_access", "Data"],
217-
["menu_access", "Databases"],
218-
["menu_access", "Datasets"],
219-
["can_share_dashboard", "Superset"],
220-
["can_share_chart", "Superset"],
221-
],
222-
"schema_access_role": [["schema_access", "[examples].[temp_schema]"]],
223-
"dummy_role": [
224-
["datasource_access", "[examples].[wb_health_population](id:1)"],
225-
["database_access", "[examples].(id:1)"],
226-
],
227-
}
228-
22975

23076
def get_perm_tuples(role_name):
23177
perm_set = set()
@@ -1757,54 +1603,6 @@ def test_views_are_secured(self):
17571603
view_str = "\n".join([str(v) for v in unsecured_views])
17581604
raise Exception(f"Some views are not secured:\n{view_str}")
17591605

1760-
@patch("superset.utils.core.g")
1761-
@patch("superset.security.manager.g")
1762-
def test_get_permissions_gamma_user(self, mock_sm_g, mock_g):
1763-
session = db.session
1764-
role_name = "dummy_role"
1765-
gamma_user = security_manager.find_user(username="gamma")
1766-
security_manager.add_role(role_name)
1767-
dummy_role = security_manager.find_role(role_name)
1768-
gamma_user.roles.append(dummy_role)
1769-
1770-
table = (
1771-
db.session.query(SqlaTable)
1772-
.filter_by(table_name="wb_health_population")
1773-
.one()
1774-
)
1775-
table_perm = table.perm
1776-
security_manager.add_permission_role(
1777-
dummy_role,
1778-
security_manager.find_permission_view_menu("datasource_access", table_perm),
1779-
)
1780-
security_manager.add_permission_role(
1781-
dummy_role,
1782-
security_manager.find_permission_view_menu(
1783-
"database_access", table.database.perm
1784-
),
1785-
)
1786-
1787-
session.commit()
1788-
1789-
mock_g.user = mock_sm_g.user = security_manager.find_user("gamma")
1790-
with self.client.application.test_request_context():
1791-
roles, permissions = security_manager.get_permissions(mock_g.user)
1792-
assert "dummy_role" in roles
1793-
assert "Gamma" in roles
1794-
assert sorted(roles["Gamma"]) == sorted(GAMMA_ROLE_PERMISSIONS["Gamma"])
1795-
assert sorted(roles["schema_access_role"]) == sorted(
1796-
GAMMA_ROLE_PERMISSIONS["schema_access_role"]
1797-
)
1798-
1799-
assert len(permissions) == 2
1800-
assert "[examples].(id:" in permissions["database_access"][0]
1801-
assert "[examples].[" in permissions["datasource_access"][0]
1802-
1803-
# cleanup
1804-
gamma_user = security_manager.find_user(username="gamma")
1805-
gamma_user.roles.remove(security_manager.find_role(role_name))
1806-
session.commit()
1807-
18081606

18091607
class TestSecurityManager(SupersetTestCase):
18101608
"""

0 commit comments

Comments
 (0)