@backstage-community/plugin-rbac-backend
Version:
152 lines (148 loc) • 5.42 kB
JavaScript
;
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