Skip to content

Commit

Permalink
feat(frontend): mongodb权限规则优化 TencentBlueKing#8407
Browse files Browse the repository at this point in the history
  • Loading branch information
JustaCattt authored and jinquantianxia committed Dec 5, 2024
1 parent d794cbe commit 25eb97b
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 26 deletions.
5 changes: 5 additions & 0 deletions dbm-ui/frontend/src/locales/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -3704,6 +3704,11 @@
"忽略错误": "忽略错误",
"强制失败节点成功": "强制失败节点成功",
"不允许使用特殊账号名称n": "不允许使用特殊账号名称 {n}",
"非 admin": "非 admin",
"请输入访问DB名_以字母开头_支持字母_数字_下划线": "请输入访问DB名,以字母开头,支持字母,数字,下划线",
"您输入的访问 DB 名不符合要求_访问 DB 名应以字母开头_且仅包含字母_数字和下划线": "您输入的访问 DB 名不符合要求。访问 DB 名应以字母开头,且仅包含字母、数字和下划线",
"访问 DB 不能为空": "访问 DB 不能为空",
"访问 DB 名不允许为 admin": "访问 DB 名不允许为 admin",
"这行勿动!新增翻译请在上一行添加!": ""

}
13 changes: 10 additions & 3 deletions dbm-ui/frontend/src/services/source/mongodbPermissionAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ export function addAccountRule(params: {
account_id: number | null;
account_type: AccountTypesValues;
}) {
return http.post<null>(`${getRootPath()}/add_account_rule/`, params);
return http.post(`${getRootPath()}/add_account_rule/`, params);
}

/**
* 创建账号
*/
export function createAccount(params: { user: string; password: string; account_type?: AccountTypesValues }) {
return http.post<null>(`${getRootPath()}/create_account/`, params);
return http.post(`${getRootPath()}/create_account/`, params);
}

/**
* 删除账号
*/
export function deleteAccount(params: { bizId: number; account_id: number; account_type?: AccountTypesValues }) {
return http.delete<null>(`${getRootPath()}/delete_account/`, params);
return http.delete(`${getRootPath()}/delete_account/`, params);
}

/**
Expand Down Expand Up @@ -82,3 +82,10 @@ export function queryAccountRules(params: { user: string; access_dbs: string[];
results: res.results.map((item) => new MongodbPermissonAccountModel(item)),
}));
}

/**
* 删除规则
*/
export function deleteAccountRule(params: { account_id: number; account_type: AccountTypesValues; rule_id: number }) {
return http.delete(`${getRootPath()}/delete_account_rule/`, params);
}
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')
}
53 changes: 40 additions & 13 deletions dbm-ui/frontend/src/views/db-manage/common/permission/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
import { useI18n } from 'vue-i18n';
import { useRequest } from 'vue-request';

import { deleteAccount as deleteMongodbAccount, getPermissionRules as getMongodbPermissionRules } from '@services/source/mongodbPermissionAccount';
import { deleteAccount as deleteMongodbAccount, deleteAccountRule as deleteMongodbAccountRule, getPermissionRules as getMongodbPermissionRules } from '@services/source/mongodbPermissionAccount';
import { deleteAccount as deleteMysqlAccount, getPermissionRules as getMysqlPermissionRules } from '@services/source/mysqlPermissionAccount';
import { deleteAccount as deleteSqlserverAccount, getPermissionRules as getSqlserverPermissionRules } from '@services/source/sqlserverPermissionAccount';
import { createTicket } from '@services/source/ticket';
Expand Down Expand Up @@ -143,7 +143,6 @@
* dbOperations 权限配置
* ddlSensitiveWords 敏感词
* dataSource 数据源
* deleteAccount 删除账号api
* createRuleComponent 创建规则组件
*/
const configMap = {
Expand All @@ -153,7 +152,6 @@
dbOperations: mysqlDbOperations[AccountTypes.MYSQL].dbOperations,
ddlSensitiveWords: mysqlDbOperations[AccountTypes.MYSQL].ddlSensitiveWords,
dataSource: getMysqlPermissionRules,
deleteAccount: deleteMysqlAccount,
createRuleComponent: MysqlCreateRule,
buttonController: {
[ButtonTypes.EDIT_RULE]: true,
Expand All @@ -166,7 +164,6 @@
dbOperations: mysqlDbOperations[AccountTypes.TENDBCLUSTER].dbOperations,
ddlSensitiveWords: mysqlDbOperations[AccountTypes.TENDBCLUSTER].ddlSensitiveWords,
dataSource: getMysqlPermissionRules,
deleteAccount: deleteMysqlAccount,
createRuleComponent: MysqlCreateRule,
buttonController: {
[ButtonTypes.EDIT_RULE]: true,
Expand All @@ -179,7 +176,6 @@
dbOperations: sqlserverDbOperations,
ddlSensitiveWords: [],
dataSource: getSqlserverPermissionRules,
deleteAccount: deleteSqlserverAccount,
createRuleComponent: SqlserverCreateRule,
buttonController: {
[ButtonTypes.EDIT_RULE]: false,
Expand All @@ -192,11 +188,10 @@
dbOperations: mongoDbOperations,
ddlSensitiveWords: [],
dataSource: getMongodbPermissionRules,
deleteAccount: deleteMongodbAccount,
createRuleComponent: MongoCreateRule,
buttonController: {
[ButtonTypes.EDIT_RULE]: false,
[ButtonTypes.DELETE_RULE]: false,
[ButtonTypes.DELETE_RULE]: true,
}
},
};
Expand Down Expand Up @@ -307,7 +302,6 @@
label: t('账号名称'),
field: 'user',
width: 200,
fixed: 'left',
render: ({ data }: { data: PermissionRule }) => (
<TextOverflowLayout>
{{
Expand Down Expand Up @@ -430,7 +424,7 @@
},
{
label: t('操作'),
width: 100,
width: 150,
fixed: 'right',
render: ({ data }: { data: PermissionRule }) => {
if (data.rules.length === 0) {
Expand Down Expand Up @@ -488,12 +482,14 @@
content={t('删除规则会创建单据,需此规则所有过往调用方审批后才执行删除。')}
title={t('确认删除该规则?')}
trigger="click"
onConfirm={() => handleShowDeleteRule(data, index)}
disabled={props.accountType === AccountTypes.MONGODB}
onConfirm={() => handlePopDeleteRule(data, index)}
>
<bk-button
theme="primary"
class="ml-8"
disabled={data.rules[index].priv_ticket?.ticket_id}
onClick={() => handleDeleteRule(data, index)}
text>
{t('删除')}
</bk-button>
Expand All @@ -511,14 +507,28 @@
/**
* 规则变更走单据
*/
const { run: createTicketRun } = useRequest(createTicket, {
const { run: createTicketRun } = useRequest(createTicket, {
manual: true,
onSuccess(data) {
ticketMessage(data.id);
fetchData();
},
})

/**
* 删除规则(不走审批)
*/
const { run: deleteAccountRuleRun } = useRequest(deleteMongodbAccountRule, {
manual: true,
onSuccess() {
Message({
message: t('删除成功'),
theme: 'success',
});
fetchData();
},
})

// 设置行样式
const setRowClass = (row: PermissionRule) => (isNewUser(row) ? 'is-new' : '');

Expand Down Expand Up @@ -580,13 +590,19 @@
* 删除账号
*/
const handleDeleteAccount = (row: PermissionRule) => {
const apiMap = {
[AccountTypes.MYSQL]: deleteMysqlAccount,
[AccountTypes.TENDBCLUSTER]: deleteMysqlAccount,
[AccountTypes.SQLSERVER]: deleteSqlserverAccount,
[AccountTypes.MONGODB]: deleteMongodbAccount,
}
InfoBox({
type: 'warning',
title: t('确认删除该账号'),
content: t('即将删除账号xx_删除后将不能恢复', { name: row.account.user }),
onConfirm: async () => {
try {
await configMap[props.accountType].deleteAccount({
await apiMap[props.accountType]({
bizId: window.PROJECT_CONFIG.BIZ_ID,
account_id: row.account.account_id,
account_type: props.accountType,
Expand Down Expand Up @@ -639,7 +655,7 @@
/**
* 删除规则
*/
const handleShowDeleteRule = (row: PermissionRule, index: number) => {
const handlePopDeleteRule = (row: PermissionRule, index: number) => {
const ticketTypeMap = {
[AccountTypes.MYSQL]: TicketTypes.MYSQL_ACCOUNT_RULE_CHANGE,
[AccountTypes.TENDBCLUSTER]: TicketTypes.TENDBCLUSTER_ACCOUNT_RULE_CHANGE,
Expand All @@ -660,6 +676,17 @@
},
});
};

/**
* 删除规则(不需要审批)
*/
const handleDeleteRule = (row: PermissionRule, index: number) => {
deleteAccountRuleRun({
account_id: row.account.account_id,
account_type: props.accountType,
rule_id: row.rules[index].rule_id,
});
};
</script>

<style lang="less" scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,26 @@
</BkFormItem>
<BkFormItem
:label="t('访问DB')"
required>
<BkRadioGroup
v-model="accessDBType"
@change="handleAccessDBTypeChange">
<BkRadio label="admin" />
<BkRadio label="not_admin">{{ t('非 admin') }}</BkRadio>
</BkRadioGroup>
</BkFormItem>
<BkFormItem
v-if="accessDBType === 'not_admin'"
:label="t('DB 名')"
property="access_db"
required
:rules="rules.access_db">
<DbTextarea
ref="textareaRef"
<BkInput
v-model="formdata.access_db"
:max-height="400"
:placeholder="t('请输入DB名称_可以使用通配符_如Data_区分大小写_多个使用英文逗号_分号或换行分隔')"
:teleport-to-body="false" />
:maxlength="100"
:placeholder="t('请输入访问DB名_以字母开头_支持字母_数字_下划线')"
:rows="4"
type="textarea" />
</BkFormItem>
<BkFormItem
class="form-item privilege"
Expand All @@ -74,7 +85,7 @@
v-model="formdata.privilege.mongo_user"
class="checkbox-group">
<BkCheckbox
v-for="option of dbOperations.mongo_user"
v-for="option of mongoUserDbOperations"
:key="option"
:label="option">
{{ option }}
Expand All @@ -83,6 +94,7 @@
</div>
</BkFormItem>
<BkFormItem
v-if="accessDBType === 'admin'"
:label="t('管理权限')"
required>
<div class="rule-form-row">
Expand Down Expand Up @@ -162,7 +174,7 @@

const initFormdata = () => ({
account_id: -1,
access_db: '',
access_db: 'admin',
privilege: {
mongo_user: [] as string[],
mongo_manager: [] as string[],
Expand Down Expand Up @@ -201,6 +213,7 @@
const formdata = ref(initFormdata());
const accounts = ref<PermissionRuleAccount[]>([]);
const existDBs = ref<string[]>([]);
const accessDBType = ref<'admin' | 'not_admin'>('admin');

const rules = {
auth: [
Expand All @@ -217,18 +230,33 @@
{
required: true,
trigger: 'blur',
message: t('访问DB不能为空'),
message: t('访问 DB 不能为空'),
validator: (value: string) => !!value,
},
{
trigger: 'blur',
message: () => t('该账号下已存在xx规则', [existDBs.value.join(',')]),
validator: verifyAccountRulesExits,
},
{
required: true,
trigger: 'blur',
message: t('访问 DB 名不允许为 admin'),
validator: (value: string) => /^(?!admin$).*/.test(value),
},
{
required: true,
trigger: 'blur',
message: t('您输入的访问 DB 名不符合要求_访问 DB 名应以字母开头_且仅包含字母_数字和下划线'),
validator: (value: string) => /^[A-Za-z][A-Za-z0-9_]*$/.test(value),
},
],
};

const selectedUserInfo = computed(() => accounts.value.find((item) => item.account_id === formdata.value.account_id));
const mongoUserDbOperations = computed(() =>
accessDBType.value === 'not_admin' ? ['read', 'readWrite'] : dbOperations.mongo_user,
);

const { loading: isSubmitting, run: addMongodbAccountRuleRun } = useRequest(addAccountRule, {
manual: true,
Expand Down Expand Up @@ -275,6 +303,12 @@
formdata.value.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 = [];
};

const handleClose = async () => {
const result = await handleBeforeClose();

Expand All @@ -284,6 +318,7 @@

isShow.value = false;
formdata.value = initFormdata();
accessDBType.value = 'admin';
existDBs.value = [];
window.changeConfirm = false;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default {
mongo_user: ['Read', 'readWrite', 'readAnyDatabase', 'readWriteAnyDatabase'],
mongo_user: ['read', 'readWrite', 'readAnyDatabase', 'readWriteAnyDatabase'],
mongo_manager: [
'dbAdmin',
'backup',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
@confirm="handleVerifyConfirm">
<BkButton
class="w-88 mr-8 ml-8"
:loading="isSubmitting"
theme="primary"
@click="handleSubmit">
{{ t('提交') }}
Expand Down

0 comments on commit 25eb97b

Please sign in to comment.