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)
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)) )
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
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
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), ) )
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), ))
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) }
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), ))
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), ))
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]), ))
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
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") }
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
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) }