fix: Fix system_reader role operation permission bug
1. Fix system_reader role has operation permissions on administrator page 2. Mark TODO of supported system scope roles Change-Id: Icd697e0b5238a25307c3d24fc6742600f892b547
This commit is contained in:
parent
ad94bb6345
commit
34c13a2dcb
@ -12,17 +12,26 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import checkItemPolicy from 'resources/policy';
|
||||
import checkItemPolicy, { systemRoleIsReader } from 'resources/policy';
|
||||
|
||||
export async function checkAllowed(
|
||||
export async function checkAllowed({
|
||||
item,
|
||||
policy,
|
||||
allowed,
|
||||
containerProps,
|
||||
actionName,
|
||||
extra
|
||||
) {
|
||||
const policyResult = checkItemPolicy(policy, item, actionName, extra);
|
||||
extra,
|
||||
isAdminPage,
|
||||
action,
|
||||
}) {
|
||||
const { enableSystemReader } = action || {};
|
||||
const policyResult = checkItemPolicy({
|
||||
policy,
|
||||
item,
|
||||
actionName,
|
||||
isAdminPage,
|
||||
enableSystemReader,
|
||||
});
|
||||
if (!policyResult) {
|
||||
return false;
|
||||
}
|
||||
@ -36,32 +45,38 @@ export async function checkAllowed(
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getAllowedResults(
|
||||
export async function getAllowedResults({
|
||||
actions,
|
||||
data,
|
||||
key,
|
||||
containerProps,
|
||||
extra
|
||||
) {
|
||||
extra,
|
||||
isAdminPage,
|
||||
}) {
|
||||
const allowedPromises = actions.map(async (it) => {
|
||||
const result = checkAllowed(
|
||||
data,
|
||||
key ? it[key].policy : it.policy,
|
||||
key ? it[key].allowed : it.allowed,
|
||||
const result = checkAllowed({
|
||||
item: data,
|
||||
policy: key ? it[key].policy : it.policy,
|
||||
allowed: key ? it[key].allowed : it.allowed,
|
||||
containerProps,
|
||||
key ? it[key].title : it.title,
|
||||
extra
|
||||
);
|
||||
actionName: key ? it[key].title : it.title,
|
||||
extra,
|
||||
isAdminPage,
|
||||
action: it.action,
|
||||
});
|
||||
return result;
|
||||
});
|
||||
const results = await Promise.all(allowedPromises);
|
||||
return results;
|
||||
}
|
||||
|
||||
export function getPolicyResults(actions, extra) {
|
||||
export function getPolicyResults({ actions, extra, isAdminPage }) {
|
||||
return actions.map((it) => {
|
||||
const { policy, title } = it;
|
||||
const result = checkItemPolicy(policy, null, title, extra);
|
||||
const { policy, title, enableSystemReader } = it;
|
||||
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
||||
return false;
|
||||
}
|
||||
const result = checkItemPolicy({ policy, actionName: title, extra });
|
||||
return result;
|
||||
});
|
||||
}
|
||||
@ -76,10 +91,10 @@ export function getAction(action, item, containerProps) {
|
||||
return action;
|
||||
}
|
||||
|
||||
export function getActionsByPolicy(actions, containerProps) {
|
||||
export function getActionsByPolicy({ actions, containerProps, isAdminPage }) {
|
||||
const actionList = actions.map((action) =>
|
||||
getAction(action, null, containerProps)
|
||||
);
|
||||
const policyResults = getPolicyResults(actionList);
|
||||
const policyResults = getPolicyResults({ actions: actionList, isAdminPage });
|
||||
return actionList.filter((it, index) => policyResults[index]);
|
||||
}
|
||||
|
@ -96,12 +96,17 @@ export default function TableBatchButtons(props) {
|
||||
onClickAction,
|
||||
onCancelAction,
|
||||
resourceName,
|
||||
isAdminPage,
|
||||
} = props;
|
||||
let moreButton = null;
|
||||
let batchButtons = null;
|
||||
let showedActions = [];
|
||||
let restActions = [];
|
||||
const actionList = getActionsByPolicy(batchActions, containerProps);
|
||||
const actionList = getActionsByPolicy({
|
||||
actions: batchActions,
|
||||
containerProps,
|
||||
isAdminPage,
|
||||
});
|
||||
if (visibleButtonNumber < actionList.length) {
|
||||
if (visibleButtonNumber < 0) {
|
||||
restActions = actionList;
|
||||
|
@ -288,7 +288,7 @@ export default class ItemActionButtons extends Component {
|
||||
}
|
||||
|
||||
async updateResult(item, containerProps) {
|
||||
const { actions } = this.props;
|
||||
const { actions, isAdminPage } = this.props;
|
||||
const { actionList, firstAction, moreActions } = getActionList(
|
||||
actions,
|
||||
item,
|
||||
@ -297,12 +297,13 @@ export default class ItemActionButtons extends Component {
|
||||
this.actionList = actionList;
|
||||
this.firstAction = firstAction;
|
||||
this.moreActions = moreActions;
|
||||
const results = await getAllowedResults(
|
||||
this.actionList,
|
||||
item,
|
||||
'action',
|
||||
containerProps
|
||||
);
|
||||
const results = await getAllowedResults({
|
||||
actions: this.actionList,
|
||||
data: item,
|
||||
key: 'action',
|
||||
containerProps,
|
||||
isAdminPage,
|
||||
});
|
||||
this.setState({
|
||||
results,
|
||||
});
|
||||
|
@ -62,15 +62,16 @@ export default class TablePrimaryButtons extends Component {
|
||||
}
|
||||
|
||||
async getActionsAllowed() {
|
||||
const { containerProps, primaryActionsExtra } = this.props;
|
||||
const { containerProps, primaryActionsExtra, isAdminPage } = this.props;
|
||||
const { detail = null } = containerProps;
|
||||
const results = await getAllowedResults(
|
||||
this.actionList,
|
||||
detail,
|
||||
null,
|
||||
const results = await getAllowedResults({
|
||||
actions: this.actionList,
|
||||
data: detail,
|
||||
containerProps,
|
||||
primaryActionsExtra
|
||||
);
|
||||
key: null,
|
||||
extra: primaryActionsExtra,
|
||||
isAdminPage,
|
||||
});
|
||||
this.setState({
|
||||
primaryAllowedResults: results,
|
||||
});
|
||||
|
@ -110,6 +110,7 @@ export default class BaseTable extends React.Component {
|
||||
hideTotal: false,
|
||||
hideDownload: false,
|
||||
primaryActionsExtra: null,
|
||||
isAdminPage: false,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
@ -472,6 +473,7 @@ export default class BaseTable extends React.Component {
|
||||
onClickAction,
|
||||
onFinishAction,
|
||||
onCancelAction,
|
||||
isAdminPage,
|
||||
} = this.props;
|
||||
const { hideRow } = this.state;
|
||||
const currentColumns = columns
|
||||
@ -489,6 +491,7 @@ export default class BaseTable extends React.Component {
|
||||
width: 150,
|
||||
render: (text, record, index) => (
|
||||
<ItemActionButtons
|
||||
isAdminPage={isAdminPage}
|
||||
actions={this.itemActions}
|
||||
onFinishAction={onFinishAction}
|
||||
onCancelAction={onCancelAction}
|
||||
@ -533,6 +536,7 @@ export default class BaseTable extends React.Component {
|
||||
onFinishAction,
|
||||
onCancelAction,
|
||||
resourceName,
|
||||
isAdminPage,
|
||||
} = this.props;
|
||||
const selectedItems = data.filter(
|
||||
(it) => selectedRowKeys.indexOf(it[rowKey]) >= 0
|
||||
@ -540,6 +544,7 @@ export default class BaseTable extends React.Component {
|
||||
if (batchActions) {
|
||||
return (
|
||||
<BatchActionButtons
|
||||
isAdminPage={isAdminPage}
|
||||
visibleButtonNumber={3}
|
||||
selectedItemKeys={selectedRowKeys}
|
||||
selectedItems={selectedItems}
|
||||
@ -639,6 +644,7 @@ export default class BaseTable extends React.Component {
|
||||
|
||||
renderActions() {
|
||||
const {
|
||||
isAdminPage,
|
||||
primaryActions,
|
||||
containerProps,
|
||||
onClickAction,
|
||||
@ -649,6 +655,7 @@ export default class BaseTable extends React.Component {
|
||||
if (primaryActions) {
|
||||
return (
|
||||
<PrimaryActionButtons
|
||||
isAdminPage={isAdminPage}
|
||||
primaryActions={primaryActions}
|
||||
containerProps={containerProps}
|
||||
onClickAction={onClickAction}
|
||||
|
@ -486,7 +486,7 @@ export default class BaseList extends React.Component {
|
||||
if (this.endpointError) {
|
||||
return;
|
||||
}
|
||||
if (!checkItemPolicy(this.policy, null, this.name)) {
|
||||
if (!checkItemPolicy({ policy: this.policy, actionName: this.name })) {
|
||||
const error = {
|
||||
message: t("You don't have access to get {name}.", {
|
||||
name: this.name.toLowerCase(),
|
||||
@ -988,6 +988,7 @@ export default class BaseList extends React.Component {
|
||||
hideTotal={this.hideTotal}
|
||||
hideDownload={this.hideDownload}
|
||||
primaryActionsExtra={this.primaryActionsExtra}
|
||||
isAdminPage={this.isAdminPage}
|
||||
{...this.getEnabledTableProps()}
|
||||
/>
|
||||
);
|
||||
|
@ -218,7 +218,7 @@ export default class DetailBase extends React.Component {
|
||||
getRouteProps = () => ({});
|
||||
|
||||
fetchDataWithPolicy = (silent, params) => {
|
||||
if (!checkItemPolicy(this.policy, null, this.name)) {
|
||||
if (!checkItemPolicy({ policy: this.policy, actionName: this.name })) {
|
||||
const error = {
|
||||
message: t("You don't have access to get {name}.", {
|
||||
name: this.name.toLowerCase(),
|
||||
@ -396,6 +396,7 @@ export default class DetailBase extends React.Component {
|
||||
onFinishAction={this.onFinishAction}
|
||||
item={this.getActionData()}
|
||||
containerProps={{ isAdminPage: this.isAdminPage }}
|
||||
isAdminPage={this.isAdminPage}
|
||||
// firstActionClassName={styles['attach-btn']}
|
||||
/>
|
||||
);
|
||||
|
@ -97,7 +97,7 @@ class BaseLayout extends Component {
|
||||
if (licenseKey && !this.checkLicenseKey(licenseKey)) {
|
||||
return null;
|
||||
}
|
||||
if (policy && !checkItemPolicy(policy)) {
|
||||
if (policy && !checkItemPolicy({ policy })) {
|
||||
return null;
|
||||
}
|
||||
if (children.length === 0) {
|
||||
|
@ -31,6 +31,8 @@ export default class View extends ModalAction {
|
||||
|
||||
static readOnly = true;
|
||||
|
||||
static enableSystemReader = true;
|
||||
|
||||
get name() {
|
||||
return t('View');
|
||||
}
|
||||
|
@ -36,11 +36,32 @@ const checkPolicyRules = (rules, every, actionName) => {
|
||||
return rules.some((rule) => checkPolicyRule(rule, actionName));
|
||||
};
|
||||
|
||||
const checkItemPolicy = (policy, item, actionName) => {
|
||||
export const systemRoleIsReader = () => {
|
||||
const { user: { roles = [] } = {} } = globals || {};
|
||||
const readerRole = 'system_reader';
|
||||
const adminRoles = ['system_admin', '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,
|
||||
item,
|
||||
actionName,
|
||||
isAdminPage,
|
||||
enableSystemReader,
|
||||
}) => {
|
||||
if (globals.policies.length === 0) {
|
||||
// TODO: change to false
|
||||
return true;
|
||||
}
|
||||
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
||||
return false;
|
||||
}
|
||||
if (!policy) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('has no policy', policy, item, actionName);
|
||||
|
@ -121,7 +121,7 @@ class RootStore {
|
||||
this.roles = roles;
|
||||
this.baseRoles = base_roles;
|
||||
this.baseDomains = base_domains;
|
||||
// const adminRole = roles.find(it => it.name === 'admin');
|
||||
// TODO: fix system/project admin/member/reader for W
|
||||
this.hasAdminRole = checkPolicy(onlyAdminCanReadPolicy);
|
||||
globals.user.hasAdminRole = this.hasAdminRole;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user