@backstage-community/plugin-rbac-backend
Version:
133 lines (129 loc) • 4.26 kB
JavaScript
;
var urlReader = require('@backstage/backend-defaults/urlReader');
var errors = require('@backstage/errors');
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
var pluginRbacCommon = require('@backstage-community/plugin-rbac-common');
require('../permissions/conditions.cjs.js');
var rules = require('../permissions/rules.cjs.js');
const rbacPermissionMetadata = {
permissions: pluginRbacCommon.policyEntityPermissions,
rules: [rules.rbacRules]
};
class PluginPermissionMetadataCollector {
pluginIdProvider;
discovery;
logger;
urlReader;
constructor({
deps,
optional
}) {
const { discovery, logger, config, pluginIdProvider } = deps;
this.discovery = discovery;
this.pluginIdProvider = pluginIdProvider;
this.logger = logger;
this.urlReader = optional?.urlReader ?? urlReader.UrlReaders.default({
config,
logger,
factories: [PluginPermissionMetadataCollector.permissionFactory]
});
}
async getPluginConditionRules(auth) {
const pluginMetadata = await this.getPluginMetaData(auth);
return pluginMetadata.filter((metadata) => metadata.metaDataResponse.rules.length > 0).map((metadata) => {
return {
pluginId: metadata.pluginId,
rules: metadata.metaDataResponse.rules
};
});
}
async getPluginPolicies(auth) {
const pluginMetadata = await this.getPluginMetaData(auth);
return pluginMetadata.filter((metadata) => metadata.metaDataResponse.permissions !== undefined).map((metadata) => {
return {
pluginId: metadata.pluginId,
policies: permissionsToCasbinPolicies(
metadata.metaDataResponse.permissions
)
};
});
}
static permissionFactory = () => {
return [{ reader: new urlReader.FetchUrlReader(), predicate: (_url) => true }];
};
async getPluginMetaData(auth) {
let pluginResponses = [];
const pluginIds = await this.pluginIdProvider.getPluginIds();
for (const pluginId of pluginIds) {
try {
const { token } = await auth.getPluginRequestToken({
onBehalfOf: await auth.getOwnServiceCredentials(),
targetPluginId: pluginId
});
const permMetaData = await this.getMetadataByPluginId(pluginId, token);
if (permMetaData) {
pluginResponses = [
...pluginResponses,
{
metaDataResponse: permMetaData,
pluginId
}
];
}
} catch (error) {
this.logger.error(
`Failed to retrieve permission metadata for ${pluginId}. ${error}`
);
}
}
return pluginResponses;
}
async getMetadataByPluginId(pluginId, token) {
let permMetaData;
if (pluginId === "permission") {
return rbacPermissionMetadata;
}
try {
const baseEndpoint = await this.discovery.getBaseUrl(pluginId);
const wellKnownURL = `${baseEndpoint}/.well-known/backstage/permissions/metadata`;
const permResp = await this.urlReader.readUrl(wellKnownURL, { token });
const permMetaDataRaw = (await permResp.buffer()).toString();
try {
permMetaData = JSON.parse(permMetaDataRaw);
} catch (err) {
return void 0;
}
} catch (err) {
if (errors.isError(err) && err.name === "NotFoundError") {
this.logger.warn(
`No permission metadata found for ${pluginId}. ${err}`
);
return undefined;
}
this.logger.error(
`Failed to retrieve permission metadata for ${pluginId}. ${err}`
);
}
return permMetaData;
}
}
function permissionsToCasbinPolicies(permissions) {
const policies = [];
for (const permission of permissions) {
if (pluginPermissionCommon.isResourcePermission(permission)) {
policies.push({
resourceType: permission.resourceType,
name: permission.name,
policy: permission.attributes.action || "use"
});
} else {
policies.push({
name: permission.name,
policy: permission.attributes.action || "use"
});
}
}
return policies;
}
exports.PluginPermissionMetadataCollector = PluginPermissionMetadataCollector;
//# sourceMappingURL=plugin-endpoints.cjs.js.map