Beispiel #1
0
    def raise_for_dashboard_access(self, dashboard: "Dashboard") -> None:
        """
        Raise an exception if the user cannot access the dashboard.
        This does not check for the required role/permission pairs,
        it only concerns itself with entity relationships.

        :param dashboard: Dashboard the user wants access to
        :raises DashboardAccessDeniedError: If the user cannot access the resource
        """
        # pylint: disable=import-outside-toplevel
        from superset import is_feature_enabled
        from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
        from superset.views.base import is_user_admin
        from superset.views.utils import is_owner

        def has_rbac_access() -> bool:
            return (not is_feature_enabled("DASHBOARD_RBAC")) or any(
                dashboard_role.id in
                [user_role.id for user_role in self.get_user_roles()]
                for dashboard_role in dashboard.roles)

        if self.is_guest_user():
            can_access = self.has_guest_access(
                GuestTokenResourceType.DASHBOARD, dashboard.id)
        else:
            can_access = (is_user_admin() or is_owner(dashboard, g.user)
                          or (dashboard.published and has_rbac_access())
                          or (not dashboard.published and not dashboard.roles))

        if not can_access:
            raise DashboardAccessDeniedError()
Beispiel #2
0
    def raise_for_dashboard_access(dashboard: "Dashboard") -> None:
        """
        Raise an exception if the user cannot access the dashboard.

        :param dashboard: Dashboard the user wants access to
        :raises DashboardAccessDeniedError: If the user cannot access the resource
        """
        # pylint: disable=import-outside-toplevel
        from superset import is_feature_enabled
        from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
        from superset.views.base import get_user_roles, is_user_admin
        from superset.views.utils import is_owner

        has_rbac_access = True

        if is_feature_enabled("DASHBOARD_RBAC"):
            has_rbac_access = any(
                dashboard_role.id in [user_role.id for user_role in get_user_roles()]
                for dashboard_role in dashboard.roles
            )

        can_access = (
            is_user_admin()
            or is_owner(dashboard, g.user)
            or (dashboard.published and has_rbac_access)
            or (not dashboard.published and not dashboard.roles)
        )

        if not can_access:
            raise DashboardAccessDeniedError()
Beispiel #3
0
    def apply(self, query: Query, value: Any) -> Query:
        if is_user_admin():
            return query

        datasource_perms = security_manager.user_view_menu_names(
            "datasource_access")
        schema_perms = security_manager.user_view_menu_names("schema_access")

        is_rbac_disabled_filter = []
        dashboard_has_roles = Dashboard.roles.any()
        if is_feature_enabled("DASHBOARD_RBAC"):
            is_rbac_disabled_filter.append(~dashboard_has_roles)

        datasource_perm_query = (db.session.query(Dashboard.id).join(
            Dashboard.slices).filter(
                and_(
                    Dashboard.published.is_(True),
                    *is_rbac_disabled_filter,
                    or_(
                        Slice.perm.in_(datasource_perms),
                        Slice.schema_perm.in_(schema_perms),
                        security_manager.can_access_all_datasources(),
                    ),
                )))

        users_favorite_dash_query = db.session.query(FavStar.obj_id).filter(
            and_(
                FavStar.user_id == security_manager.user_model.get_user_id(),
                FavStar.class_name == "Dashboard",
            ))
        owner_ids_query = (db.session.query(Dashboard.id).join(
            Dashboard.owners).filter(
                security_manager.user_model.id ==
                security_manager.user_model.get_user_id()))

        dashboard_rbac_or_filters = []
        if is_feature_enabled("DASHBOARD_RBAC"):
            roles_based_query = (db.session.query(Dashboard.id).join(
                Dashboard.roles).filter(
                    and_(
                        Dashboard.published.is_(True),
                        dashboard_has_roles,
                        Role.id.in_([x.id for x in get_user_roles()]),
                    ), ))

            dashboard_rbac_or_filters.append(
                Dashboard.id.in_(roles_based_query))

        query = query.filter(
            or_(
                Dashboard.id.in_(owner_ids_query),
                Dashboard.id.in_(datasource_perm_query),
                Dashboard.id.in_(users_favorite_dash_query),
                *dashboard_rbac_or_filters,
            ))

        return query
Beispiel #4
0
def raise_for_dashboard_access(dashboard: Dashboard) -> None:
    from superset.views.base import get_user_roles, is_user_admin
    from superset.views.utils import is_owner

    if is_feature_enabled("DASHBOARD_RBAC"):
        has_rbac_access = any(dashboard_role.id in
                              [user_role.id for user_role in get_user_roles()]
                              for dashboard_role in dashboard.roles)
        can_access = (is_user_admin() or is_owner(dashboard, g.user)
                      or (dashboard.published and has_rbac_access))

        if not can_access:
            raise DashboardAccessDeniedError()
Beispiel #5
0
def check_access(dataset_id: int, chart_id: Optional[int],
                 actor: User) -> None:
    check_dataset_access(dataset_id)
    if not chart_id:
        return
    chart = ChartDAO.find_by_id(chart_id)
    if chart:
        can_access_chart = (is_user_admin() or is_owner(chart, actor)
                            or security_manager.can_access(
                                "can_read", "Chart"))
        if can_access_chart:
            return
        raise ChartAccessDeniedError()
    raise ChartNotFoundError()
Beispiel #6
0
    def apply(self, query: Query, value: Any) -> Query:
        if is_user_admin():
            return query
        current_user_id = g.user.id

        filter_set_ids_by_dashboard_owners = (  # pylint: disable=C0103
            query.from_self(FilterSet.id).join(
                dashboard_user,
                FilterSet.owner_id == dashboard_user.c.dashboard_id).filter(
                    and_(
                        FilterSet.owner_type == DASHBOARD_OWNER_TYPE,
                        dashboard_user.c.user_id == current_user_id,
                    )))

        return query.filter(
            or_(
                and_(
                    FilterSet.owner_type == USER_OWNER_TYPE,
                    FilterSet.owner_id == current_user_id,
                ),
                FilterSet.id.in_(filter_set_ids_by_dashboard_owners),
            ))
Beispiel #7
0
    def apply(self, query: Query, value: Any) -> Query:
        if is_user_admin():
            return query

        datasource_perms = security_manager.user_view_menu_names(
            "datasource_access")
        schema_perms = security_manager.user_view_menu_names("schema_access")
        published_dash_query = (
            db.session.query(Dashboard.id).join(Dashboard.slices).filter(
                and_(
                    Dashboard.published == True,  # pylint: disable=singleton-comparison
                    or_(
                        Slice.perm.in_(datasource_perms),
                        Slice.schema_perm.in_(schema_perms),
                        security_manager.can_access_all_datasources(),
                    ),
                )))

        users_favorite_dash_query = db.session.query(FavStar.obj_id).filter(
            and_(
                FavStar.user_id == security_manager.user_model.get_user_id(),
                FavStar.class_name == "Dashboard",
            ))
        owner_ids_query = (db.session.query(Dashboard.id).join(
            Dashboard.owners).filter(
                security_manager.user_model.id ==
                security_manager.user_model.get_user_id()))

        query = query.filter(
            or_(
                Dashboard.id.in_(owner_ids_query),
                Dashboard.id.in_(published_dash_query),
                Dashboard.id.in_(users_favorite_dash_query),
            ))

        return query
Beispiel #8
0
    def apply(self, query: Query, value: Any) -> Query:
        if is_user_admin():
            return query

        datasource_perms = security_manager.user_view_menu_names(
            "datasource_access")
        schema_perms = security_manager.user_view_menu_names("schema_access")

        is_rbac_disabled_filter = []
        dashboard_has_roles = Dashboard.roles.any()
        if is_feature_enabled("DASHBOARD_RBAC"):
            is_rbac_disabled_filter.append(~dashboard_has_roles)

        datasource_perm_query = (db.session.query(Dashboard.id).join(
            Dashboard.slices).filter(
                and_(
                    Dashboard.published.is_(True),
                    *is_rbac_disabled_filter,
                    or_(
                        Slice.perm.in_(datasource_perms),
                        Slice.schema_perm.in_(schema_perms),
                        security_manager.can_access_all_datasources(),
                    ),
                )))

        users_favorite_dash_query = db.session.query(FavStar.obj_id).filter(
            and_(
                FavStar.user_id == security_manager.user_model.get_user_id(),
                FavStar.class_name == "Dashboard",
            ))
        owner_ids_query = (db.session.query(Dashboard.id).join(
            Dashboard.owners).filter(
                security_manager.user_model.id ==
                security_manager.user_model.get_user_id()))

        feature_flagged_filters = []
        if is_feature_enabled("DASHBOARD_RBAC"):
            roles_based_query = (db.session.query(Dashboard.id).join(
                Dashboard.roles).filter(
                    and_(
                        Dashboard.published.is_(True),
                        dashboard_has_roles,
                        Role.id.in_(
                            [x.id for x in security_manager.get_user_roles()]),
                    ), ))

            feature_flagged_filters.append(Dashboard.id.in_(roles_based_query))

        if is_feature_enabled("EMBEDDED_SUPERSET"
                              ) and security_manager.is_guest_user(g.user):

            guest_user: GuestUser = g.user
            embedded_dashboard_ids = [
                r["id"] for r in guest_user.resources
                if r["type"] == GuestTokenResourceType.DASHBOARD.value
            ]

            # TODO (embedded): only use uuid filter once uuids are rolled out
            condition = (Dashboard.embedded.any(
                EmbeddedDashboard.uuid.in_(embedded_dashboard_ids)) if any(
                    is_uuid(id_) for id_ in embedded_dashboard_ids) else
                         Dashboard.id.in_(embedded_dashboard_ids))

            feature_flagged_filters.append(condition)

        query = query.filter(
            or_(
                Dashboard.id.in_(owner_ids_query),
                Dashboard.id.in_(datasource_perm_query),
                Dashboard.id.in_(users_favorite_dash_query),
                *feature_flagged_filters,
            ))

        return query