UNPKG

@backstage-community/plugin-rbac-backend

Version:
152 lines (148 loc) 5.42 kB
'use strict'; var errors = require('@backstage/errors'); var helper = require('../helper.cjs.js'); var defaultPermissions = require('../default-permissions/default-permissions.cjs.js'); var policiesValidation = require('../validation/policies-validation.cjs.js'); const ROLE_METADATA_TABLE = "role-metadata"; class DataBaseRoleMetadataStorage { constructor(knex) { this.knex = knex; } cachedDefaultRoleMeta; async filterRoleMetadata(source) { return await this.knex.table(ROLE_METADATA_TABLE).where((builder) => { if (source) { builder.where("source", source); } }); } async syncDefaultRoleMetadata(actualDefRoleRef) { if (!actualDefRoleRef) { await this.knex(ROLE_METADATA_TABLE).where("isDefault", true).delete(); this.cachedDefaultRoleMeta = void 0; return; } await this.knex.transaction(async (trx) => { const currentDefaultRole = await this.getDefaultRole(trx); if (currentDefaultRole && currentDefaultRole.roleEntityRef !== actualDefRoleRef) { await trx(ROLE_METADATA_TABLE).where("isDefault", true).delete(); } const existing = await this.findRoleMetadata(actualDefRoleRef, trx); if (!existing) { const newDefaultRole = defaultPermissions.buildDefaultRoleMetadata(actualDefRoleRef); await this.createRoleMetadata(newDefaultRole, trx); } else { const err = await policiesValidation.validateSource("configuration", existing); if (err) { throw new Error( `Role '${actualDefRoleRef}' has incompatible source. Expected 'configuration' source value. Cause: ${err.message}` ); } } }); const row = await this.findRoleMetadata(actualDefRoleRef); this.cachedDefaultRoleMeta = row; } getCachedDefaultRoleMetadata() { return this.cachedDefaultRoleMeta; } async getDefaultRole(trx) { const db = trx || this.knex; return await db(ROLE_METADATA_TABLE).where("isDefault", true).first(); } async filterForOwnerRoleMetadata(filter) { const roleMetadata = await this.knex.table(ROLE_METADATA_TABLE); if (filter) { const ownerRoles = roleMetadata.filter((role) => { return helper.matches(role, filter); }); if (this.cachedDefaultRoleMeta) { const cachedDefault = this.cachedDefaultRoleMeta; const hasDefaultRole = ownerRoles.some( (role) => role.roleEntityRef === cachedDefault.roleEntityRef ); if (!hasDefaultRole) { ownerRoles.push(cachedDefault); } } return ownerRoles; } return roleMetadata; } async findRoleMetadata(roleEntityRef, trx) { const db = trx || this.knex; return await db.table(ROLE_METADATA_TABLE).where("roleEntityRef", roleEntityRef).first(); } async createRoleMetadata(metadata, trx) { if (await this.findRoleMetadata(metadata.roleEntityRef, trx)) { throw new errors.ConflictError( `A metadata for role ${metadata.roleEntityRef} has already been stored` ); } const result = await trx(ROLE_METADATA_TABLE).insert(metadata).returning("id"); if (result && result?.length > 0) { return result[0].id; } throw new Error( `Failed to create the role metadata: '${JSON.stringify(metadata)}'.` ); } async updateRoleMetadata(newRoleMetadata, oldRoleEntityRef, externalTrx) { const trx = externalTrx ?? await this.knex.transaction(); const currentMetadataDao = await this.findRoleMetadata( oldRoleEntityRef, trx ); if (!currentMetadataDao) { throw new errors.NotFoundError( `A metadata for role '${oldRoleEntityRef}' was not found` ); } if (currentMetadataDao.source !== "legacy" && currentMetadataDao.source !== newRoleMetadata.source) { throw new errors.InputError(`The RoleMetadata.source field is 'read-only'.`); } if (helper.deepSortedEqual(currentMetadataDao, newRoleMetadata)) { return; } const result = await trx(ROLE_METADATA_TABLE).where("id", currentMetadataDao.id).update(newRoleMetadata).returning("id"); if (!externalTrx) { await trx.commit(); } if (!result || result.length === 0) { throw new Error( `Failed to update the role metadata '${JSON.stringify( currentMetadataDao )}' with new value: '${JSON.stringify(newRoleMetadata)}'.` ); } } async removeRoleMetadata(roleEntityRef, externalTrx) { const trx = externalTrx ?? await this.knex.transaction(); const metadataDao = await this.findRoleMetadata(roleEntityRef, trx); if (!metadataDao) { throw new errors.NotFoundError( `A metadata for role '${roleEntityRef}' was not found` ); } await trx(ROLE_METADATA_TABLE).delete().whereIn("id", [metadataDao.id]); if (!externalTrx) { await trx.commit(); } } } function daoToMetadata(dao) { return { source: dao.source, description: dao.description, owner: dao.owner, author: dao.author, modifiedBy: dao.modifiedBy, createdAt: dao.createdAt, lastModified: dao.lastModified, isDefault: dao.isDefault === true || dao.isDefault === 1 ? true : false }; } exports.DataBaseRoleMetadataStorage = DataBaseRoleMetadataStorage; exports.ROLE_METADATA_TABLE = ROLE_METADATA_TABLE; exports.daoToMetadata = daoToMetadata; //# sourceMappingURL=role-metadata.cjs.js.map