UNPKG

@backstage-community/plugin-rbac-backend

Version:
133 lines (129 loc) 4.26 kB
'use strict'; 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