@backstage-community/plugin-rbac-backend
Version:
143 lines (139 loc) • 5.08 kB
JavaScript
;
var errors = require('@backstage/errors');
var pluginRbacCommon = require('@backstage-community/plugin-rbac-common');
var helper = require('../helper.cjs.js');
var adminCreation = require('../admin-permissions/admin-creation.cjs.js');
var policiesValidation = require('../validation/policies-validation.cjs.js');
const DEFAULT_ROLE_DESCRIPTION = "Role with default permissions for all users and groups.";
const DEFAULT_PERMISSIONS_CONF = "permission.rbac.defaultPermissions";
class DefaultPermissionsReader {
constructor(config) {
this.config = config;
}
readRole() {
const defPermissionsConfig = this.config.getOptionalConfig(
DEFAULT_PERMISSIONS_CONF
);
let role;
if (defPermissionsConfig) {
role = defPermissionsConfig.getOptionalString("defaultRole");
if (!role) {
throw new errors.InputError(
"Default role is mandatory for defaultPermissions configuration. Please set a valid default role in the configuration."
);
}
const validationError = policiesValidation.validateEntityReference(role, true);
if (validationError) {
throw new errors.InputError(
`Invalid default role '${role}': ${validationError.message}`
);
}
}
return role;
}
readPolicies() {
const defPermissionsConfig = this.config.getOptionalConfig(
DEFAULT_PERMISSIONS_CONF
);
const role = this.readRole();
let policies = [];
if (defPermissionsConfig) {
const basicPermissions = defPermissionsConfig.getOptionalConfigArray("basicPermissions");
if (!basicPermissions || basicPermissions.length === 0) {
throw new errors.InputError(
`The default role '${role}' requires at least one entry in permission.rbac.defaultPermissions.basicPermissions.`
);
}
policies = basicPermissions.map((permission) => {
const permissionName = permission.getString("permission");
const action = permission.getOptionalString("action");
if (action && !pluginRbacCommon.isValidPermissionAction(action)) {
throw new errors.InputError(
`Invalid action '${action}' for permission '${permissionName}'.`
);
}
return {
entityReference: role,
permission: permissionName,
policy: action || "use",
effect: "allow"
};
});
policies.forEach((policy) => {
const validationError = policiesValidation.validatePolicy(policy);
if (validationError) {
throw new errors.InputError(
`Invalid default permission policy for role '${role}': ${validationError.message}`
);
}
});
}
return policies;
}
}
class DefaultPermissionsSyncher {
constructor(roleMetadataStorage, enforcer, defaultPermissionsReader) {
this.roleMetadataStorage = roleMetadataStorage;
this.enforcer = enforcer;
this.defaultPermissionsReader = defaultPermissionsReader;
}
async sync() {
const policies = this.defaultPermissionsReader.readPolicies();
const roleEntityRef = this.defaultPermissionsReader.readRole();
const prevDefRole = await this.roleMetadataStorage.getDefaultRole();
const err = await policiesValidation.validateSource("configuration", prevDefRole);
if (err) {
throw new Error(
`Detected previous default role with incompatible source: ${err.message}`
);
}
if (!roleEntityRef) {
if (prevDefRole) {
const pls = await this.enforcer.getFilteredPolicy(
0,
prevDefRole.roleEntityRef
);
if (pls.length > 0) {
await this.enforcer.removePolicies(pls);
}
await this.roleMetadataStorage.removeRoleMetadata(
prevDefRole.roleEntityRef
);
}
return;
}
if (prevDefRole && prevDefRole.roleEntityRef !== roleEntityRef) {
const oldPolicies = await this.enforcer.getFilteredPolicy(
0,
prevDefRole.roleEntityRef
);
if (oldPolicies.length > 0) {
await this.enforcer.removePolicies(oldPolicies);
}
}
const casbinPolicies = policies.map((p) => [
p.entityReference,
p.permission,
p.policy,
p.effect
]);
await this.roleMetadataStorage.syncDefaultRoleMetadata(roleEntityRef);
await helper.syncRolePolicies(this.enforcer, roleEntityRef, casbinPolicies);
}
}
function buildDefaultRoleMetadata(defaultRoleRef) {
return {
roleEntityRef: defaultRoleRef,
author: adminCreation.ADMIN_ROLE_AUTHOR,
source: "configuration",
isDefault: true,
description: DEFAULT_ROLE_DESCRIPTION,
modifiedBy: adminCreation.ADMIN_ROLE_AUTHOR,
lastModified: (/* @__PURE__ */ new Date()).toUTCString(),
createdAt: (/* @__PURE__ */ new Date()).toUTCString()
};
}
exports.DefaultPermissionsReader = DefaultPermissionsReader;
exports.DefaultPermissionsSyncher = DefaultPermissionsSyncher;
exports.buildDefaultRoleMetadata = buildDefaultRoleMetadata;
//# sourceMappingURL=default-permissions.cjs.js.map