import { isArray, isObject, isFunction, isString, has } from 'lodash';
import globalRootStore from 'stores/root';
export const policyMap = {
nova: ['os_compute_api'],
ironic: ['baremetal:'],
cinder: [
'volume:',
'volume_extension',
'backup:get',
'backup:restore',
'scheduler_extension',
],
glance: [
'get_image',
'add_image',
'delete_image',
'modify_image',
'get_members',
'add_member',
'delete_member',
'metadef',
],
neutron: [
'get_network',
'create_network',
'update_network',
'delete_network',
'get_agent',
'delete_agent',
'update_agent',
'get_dhcp-agents',
'get_l3-agents',
'create_subnet',
'get_subnet',
'update_subnet',
'delete_subnet',
'create_port',
'get_port',
'update_port',
'delete_port',
'router',
'policy_bandwidth_limit_rule',
'policy_dscp_marking_rule',
'security_group',
'floatingip',
'vpnservice',
'ipsec_site_connection',
'rbac_policy',
],
octavia: ['os_load-balancer_api'],
heat: ['stacks:', 'resource:index'],
magnum: ['cluster:', 'clustertemplate:'],
barbican: [
'secret:get',
'secret:decrypt',
'secret:delete',
'containers:post',
'secrets:post',
'orders:post',
],
zun: ['capsule:', 'container:', 'host:get'],
manila: ['share:', 'share_', 'scheduler_stats:pools'],
trove: [
'instance:create',
'instance:delete',
'instance:update',
'instance:backups',
'instance:restart',
'instance:resize',
'instance:extension',
'instance:guest_log_list',
'configuration:',
'backup:index',
'backup:show',
],
};
export const convertPolicyMap = (map) => {
const newObj = {};
Object.entries(map).forEach(([key, value]) => {
value.forEach((v) => {
if (newObj[v]) {
console.log('policy rule prefix is repeat', `${newObj[v]}:${key}`);
}
newObj[v] = key;
});
});
return newObj;
};
export const changeToActualPolicy = (rule, map) => {
const policies = convertPolicyMap(map);
if (policies[rule]) {
return `${policies[rule]}:${rule}`;
}
const item = Object.keys(policies).filter((key) => {
return rule.includes(key);
});
if (item.length > 1) {
item.forEach((key) => {
console.log(
'policy rule prefix is conflict or repeat',
`${policies[key]}:${rule}`
);
});
}
const prefix = item.length && policies[item[0]];
return prefix ? `${prefix}:${rule}` : rule;
};
export const checkPolicyRule = (rule, actionName, isAliasPolicy) => {
if (!rule) {
return true;
}
const actualRule = isAliasPolicy
? rule
: changeToActualPolicy(rule, policyMap);
const item = globalRootStore.policies.find((it) => it.rule === actualRule);
if (!item) {
console.log('policy rule not exit', actualRule, actionName);
}
return item ? item.allowed : true;
};
const checkPolicyRules = (rules, every, actionName, isAliasPolicy) => {
if (rules.length === 0) {
return true;
}
if (every) {
return rules.every((rule) =>
checkPolicyRule(rule, actionName, isAliasPolicy)
);
}
return rules.some((rule) => checkPolicyRule(rule, actionName, isAliasPolicy));
};
export const systemRoleIsReader = () => {
const { roles = [] } = globalRootStore.user || {};
const readerRole = 'reader';
const adminRoles = ['admin'];
const hasReaderRole = roles.some((it) => it.name === readerRole);
if (!hasReaderRole) {
return false;
}
const hasAdminRole = roles.some((it) => adminRoles.includes(it.name));
return hasReaderRole && !hasAdminRole;
};
const checkItemPolicy = ({
policy,
aliasPolicy,
item,
actionName,
isAdminPage,
enableSystemReader,
}) => {
if (globalRootStore.policies.length === 0) {
return false;
}
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
return false;
}
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
return false;
}
if (!policy && !aliasPolicy) {
console.log('has no policy', policy, item, actionName);
return true;
}
const usePolicy = aliasPolicy || policy;
const itemPolicy = isFunction(usePolicy) ? usePolicy(item) : usePolicy;
let rules = [];
let every = true;
if (isArray(itemPolicy)) {
rules = itemPolicy;
} else if (isObject(itemPolicy)) {
rules = itemPolicy.rules;
if (has(itemPolicy, 'every')) {
every = itemPolicy.every;
}
} else if (isString(itemPolicy)) {
rules = [itemPolicy];
}
if (!rules) {
console.log('has no rules', usePolicy, item, actionName, rules);
return true;
}
return checkPolicyRules(rules, every, actionName, !!aliasPolicy);
};
export default checkItemPolicy;
export const allCanReadPolicy = {
rules: ['admin', 'reader', 'member'],
every: false,
};
export const allCanChangePolicy = {
rules: ['admin', 'member'],
every: false,
};
export const onlyAdminCanReadPolicy = {
rules: ['admin', 'reader'],
every: false,
};
export const onlyAdminCanChangePolicy = {
rules: ['admin'],
every: false,
};
export const checkSystemAdmin = () => {
return globalRootStore.hasAdminRole;
};