mirror of https://github.com/apache/superset.git
fix: RBAC for export for dashboard viewers (#17527)
* set out export * update test * use default dataset * update test * these test work * fix test * update * fix * fix test * make the test better
This commit is contained in:
parent
7429282972
commit
2e29f36e78
|
@ -66,7 +66,7 @@ export default function ChartCard({
|
|||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canExport =
|
||||
hasPerm('can_read') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
hasPerm('can_export') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
const theme = useTheme();
|
||||
|
||||
const menu = (
|
||||
|
|
|
@ -183,7 +183,7 @@ function ChartList(props: ChartListProps) {
|
|||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canExport =
|
||||
hasPerm('can_read') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
hasPerm('can_export') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
const initialSort = [{ id: 'changed_on_delta_humanized', desc: true }];
|
||||
|
||||
const handleBulkChartExport = (chartsToExport: Chart[]) => {
|
||||
|
|
|
@ -66,7 +66,7 @@ function DashboardCard({
|
|||
const history = useHistory();
|
||||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canExport = hasPerm('can_read');
|
||||
const canExport = hasPerm('can_export');
|
||||
|
||||
const theme = useTheme();
|
||||
const menu = (
|
||||
|
|
|
@ -149,7 +149,7 @@ function DashboardList(props: DashboardListProps) {
|
|||
const canCreate = hasPerm('can_write');
|
||||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canExport = hasPerm('can_read');
|
||||
const canExport = hasPerm('can_export');
|
||||
|
||||
const initialSort = [{ id: 'changed_on_delta_humanized', desc: true }];
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
|||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canExport =
|
||||
hasPerm('can_read') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
hasPerm('can_export') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
|
||||
const menuData: SubMenuProps = {
|
||||
activeChild: 'Databases',
|
||||
|
|
|
@ -152,7 +152,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
|||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canCreate = hasPerm('can_write');
|
||||
const canExport = hasPerm('can_read');
|
||||
const canExport = hasPerm('can_export');
|
||||
|
||||
const initialSort = SORT_BY;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ const mockImportFile = new File(
|
|||
);
|
||||
|
||||
fetchMock.get(queriesInfoEndpoint, {
|
||||
permissions: ['can_write', 'can_read'],
|
||||
permissions: ['can_write', 'can_read', 'can_export'],
|
||||
});
|
||||
fetchMock.get(queriesEndpoint, {
|
||||
result: mockqueries,
|
||||
|
|
|
@ -133,7 +133,7 @@ function SavedQueryList({
|
|||
const canEdit = hasPerm('can_write');
|
||||
const canDelete = hasPerm('can_write');
|
||||
const canExport =
|
||||
hasPerm('can_read') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
hasPerm('can_export') && isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT);
|
||||
|
||||
const openNewQuery = () => {
|
||||
window.open(`${window.location.origin}/superset/sqllab?new=true`);
|
||||
|
|
|
@ -100,7 +100,6 @@ MODEL_API_RW_METHOD_PERMISSION_MAP = {
|
|||
"bulk_delete": "write",
|
||||
"delete": "write",
|
||||
"distinct": "read",
|
||||
"export": "read",
|
||||
"get": "read",
|
||||
"get_list": "read",
|
||||
"info": "read",
|
||||
|
|
|
@ -183,10 +183,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin, InsertChartMixin):
|
|||
rv = self.get_assert_metric(uri, "info")
|
||||
data = json.loads(rv.data.decode("utf-8"))
|
||||
assert rv.status_code == 200
|
||||
assert set(data["permissions"]) == {
|
||||
"can_read",
|
||||
"can_write",
|
||||
}
|
||||
assert set(data["permissions"]) == {"can_read", "can_write", "can_export"}
|
||||
|
||||
def create_chart_import(self):
|
||||
buf = BytesIO()
|
||||
|
|
|
@ -378,9 +378,7 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin, InsertChartMixi
|
|||
rv = self.get_assert_metric(uri, "info")
|
||||
data = json.loads(rv.data.decode("utf-8"))
|
||||
assert rv.status_code == 200
|
||||
assert "can_read" in data["permissions"]
|
||||
assert "can_write" in data["permissions"]
|
||||
assert len(data["permissions"]) == 2
|
||||
assert set(data["permissions"]) == {"can_read", "can_write", "can_export"}
|
||||
|
||||
@pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
|
||||
def test_get_dashboard_not_found(self):
|
||||
|
|
|
@ -744,9 +744,7 @@ class TestDatabaseApi(SupersetTestCase):
|
|||
rv = self.get_assert_metric(uri, "info")
|
||||
data = json.loads(rv.data.decode("utf-8"))
|
||||
assert rv.status_code == 200
|
||||
assert "can_read" in data["permissions"]
|
||||
assert "can_write" in data["permissions"]
|
||||
assert len(data["permissions"]) == 2
|
||||
assert set(data["permissions"]) == {"can_read", "can_write", "can_export"}
|
||||
|
||||
def test_get_invalid_database_table_metadata(self):
|
||||
"""
|
||||
|
@ -1143,9 +1141,7 @@ class TestDatabaseApi(SupersetTestCase):
|
|||
argument = [database.id]
|
||||
uri = f"api/v1/database/export/?q={prison.dumps(argument)}"
|
||||
rv = self.client.get(uri)
|
||||
# export only requires can_read now, but gamma need to have explicit access to
|
||||
# view the database
|
||||
assert rv.status_code == 404
|
||||
assert rv.status_code == 401
|
||||
|
||||
def test_export_database_non_existing(self):
|
||||
"""
|
||||
|
|
|
@ -375,9 +375,7 @@ class TestDatasetApi(SupersetTestCase):
|
|||
rv = self.get_assert_metric(uri, "info")
|
||||
data = json.loads(rv.data.decode("utf-8"))
|
||||
assert rv.status_code == 200
|
||||
assert "can_read" in data["permissions"]
|
||||
assert "can_write" in data["permissions"]
|
||||
assert len(data["permissions"]) == 2
|
||||
assert set(data["permissions"]) == {"can_read", "can_write", "can_export"}
|
||||
|
||||
def test_create_dataset_item(self):
|
||||
"""
|
||||
|
@ -1382,18 +1380,33 @@ class TestDatasetApi(SupersetTestCase):
|
|||
rv = self.get_assert_metric(uri, "export")
|
||||
assert rv.status_code == 404
|
||||
|
||||
@pytest.mark.usefixtures("create_datasets")
|
||||
def test_export_dataset_gamma(self):
|
||||
"""
|
||||
Dataset API: Test export dataset has gamma
|
||||
"""
|
||||
birth_names_dataset = self.get_birth_names_dataset()
|
||||
dataset = self.get_fixture_datasets()[0]
|
||||
|
||||
argument = [birth_names_dataset.id]
|
||||
argument = [dataset.id]
|
||||
uri = f"api/v1/dataset/export/?q={prison.dumps(argument)}"
|
||||
|
||||
self.login(username="gamma")
|
||||
rv = self.client.get(uri)
|
||||
assert rv.status_code == 404
|
||||
assert rv.status_code == 401
|
||||
|
||||
perm1 = security_manager.find_permission_view_menu("can_export", "Dataset")
|
||||
|
||||
perm2 = security_manager.find_permission_view_menu(
|
||||
"datasource_access", dataset.perm
|
||||
)
|
||||
|
||||
# add perissions to allow export + access to query this dataset
|
||||
gamma_role = security_manager.find_role("Gamma")
|
||||
security_manager.add_permission_role(gamma_role, perm1)
|
||||
security_manager.add_permission_role(gamma_role, perm2)
|
||||
|
||||
rv = self.client.get(uri)
|
||||
assert rv.status_code == 200
|
||||
|
||||
@patch.dict(
|
||||
"superset.extensions.feature_flag_manager._feature_flags",
|
||||
|
@ -1444,19 +1457,20 @@ class TestDatasetApi(SupersetTestCase):
|
|||
{"VERSIONED_EXPORT": True},
|
||||
clear=True,
|
||||
)
|
||||
@pytest.mark.usefixtures("create_datasets")
|
||||
def test_export_dataset_bundle_gamma(self):
|
||||
"""
|
||||
Dataset API: Test export dataset has gamma
|
||||
"""
|
||||
birth_names_dataset = self.get_birth_names_dataset()
|
||||
dataset = self.get_fixture_datasets()[0]
|
||||
|
||||
argument = [birth_names_dataset.id]
|
||||
argument = [dataset.id]
|
||||
uri = f"api/v1/dataset/export/?q={prison.dumps(argument)}"
|
||||
|
||||
self.login(username="gamma")
|
||||
rv = self.client.get(uri)
|
||||
# gamma users by default do not have access to this dataset
|
||||
assert rv.status_code == 404
|
||||
assert rv.status_code == 401
|
||||
|
||||
@unittest.skip("Number of related objects depend on DB")
|
||||
@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
|
||||
|
|
|
@ -434,9 +434,7 @@ class TestSavedQueryApi(SupersetTestCase):
|
|||
rv = self.get_assert_metric(uri, "info")
|
||||
data = json.loads(rv.data.decode("utf-8"))
|
||||
assert rv.status_code == 200
|
||||
assert "can_read" in data["permissions"]
|
||||
assert "can_write" in data["permissions"]
|
||||
assert len(data["permissions"]) == 2
|
||||
assert set(data["permissions"]) == {"can_read", "can_write", "can_export"}
|
||||
|
||||
def test_related_saved_query(self):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue