blob: 19885d9582320f44dc8cd292a244e77ce964b475 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Unit tests for Superset"""
from unittest import mock
import pytest
from tests.dashboards.dashboard_test_utils import *
from tests.dashboards.security.base_case import BaseTestDashboardSecurity
from tests.dashboards.superset_factory_util import (
create_dashboard_to_db,
create_database_to_db,
create_datasource_table_to_db,
create_slice_to_db,
)
from tests.fixtures.public_role import public_role_like_gamma
@mock.patch.dict(
"superset.extensions.feature_flag_manager._feature_flags", DASHBOARD_RBAC=True,
)
class TestDashboardRoleBasedSecurity(BaseTestDashboardSecurity):
def test_get_dashboard_view__admin_can_access(self):
# arrange
dashboard_to_access = create_dashboard_to_db(
owners=[], slices=[create_slice_to_db()], published=False
)
self.login("admin")
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert_dashboard_view_response(response, dashboard_to_access)
def test_get_dashboard_view__owner_can_access(self):
# arrange
username = random_str()
new_role = f"role_{random_str()}"
owner = self.create_user_with_roles(
username, [new_role], should_create_roles=True
)
dashboard_to_access = create_dashboard_to_db(
owners=[owner], slices=[create_slice_to_db()], published=False
)
self.login(username)
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert_dashboard_view_response(response, dashboard_to_access)
def test_get_dashboard_view__user_can_not_access_without_permission(self):
username = random_str()
new_role = f"role_{random_str()}"
self.create_user_with_roles(username, [new_role], should_create_roles=True)
dashboard_to_access = create_dashboard_to_db(published=True)
self.login(username)
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert403(response)
def test_get_dashboard_view__user_with_dashboard_permission_can_not_access_draft(
self,
):
# arrange
dashboard_to_access = create_dashboard_to_db(published=False)
username = random_str()
new_role = f"role_{random_str()}"
self.create_user_with_roles(username, [new_role], should_create_roles=True)
grant_access_to_dashboard(dashboard_to_access, new_role)
self.login(username)
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert403(response)
# post
revoke_access_to_dashboard(dashboard_to_access, new_role)
def test_get_dashboard_view__user_access_with_dashboard_permission(self):
# arrange
username = random_str()
new_role = f"role_{random_str()}"
self.create_user_with_roles(username, [new_role], should_create_roles=True)
dashboard_to_access = create_dashboard_to_db(
published=True, slices=[create_slice_to_db()]
)
self.login(username)
grant_access_to_dashboard(dashboard_to_access, new_role)
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert_dashboard_view_response(response, dashboard_to_access)
# post
revoke_access_to_dashboard(dashboard_to_access, new_role)
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboard_view__public_user_can_not_access_without_permission(self):
dashboard_to_access = create_dashboard_to_db(published=True)
self.logout()
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert403(response)
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboard_view__public_user_with_dashboard_permission_can_not_access_draft(
self,
):
# arrange
dashboard_to_access = create_dashboard_to_db(published=False)
grant_access_to_dashboard(dashboard_to_access, "Public")
self.logout()
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert403(response)
# post
revoke_access_to_dashboard(dashboard_to_access, "Public")
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboard_view__public_user_access_with_dashboard_permission(self):
# arrange
dashboard_to_access = create_dashboard_to_db(
published=True, slices=[create_slice_to_db()]
)
grant_access_to_dashboard(dashboard_to_access, "Public")
self.logout()
# act
response = self.get_dashboard_view_response(dashboard_to_access)
# assert
self.assert_dashboard_view_response(response, dashboard_to_access)
# post
revoke_access_to_dashboard(dashboard_to_access, "Public")
def test_get_dashboards_list__admin_get_all_dashboards(self):
# arrange
create_dashboard_to_db(
owners=[], slices=[create_slice_to_db()], published=False
)
dashboard_counts = count_dashboards()
self.login("admin")
# act
response = self.get_dashboards_list_response()
# assert
self.assert_dashboards_list_view_response(response, dashboard_counts)
def test_get_dashboards_list__owner_get_all_owned_dashboards(self):
# arrange
(
not_owned_dashboards,
owned_dashboards,
) = self._create_sample_dashboards_with_owner_access()
# act
response = self.get_dashboards_list_response()
# assert
self.assert_dashboards_list_view_response(
response, 2, owned_dashboards, not_owned_dashboards
)
def _create_sample_dashboards_with_owner_access(self):
username = random_str()
new_role = f"role_{random_str()}"
owner = self.create_user_with_roles(
username, [new_role], should_create_roles=True
)
database = create_database_to_db()
table = create_datasource_table_to_db(db_id=database.id, owners=[owner])
first_dash = create_dashboard_to_db(
owners=[owner], slices=[create_slice_to_db(datasource_id=table.id)]
)
second_dash = create_dashboard_to_db(
owners=[owner], slices=[create_slice_to_db(datasource_id=table.id)]
)
owned_dashboards = [first_dash, second_dash]
not_owned_dashboards = [
create_dashboard_to_db(
slices=[create_slice_to_db(datasource_id=table.id)], published=True
)
]
self.login(username)
return not_owned_dashboards, owned_dashboards
def test_get_dashboards_list__user_without_any_permissions_get_empty_list(self):
# arrange
username = random_str()
new_role = f"role_{random_str()}"
self.create_user_with_roles(username, [new_role], should_create_roles=True)
create_dashboard_to_db(published=True)
self.login(username)
# act
response = self.get_dashboards_list_response()
# assert
self.assert_dashboards_list_view_response(response, 0)
def test_get_dashboards_list__user_get_only_published_permitted_dashboards(self):
# arrange
(
new_role,
draft_dashboards,
published_dashboards,
) = self._create_sample_only_published_dashboard_with_roles()
# act
response = self.get_dashboards_list_response()
# assert
self.assert_dashboards_list_view_response(
response, len(published_dashboards), published_dashboards, draft_dashboards,
)
# post
for dash in published_dashboards + draft_dashboards:
revoke_access_to_dashboard(dash, new_role)
def _create_sample_only_published_dashboard_with_roles(self):
username = random_str()
new_role = f"role_{random_str()}"
self.create_user_with_roles(username, [new_role], should_create_roles=True)
published_dashboards = [
create_dashboard_to_db(published=True),
create_dashboard_to_db(published=True),
]
draft_dashboards = [
create_dashboard_to_db(published=False),
create_dashboard_to_db(published=False),
]
for dash in published_dashboards + draft_dashboards:
grant_access_to_dashboard(dash, new_role)
self.login(username)
return new_role, draft_dashboards, published_dashboards
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboards_list__public_user_without_any_permissions_get_empty_list(
self,
):
create_dashboard_to_db(published=True)
# act
response = self.get_dashboards_list_response()
# assert
self.assert_dashboards_list_view_response(response, 0)
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboards_list__public_user_get_only_published_permitted_dashboards(
self,
):
# arrange
published_dashboards = [
create_dashboard_to_db(published=True),
create_dashboard_to_db(published=True),
]
draft_dashboards = [
create_dashboard_to_db(published=False),
create_dashboard_to_db(published=False),
]
for dash in published_dashboards + draft_dashboards:
grant_access_to_dashboard(dash, "Public")
self.logout()
# act
response = self.get_dashboards_list_response()
# assert
self.assert_dashboards_list_view_response(
response, len(published_dashboards), published_dashboards, draft_dashboards,
)
# post
for dash in published_dashboards + draft_dashboards:
revoke_access_to_dashboard(dash, "Public")
def test_get_dashboards_api__admin_get_all_dashboards(self):
# arrange
create_dashboard_to_db(
owners=[], slices=[create_slice_to_db()], published=False
)
dashboard_counts = count_dashboards()
self.login("admin")
# act
response = self.get_dashboards_api_response()
# assert
self.assert_dashboards_api_response(response, dashboard_counts)
def test_get_dashboards_api__owner_get_all_owned_dashboards(self):
# arrange
(
not_owned_dashboards,
owned_dashboards,
) = self._create_sample_dashboards_with_owner_access()
# act
response = self.get_dashboards_api_response()
# assert
self.assert_dashboards_api_response(
response, 2, owned_dashboards, not_owned_dashboards
)
def test_get_dashboards_api__user_without_any_permissions_get_empty_list(self):
username = random_str()
new_role = f"role_{random_str()}"
self.create_user_with_roles(username, [new_role], should_create_roles=True)
create_dashboard_to_db(published=True)
self.login(username)
# act
response = self.get_dashboards_api_response()
# assert
self.assert_dashboards_api_response(response, 0)
def test_get_dashboards_api__user_get_only_published_permitted_dashboards(self):
(
new_role,
draft_dashboards,
published_dashboards,
) = self._create_sample_only_published_dashboard_with_roles()
# act
response = self.get_dashboards_api_response()
# assert
self.assert_dashboards_api_response(
response, len(published_dashboards), published_dashboards, draft_dashboards,
)
# post
for dash in published_dashboards + draft_dashboards:
revoke_access_to_dashboard(dash, new_role)
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboards_api__public_user_without_any_permissions_get_empty_list(
self,
):
create_dashboard_to_db(published=True)
self.logout()
# act
response = self.get_dashboards_api_response()
# assert
self.assert_dashboards_api_response(response, 0)
@pytest.mark.usefixtures("public_role_like_gamma")
def test_get_dashboards_api__public_user_get_only_published_permitted_dashboards(
self,
):
# arrange
published_dashboards = [
create_dashboard_to_db(published=True),
create_dashboard_to_db(published=True),
]
draft_dashboards = [
create_dashboard_to_db(published=False),
create_dashboard_to_db(published=False),
]
for dash in published_dashboards + draft_dashboards:
grant_access_to_dashboard(dash, "Public")
self.logout()
# act
response = self.get_dashboards_api_response()
# assert
self.assert_dashboards_api_response(
response, len(published_dashboards), published_dashboards, draft_dashboards,
)
# post
for dash in published_dashboards + draft_dashboards:
revoke_access_to_dashboard(dash, "Public")