예제 #1
0
    def get_user_datasources(cls, session: Session) -> List["BaseDatasource"]:
        from superset import security_manager

        # collect datasources which the user has explicit permissions to
        user_perms = security_manager.user_view_menu_names("datasource_access")
        schema_perms = security_manager.user_view_menu_names("schema_access")
        user_datasources = set()
        for datasource_class in ConnectorRegistry.sources.values():
            user_datasources.update(
                session.query(datasource_class).filter(
                    or_(
                        datasource_class.perm.in_(user_perms),
                        datasource_class.schema_perm.in_(schema_perms),
                    )).all())

        # group all datasources by database
        all_datasources = cls.get_all_datasources(session)
        datasources_by_database: Dict["Database",
                                      Set["BaseDatasource"]] = defaultdict(set)
        for datasource in all_datasources:
            datasources_by_database[datasource.database].add(datasource)

        # add datasources with implicit permission (eg, database access)
        for database, datasources in datasources_by_database.items():
            if security_manager.can_access_database(database):
                user_datasources.update(datasources)

        return list(user_datasources)
예제 #2
0
 def apply(self, query: Query, value: Any) -> Query:
     if security_manager.can_access_all_datasources():
         return query
     perms = security_manager.user_view_menu_names("datasource_access")
     schema_perms = security_manager.user_view_menu_names("schema_access")
     return query.filter(
         or_(self.model.perm.in_(perms), self.model.schema_perm.in_(schema_perms))
     )
예제 #3
0
    def apply(self, query: Query, value: Any) -> Query:
        user_roles = [role.name.lower() for role in list(get_user_roles())]
        if "admin" in user_roles:
            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()
            )
        )
        
        if "custom" in user_roles:
            query = query.filter(
                and_(
                    Dashboard.id.in_(owner_ids_query),
                )
            )
            return query

        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
예제 #4
0
파일: filters.py 프로젝트: zxf033/superset
    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
예제 #5
0
 def apply(self, query, value):
     if security_manager.all_datasource_access():
         return query
     datasource_perms = security_manager.user_view_menu_names("datasource_access")
     schema_perms = security_manager.user_view_menu_names("schema_access")
     return query.filter(
         or_(
             self.model.perm.in_(datasource_perms),
             self.model.schema_perm.in_(schema_perms),
         )
     )
예제 #6
0
 def apply(self, query: Query, value: Any) -> Query:
     if security_manager.can_access_all_datasources():
         return query
     perms = security_manager.user_view_menu_names("datasource_access")
     schema_perms = security_manager.user_view_menu_names("schema_access")
     owner_ids_query = (db.session.query(models.SqlaTable.id).join(
         models.SqlaTable.owners).filter(
             security_manager.user_model.id ==
             security_manager.user_model.get_user_id()))
     return query.filter(
         or_(
             self.model.perm.in_(perms),
             self.model.schema_perm.in_(schema_perms),
             models.SqlaTable.id.in_(owner_ids_query),
         ))
예제 #7
0
 def can_access_databases(  # noqa pylint: disable=no-self-use
     self,
     view_menu_name: str,
 ) -> Set[str]:
     return {
         security_manager.unpack_database_and_schema(vm).database
         for vm in security_manager.user_view_menu_names(view_menu_name)
     }
예제 #8
0
 def apply(self, query: Query, value: Any) -> Query:
     if security_manager.all_database_access():
         return query
     database_perms = security_manager.user_view_menu_names(
         "database_access")
     # TODO(bogdan): consider adding datasource access here as well.
     schema_access_databases = self.schema_access_databases()
     return query.filter(
         or_(
             self.model.perm.in_(database_perms),
             self.model.database_name.in_(schema_access_databases),
         ))
예제 #9
0
 def apply(self, query, func):  # noqa pylint: disable=unused-argument,arguments-differ
     if security_manager.all_database_access():
         return query
     database_perms = security_manager.user_view_menu_names(
         "database_access")
     # TODO(bogdan): consider adding datasource access here as well.
     schema_access_databases = self.schema_access_databases()
     return query.filter(
         or_(
             self.model.perm.in_(database_perms),
             self.model.database_name.in_(schema_access_databases),
         ))
예제 #10
0
    def apply(self, query: Query, value: Any) -> Query:
        if security_manager.can_access_all_databases():
            return query
        database_perms = security_manager.user_view_menu_names(
            "database_access")
        schema_access_databases = can_access_databases("schema_access")

        datasource_access_databases = can_access_databases("datasource_access")

        return query.filter(
            or_(
                self.model.perm.in_(database_perms),
                self.model.database_name.in_(
                    [*schema_access_databases, *datasource_access_databases]),
            ))
예제 #11
0
    def apply(self, query: Query, value: Any) -> Query:
        if security_manager.is_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, isouter=True).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 == get_user_id(),
                FavStar.class_name == "Dashboard",
            ))
        owner_ids_query = (db.session.query(Dashboard.id).join(
            Dashboard.owners).filter(
                security_manager.user_model.id == 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
예제 #12
0
 def schema_access_databases(self) -> Set[str]:  # noqa pylint: disable=no-self-use
     return {
         security_manager.unpack_schema_perm(vm)[0]
         for vm in security_manager.user_view_menu_names("schema_access")
     }
예제 #13
0
 def schema_access_databases(self):  # noqa pylint: disable=no-self-use
     found_databases = set()
     for vm in security_manager.user_view_menu_names("schema_access"):
         database_name, _ = security_manager.unpack_schema_perm(vm)
         found_databases.add(database_name)
     return found_databases
예제 #14
0
def can_access_databases(view_menu_name: str, ) -> Set[str]:
    return {
        security_manager.unpack_database_and_schema(vm).database
        for vm in security_manager.user_view_menu_names(view_menu_name)
    }