UNPKG

@infosys_ltd/backstage-plugin-permission-backend-module-catalog-policy

Version:

The catalog-policy backend module for the permission plugin.

158 lines (151 loc) 5.23 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var errors = require('@backstage/errors'); var pluginPermissionCommon = require('@backstage/plugin-permission-common'); var backendPluginApi = require('@backstage/backend-plugin-api'); var alpha = require('@backstage/plugin-permission-node/alpha'); class openFgaPolicyEvaluator { static fromConfig(configApi, discoveryApi) { const baseUrl = configApi.getOptionalString("openfga.baseUrl") ?? ""; const storeId = configApi.getOptionalString("openfga.storeId") ?? ""; const authorizationModelId = configApi.getOptionalString("openfga.authorizationModelId") ?? ""; if (!storeId || !authorizationModelId) { console.error("Missing configuration values for OpenFGA. Please check your app-config.yaml."); } return new openFgaPolicyEvaluator({ discoveryApi, baseUrl, storeId, authorizationModelId }); } constructor(opts) { this.discoveryApi = opts.discoveryApi; this.baseUrl = opts.baseUrl; this.storeId = opts.storeId; this.authorizationModelId = opts.authorizationModelId; this.permissionResponse = null; } getPermissionResponse() { return this.permissionResponse; } async fetch(input, init) { const apiUrl = `${this.baseUrl}${input}`; const response = await fetch(apiUrl, init); if (!response.ok) { throw await errors.ResponseError.fromResponse(response); } return await response.json(); } async sendPermissionRequest(entityName, action, userName) { const url = `/stores/${this.storeId}/check`; const relation = typeof action === "string" && action.toLowerCase() === "delete" ? "catalog_entity_delete" : "catalog_entity_read"; const requestBody = { tuple_key: { user: `${userName}`, relation, object: `catalog_entity:${entityName}` }, authorization_model_id: this.authorizationModelId }; const response = await this.fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); this.permissionResponse = response; return response; } async addPolicy(entityName, accessType, userName) { const url = `/stores/${this.storeId}/write`; const requestBody = { writes: { tuple_keys: [ { user: `${userName}`, relation: accessType, object: `catalog_entity:${entityName}` } ] }, authorization_model_id: this.authorizationModelId }; const response = await this.fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); return response; } async revokePolicy(entityName, accessType, userName) { const url = `/stores/${this.storeId}/write`; const requestBody = { deletes: { tuple_keys: [ { user: `${userName}`, relation: accessType, object: `catalog_entity:${entityName}` } ] }, authorization_model_id: this.authorizationModelId }; const response = await this.fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); return response; } } class OpenFgaCatalogPolicy { constructor(configApi, discoveryApi) { this.openFgaClient = openFgaPolicyEvaluator.fromConfig( configApi, discoveryApi ); } async handle(request, user) { const identityUser = user; if (pluginPermissionCommon.isResourcePermission(request.permission, "catalog-entity")) { if (request.permission.name === "catalog.entity.delete") { const entityName = "example-website"; const userName = identityUser?.identity.ownershipEntityRefs; try { const response = await this.openFgaClient.sendPermissionRequest( entityName, "Delete", userName ); return response.allowed ? { result: pluginPermissionCommon.AuthorizeResult.ALLOW } : { result: pluginPermissionCommon.AuthorizeResult.DENY }; } catch (error) { console.error("Error checking permission:", error); return { result: pluginPermissionCommon.AuthorizeResult.DENY }; } } return { result: pluginPermissionCommon.AuthorizeResult.ALLOW }; } return { result: pluginPermissionCommon.AuthorizeResult.DENY }; } } const permissionModuleCatalogPolicy = backendPluginApi.createBackendModule({ pluginId: "permission", moduleId: "catalog-policy", register(reg) { reg.registerInit({ deps: { config: backendPluginApi.coreServices.rootConfig, policy: alpha.policyExtensionPoint, discovery: backendPluginApi.coreServices.discovery }, async init({ config, policy, discovery }) { policy.setPolicy(new OpenFgaCatalogPolicy(config, discovery)); } }); } }); exports.OpenFgaCatalogPolicy = OpenFgaCatalogPolicy; exports.default = permissionModuleCatalogPolicy; exports.openFgaPolicyEvaluator = openFgaPolicyEvaluator; //# sourceMappingURL=index.cjs.js.map