Skip to content

Commit

Permalink
feat(frontend): 权限规则db校验规则 #8407
Browse files Browse the repository at this point in the history
  • Loading branch information
JustaCattt authored and hLinx committed Dec 11, 2024
1 parent 5b0679f commit 5451439
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 206 deletions.
6 changes: 4 additions & 2 deletions dbm-ui/frontend/src/locales/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -641,11 +641,9 @@
"即将删除账号xx_删除后将不能恢复": "即将删除账号\"{name}\", 删除后将不能恢复",
"成功删除账号": "成功删除账号",
"成功添加授权规则": "成功添加授权规则",
"访问DB不能为空": "访问 DB 不能为空",
"请设置权限": "请设置权限",
"全选": "全选",
"权限设置": "权限设置",
"请输入DB名称_可以使用通配符_如Data_区分大小写_多个使用英文逗号_分号或换行分隔": "请输入 DB 名称,可以使用通配符 %,如 Data%,区分大小写,多个使用英文逗号、分号或换行分隔",
"该账号下已存在xx规则": "该账号下已存在 {0} 规则",
"收藏成功": "收藏成功",
"取消收藏成功": "取消收藏成功",
Expand Down Expand Up @@ -3712,5 +3710,9 @@
"请输入访问DB名_以字母开头_支持字母_数字_下划线_多个使用英文逗号_分号或换行分隔": "请输入访问DB名,以字母开头,支持字母,数字,下划线。多个使用英文逗号、分号或换行分隔",
"单据协助设置": "单据协助设置",
"主域名,从域名,单节点必须分开查询": "主域名,从域名,单节点必须分开查询",
"请输入访问DB名_支持 % 通配符_多个使用英文逗号_分号或换行分隔": "请输入访问DB名,支持 % 通配符。多个使用英文逗号、分号或换行分隔",
"% 不能单独使用": "% 不能单独使用",
"访问 DB 名必须合法": "访问 DB 名必须合法",
"请输入访问DB名_以字母开头_支持 % 通配符 或 % 单独使用代表ALL_多个使用英文逗号_分号或换行分隔": "请输入访问DB名,以字母开头,支持 % 通配符 或 % 单独使用代表ALL。多个使用英文逗号、分号或换行分隔",
"这行勿动!新增翻译请在上一行添加!": ""
}
2 changes: 1 addition & 1 deletion dbm-ui/frontend/src/types/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ declare global {
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
import('vue')
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
ref="ruleRef"
class="rule-form"
form-type="vertical"
:model="formdata"
:model="formData"
:rules="rules">
<BkFormItem
:label="t('账号名')"
property="account_id"
required>
<BkSelect
v-model="formdata.account_id"
v-model="formData.account_id"
:clearable="false"
filterable
:input-search="false"
Expand Down Expand Up @@ -58,7 +58,7 @@
required
:rules="rules.access_db">
<BkInput
v-model="formdata.access_db"
v-model="formData.access_db"
:maxlength="100"
:placeholder="t('请输入访问DB名_以字母开头_支持字母_数字_下划线_多个使用英文逗号_分号或换行分隔')"
:rows="4"
Expand All @@ -67,7 +67,7 @@
<BkFormItem
class="form-item privilege"
:label="t('权限设置')"
property="auth"
property="privilege"
:required="false">
<div class="rule-setting-box">
<BkFormItem
Expand All @@ -82,7 +82,7 @@
{{ t('全选') }}
</BkCheckbox>
<BkCheckboxGroup
v-model="formdata.privilege.mongo_user"
v-model="formData.privilege.mongo_user"
class="checkbox-group">
<BkCheckbox
v-for="option of mongoUserDbOperations"
Expand All @@ -106,7 +106,7 @@
{{ t('全选') }}
</BkCheckbox>
<BkCheckboxGroup
v-model="formdata.privilege.mongo_manager"
v-model="formData.privilege.mongo_manager"
class="checkbox-group">
<BkCheckbox
v-for="option of dbOperations.mongo_manager"
Expand Down Expand Up @@ -138,7 +138,6 @@
</template>

<script setup lang="ts">
import { Message } from 'bkui-vue';
import _ from 'lodash';
import { useI18n } from 'vue-i18n';
import { useRequest } from 'vue-request';
Expand All @@ -152,9 +151,11 @@

import DbForm from '@components/db-form/index.vue';

import { messageSuccess } from '@utils';

import dbOperations from './config';

type AuthItemKey = keyof typeof dbOperations;
type AuthItemKey = 'mongo_user' | 'mongo_manager';

interface Props {
accountId: number;
Expand All @@ -171,9 +172,17 @@
default: false,
});

const { t } = useI18n();
const handleBeforeClose = useBeforeClose();

const ruleRef = ref<InstanceType<typeof DbForm>>();
const accounts = ref<PermissionRuleAccount[]>([]);
const existDBs = ref<string[]>([]);
const accessDBType = ref<'admin' | 'not_admin'>('admin');

const replaceReg = /[,;\r\n]/g;

const initFormdata = () => ({
const initFormData = () => ({
account_id: -1,
access_db: 'admin',
privilege: {
Expand All @@ -182,47 +191,13 @@
},
});

const verifyAccountRulesExits = () => {
existDBs.value = [];

const user = selectedUserInfo.value?.user;
const dbs = formdata.value.access_db
.replace(replaceReg, ',')
.split(',')
.filter((db) => db !== '');

if (!user || dbs.length === 0) {
return false;
}

return queryAccountRules({
user,
access_dbs: dbs,
account_type: AccountTypes.MONGODB,
}).then((res) => {
const rules = res.results[0]?.rules || [];
existDBs.value = rules.map((item) => item.access_db);

return rules.length === 0;
});
};

const { t } = useI18n();
const handleBeforeClose = useBeforeClose();

const ruleRef = ref<InstanceType<typeof DbForm>>();
const formdata = ref(initFormdata());
const accounts = ref<PermissionRuleAccount[]>([]);
const existDBs = ref<string[]>([]);
const accessDBType = ref<'admin' | 'not_admin'>('admin');

const rules = {
auth: [
privilege: [
{
trigger: 'change',
message: t('请设置权限'),
validator: () => {
const { mongo_user: mongoUser, mongo_manager: mongoManager } = formdata.value.privilege;
const { mongo_user: mongoUser, mongo_manager: mongoManager } = formData.privilege;
return mongoUser.length !== 0 || mongoManager.length !== 0;
},
},
Expand All @@ -232,12 +207,35 @@
required: true,
trigger: 'blur',
message: t('访问 DB 不能为空'),
validator: (value: string) => !!value,
validator: (value: string) => {
const dbs = value.split(/[\n;,]/);
return _.every(dbs, (item) => !!item.trim());
},
},
{
required: true,
trigger: 'blur',
message: () => t('该账号下已存在xx规则', [existDBs.value.join(',')]),
validator: verifyAccountRulesExits,
message: () => t('该账号下已存在xx规则', [existDBs.value.join(',')]),
validator: () => {
existDBs.value = [];
const user = accounts.value.find((item) => item.account_id === formData.account_id)?.user;
const dbs = formData.access_db
.replace(replaceReg, ',')
.split(',')
.filter((db) => db !== '');
if (!user || dbs.length === 0) {
return false;
}
return queryAccountRules({
user,
access_dbs: dbs,
account_type: AccountTypes.MONGODB,
}).then((res) => {
const rules = res.results[0]?.rules || [];
existDBs.value = rules.map((item) => item.access_db);
return rules.length === 0;
});
},
},
{
required: true,
Expand All @@ -251,40 +249,38 @@
message: t('请输入访问DB名_以字母开头_支持字母_数字_下划线_多个使用英文逗号_分号或换行分隔'),
validator: (value: string) => {
const dbs = value.split(/[\n;,]/);
return _.every(dbs, (item) => (!item ? true : /^[_a-zA-Z0-9]/.test(item) && !/\*/.test(value)));
return _.every(dbs, (item) => (!item ? true : /^(?:[a-zA-Z].*$)/.test(item)));
},
},
],
};

const selectedUserInfo = computed(() => accounts.value.find((item) => item.account_id === formdata.value.account_id));
const formData = reactive(initFormData());

const mongoUserDbOperations = computed(() =>
accessDBType.value === 'not_admin' ? ['read', 'readWrite'] : dbOperations.mongo_user,
);

const { loading: isSubmitting, run: addMongodbAccountRuleRun } = useRequest(addAccountRule, {
const { run: getPermissionRulesRun, loading: getPermissionRulesLoading } = useRequest(getPermissionRules, {
manual: true,
onSuccess() {
Message({
message: t('成功添加授权规则'),
theme: 'success',
});
emits('success');
window.changeConfirm = false;
handleClose();
onSuccess(permissionRules) {
accounts.value = permissionRules.results.map((item) => item.account);
},
});

const { run: getPermissionRulesRun, loading: getPermissionRulesLoading } = useRequest(getPermissionRules, {
const { run: addMongodbAccountRuleRun, loading: isSubmitting } = useRequest(addAccountRule, {
manual: true,
onSuccess(permissionRules) {
accounts.value = permissionRules.results.map((item) => item.account);
onSuccess() {
messageSuccess(t('成功添加授权规则'));
emits('success');
window.changeConfirm = false;
handleClose();
},
});

watch(isShow, (show) => {
if (show) {
formdata.value.account_id = props.accountId ?? -1;
formData.account_id = props.accountId ?? -1;
getPermissionRulesRun({
offset: 0,
limit: -1,
Expand All @@ -293,24 +289,24 @@
}
});

const getAllCheckedboxValue = (key: AuthItemKey) => formdata.value.privilege[key].length === dbOperations[key].length;
const getAllCheckedboxValue = (key: AuthItemKey) => formData.privilege[key].length === dbOperations[key].length;

const getAllCheckedboxIndeterminate = (key: AuthItemKey) =>
formdata.value.privilege[key].length > 0 && formdata.value.privilege[key].length !== dbOperations[key].length;
formData.privilege[key].length > 0 && formData.privilege[key].length !== dbOperations[key].length;

const handleSelectedAll = (key: AuthItemKey, value: boolean) => {
if (value) {
formdata.value.privilege[key] = dbOperations[key];
formData.privilege[key] = dbOperations[key];
return;
}

formdata.value.privilege[key] = [];
formData.privilege[key] = [];
};

const handleAccessDBTypeChange = (value: 'admin' | 'not_admin') => {
formdata.value.access_db = value === 'admin' ? 'admin' : '';
formdata.value.privilege.mongo_user = [];
formdata.value.privilege.mongo_manager = [];
formData.access_db = value === 'admin' ? 'admin' : '';
formData.privilege.mongo_user = [];
formData.privilege.mongo_manager = [];
};

const handleClose = async () => {
Expand All @@ -321,7 +317,7 @@
}

isShow.value = false;
formdata.value = initFormdata();
_.merge(formData, initFormData());
accessDBType.value = 'admin';
existDBs.value = [];
window.changeConfirm = false;
Expand All @@ -330,8 +326,8 @@
const handleSubmit = async () => {
await ruleRef.value!.validate();
const params = {
...formdata.value,
access_db: formdata.value.access_db.replace(replaceReg, ','), // 统一分隔符
...formData,
access_db: formData.access_db.replace(replaceReg, ','), // 统一分隔符
account_type: AccountTypes.MONGODB,
};
addMongodbAccountRuleRun(params);
Expand Down
Loading

0 comments on commit 5451439

Please sign in to comment.