import { getConfig } from '@/config/configuration' ; import { getEntityAccessControlCache } from '@/config/services' ; import ClusterAclsNotLoadedError from '@/model/errors/ClusterAclsNotLoadedError' ; import ClusterNotAuthorizedError from '@/model/errors/ClusterNotAuthorizedError' ; import EntityNotAuthorizedError from '@/model/errors/EntityNotAuthorizedError' ; import { getStore } from '@/model/store' ; import { EntityType } from '@/typings/enums' ; import { IClusterDefinition , IClusterOwnership , IClusterSummary , IEntityOwnership , } from '@/typings/typings' ; import { isClusterShared } from '@/utils/app-utils' ; import { isUserAuthorized } from '@/utils/user-utils' ; import { IRequestUserInfo } from '@sharedtypes/express' ; param user param cluster return throws throws export function canUserAccessCluster ( user , cluster ) { const { ALL_CLUSTERS_MEMBERS , CLUSTER_ACCESS_CONTROL_ENABLED , RESTRICTED_CLUSTERS , UNRESTRICTED_CLUSTERS , REQUIRE_AUTHENTICATION , } = getConfig ( ) ; const clusterName = cluster . name ; if ( ! REQUIRE_AUTHENTICATION || ! CLUSTER_ACCESS_CONTROL_ENABLED ) { return true ; } const clusterAclDef = getClusterAclDef ( clusterName ) ; if ( ! clusterAclDef ) { return false ; } const clusterAllowedGroups = new Array < string > ( ) . concat ( clusterAclDef . owners , ALL_CLUSTERS_MEMBERS ) ; const userAuthorized = isUserAuthorized ( user , clusterAllowedGroups ) ; const isClusterRestricted = RESTRICTED_CLUSTERS . includes ( clusterName . toLowerCase ( ) ) ; const isClusterUnrestricted = clusterAclDef . isShared || UNRESTRICTED_CLUSTERS . includes ( clusterName . toLowerCase ( ) ) ; return ( userAuthorized || isClusterUnrestricted ) && ! isClusterRestricted ; } param user param cluster param store export function verifyUserCanAccessCluster ( user , cluster ) { if ( ! canUserAccessCluster ( user , cluster ) ) { throw new ClusterNotAuthorizedError ( user . email , cluster ) ; } } param user param cluster param entityType param entityName param useLocalCacheOnly async function canUserAccessEntity ( user , cluster , entityType , entityName , useLocalCacheOnly = false ) { const { ALL_ENTITY_MEMBERS } = getConfig ( ) ; verifyUserCanAccessCluster ( user , cluster ) ; if ( ! isClusterShared ( cluster . name ) ) { return true ; } const ownership = await getEntityOwnership ( cluster . name , cluster . env , entityType , entityName , useLocalCacheOnly ) ; const owners = ownership ?. owners ?? [ ] ; const entityAllowedGroups = new Array < string > ( ) . concat ( owners , ALL_ENTITY_MEMBERS ) ; return isUserAuthorized ( user , entityAllowedGroups ) ; } param user param cluster param entityType param entityName param useLocalCacheOnly export async function verifyUserAccessEntity ( user , cluster , entityType , entityName , useLocalCacheOnly = false ) { try { const canAccess = await canUserAccessEntity ( user , cluster , entityType , entityName , useLocalCacheOnly ) ; if ( ! canAccess ) { throw new EntityNotAuthorizedError ( cluster , entityType , entityName ) ; } } catch ( err ) { throw err ; } } param user param entityTypes param entityNames export async function filterAccessibleEntities ( user , cluster , entityTypes , entityNames ) { await getEntityAccessControlCache ( ) . refresh ( ) ; const access = await Promise . all ( entityNames . map ( async ( entityName ) => await canUserAccessEntity ( user , cluster , entityTypes , entityName , true ) ) ) ; return new Set ( entityNames . filter ( ( name , index ) => access [ index ] ) ) ; } function getClusterAclDef ( clusterName ) { const { accessControl } = getStore ( ) ; const clusterAclMap = accessControl . clusterAclMap ; if ( ! clusterAclMap ) { throw new ClusterAclsNotLoadedError ( clusterName ) ; } return clusterAclMap [ clusterName . toLowerCase ( ) ] || undefined ; } /**
 * Fetches any defined entity ownership information for the specified cluster, type, and name.
 */ async function getEntityOwnership ( clusterName , env , entityType , entityName , useLocalCacheOnly ) { const cache = getEntityAccessControlCache ( ) ; const entity = useLocalCacheOnly ? await cache . getIfPresent ( clusterName , env , entityType , entityName ) : await cache . get ( clusterName , env , entityType , entityName ) ; return entity ; }