in source/packages/services/assetlibrary/src/authz/authz.full.service.ts [28:107]
public async authorizationCheck(
deviceIds: string[],
groupPaths: string[],
accessLevelRequired: ClaimAccess
): Promise<void> {
logger.debug(
`authz.full.service authorizationCheck: in: deviceIds:${deviceIds}, groupPaths:${groupPaths}, accessLevelRequired:${accessLevelRequired}`
);
if (!this.isAuthzEnabled) {
logger.debug(`authz.full.service authorizationCheck: authz not enabled`);
return;
}
if (deviceIds === undefined || deviceIds === null) {
deviceIds = [];
}
if (groupPaths === undefined || groupPaths === null) {
groupPaths = [];
}
const combinedIds: string[] = [...new Set([...deviceIds, ...groupPaths])];
logger.debug(
`authz.full.service authorizationCheck: combinedIds:${JSON.stringify(combinedIds)}`
);
if (combinedIds.length === 0) {
return;
}
// retrieve the claims from the thread local
const claims = Claims.getInstance();
logger.debug(`authz.full.service authorizationCheck: claims: ${JSON.stringify(claims)}`);
// determine if the user has any access to provided ids via their allowed hierarchies
const authorizations = await this.dao.listAuthorizedHierarchies(
deviceIds,
groupPaths,
claims.listPaths()
);
const existsSet =
authorizations?.exists !== undefined ? new Set(authorizations.exists) : undefined;
// if one of the requested items is missing, we refuse the whole request
if ((existsSet?.size ?? 0) !== combinedIds.length) {
const notFound = combinedIds.filter((id) => !authorizations.exists.includes(id));
throw new NotFoundError(`Device(s)/group(s) ${JSON.stringify(notFound)} not found.`);
}
// if the user does not have access to all, then not authorized to any
const notAuthorized = Object.keys(authorizations.authorized).filter(
(k) => !combinedIds.includes(k)
);
if (notAuthorized.length > 0) {
throw new NotAuthorizedError(
`Access to ${JSON.stringify(notAuthorized)} not authorized.`
);
}
// even though the user has access to a hierarchy, need to ensure its the right level of access
const entitiesWithSufficientAccess: string[] = [];
for (const entityId of Object.keys(authorizations.authorized)) {
const paths = authorizations.authorized[entityId];
for (const path of paths) {
if (claims.hasAccessForPath(path, accessLevelRequired)) {
entitiesWithSufficientAccess.push(entityId);
break;
}
}
}
if (entitiesWithSufficientAccess.length !== combinedIds.length) {
logger.debug(`authz.full.service authorizationCheck: not authorized`);
throw new NotAuthorizedError(
`Insufficient access to ${JSON.stringify(entitiesWithSufficientAccess)}.`
);
}
logger.debug(`authz.full.service authorizationCheck: exit`);
}