# 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")
