Merge pull request #3395 from jumpserver/pr@dev@perf_change_accont_template_password_rules

perf: 修改密码规则
This commit is contained in:
老广
2023-09-19 11:00:42 +08:00
committed by GitHub
10 changed files with 171 additions and 60 deletions

View File

@@ -67,6 +67,9 @@ export default {
} }
}, },
computed: { computed: {
dataForm() {
return this.$refs.dataForm
},
iForm() { iForm() {
const iForm = {} const iForm = {}
Object.entries(this.form).forEach(([key, value]) => { Object.entries(this.form).forEach(([key, value]) => {

View File

@@ -136,8 +136,8 @@ export default {
}) })
}, },
// 重置表单 // 重置表单
resetForm(formName) { resetForm() {
this.$refs[formName].resetFields() this.$refs['form'].resetFields()
}, },
handleClick(button) { handleClick(button) {
const callback = button.callback || function(values, form) { const callback = button.callback || function(values, form) {
@@ -148,6 +148,7 @@ export default {
callback(values, form, button) callback(values, form, button)
}, },
getFormValue() { getFormValue() {
return this.$refs.form.getFormValue()
} }
} }
} }

View File

@@ -0,0 +1,101 @@
<template>
<div style="display: block">
<el-button size="mini" type="primary" @click="visible=true">
{{ $t('common.Setting') }}
</el-button>
<Dialog
:destroy-on-close="true"
:title="$tc('common.PasswordRule')"
:visible.sync="visible"
width="600px"
@cancel="handleCancel"
@confirm="handleConfirm"
@open="handleOpen"
>
<AutoDataForm ref="dataform" v-bind="form" />
</Dialog>
</div>
</template>
<script>
import Dialog from '@/components/Dialog/index.vue'
import AutoDataForm from '@/components/Form/AutoDataForm/index.vue'
export default {
name: 'PasswordRule',
components: { Dialog, AutoDataForm },
props: {
value: {
type: Object,
default: () => ({
length: 16
})
}
},
data() {
return {
visible: false,
form: {
url: '',
hasButtons: false,
hasReset: false,
hasSaveContinue: false,
form: Object.assign({}, this.value),
fields: [
{
id: 'length',
label: this.$t('common.Length'),
type: 'input-number',
el: {
min: 8,
max: 30
}
},
{
id: 'uppercase',
label: this.$t('common.Uppercase'),
type: 'switch'
},
{
id: 'lowercase',
label: this.$t('common.Lowercase'),
type: 'switch'
},
{
id: 'digit',
label: this.$t('common.Digit'),
type: 'switch'
},
{
id: 'symbol',
label: this.$t('common.SpecialSymbol'),
type: 'switch'
}
]
}
}
},
methods: {
handleConfirm() {
const formValue = this.$refs.dataform.dataForm.getFormValue()
this.form.form = formValue
this.$emit('input', formValue)
setTimeout(() => {
this.visible = false
}, 100)
},
handleCancel() {
this.$refs.dataform.dataForm.resetForm()
setTimeout(() => {
this.visible = false
}, 100)
},
handleOpen() {
}
}
}
</script>
<style scoped>
</style>

View File

@@ -18,6 +18,7 @@ import BoolTextReadonly from './BoolTextReadonly.vue'
import NestedObjectSelect2 from './NestedObjectSelect2.vue' import NestedObjectSelect2 from './NestedObjectSelect2.vue'
import DatetimeRangePicker from './DatetimeRangePicker.vue' import DatetimeRangePicker from './DatetimeRangePicker.vue'
import JSONManyToManySelect from './JSONManyToManySelect/index.vue' import JSONManyToManySelect from './JSONManyToManySelect/index.vue'
import PasswordRule from './PasswordRule.vue'
export default { export default {
Link, Link,
@@ -34,6 +35,7 @@ export default {
DynamicInput, DynamicInput,
PasswordInput, PasswordInput,
UploadSecret, UploadSecret,
PasswordRule,
TextReadonly, TextReadonly,
WeekCronSelect, WeekCronSelect,
BoolTextReadonly, BoolTextReadonly,
@@ -57,6 +59,7 @@ export {
DynamicInput, DynamicInput,
PasswordInput, PasswordInput,
UploadSecret, UploadSecret,
PasswordRule,
TextReadonly, TextReadonly,
WeekCronSelect, WeekCronSelect,
BoolTextReadonly, BoolTextReadonly,

View File

@@ -87,7 +87,8 @@
"SystemUserAmount": "SystemUser amount", "SystemUserAmount": "SystemUser amount",
"AssetChangeSecretUpdate": "Update account change secret", "AssetChangeSecretUpdate": "Update account change secret",
"Success": "Success", "Success": "Success",
"AddSystemUser": "Add system user" "AddSystemUser": "Add system user",
"PasswordRule": "PasswordRule"
}, },
"AccountPush": { "AccountPush": {
"WindowsPushHelpText": "Windows assets do not support pushing keys", "WindowsPushHelpText": "Windows assets do not support pushing keys",
@@ -490,7 +491,8 @@
"ReLogin": "Re-Login", "ReLogin": "Re-Login",
"ReLoginTitle": "The current three-party login user (cas/saml) is not bound to MFA and does not support password verification. Please login again", "ReLoginTitle": "The current three-party login user (cas/saml) is not bound to MFA and does not support password verification. Please login again",
"NeedReLogin": "Need Re-Login", "NeedReLogin": "Need Re-Login",
"ReLoginErr": "Login time has exceeded 5 minutes, please login again" "ReLoginErr": "Login time has exceeded 5 minutes, please login again",
"AddPassKey": "AddPassKey"
}, },
"common": { "common": {
"Enterprise": "Enterprise", "Enterprise": "Enterprise",
@@ -761,7 +763,8 @@
"Download": "Download", "Download": "Download",
"UserPage": "User page", "UserPage": "User page",
"View": "View", "View": "View",
"EnterpriseEdition": "Enterprise edition" "EnterpriseEdition": "Enterprise edition",
"PassKey": "Passkey"
}, },
"passwordOrPassphrase": "Password or Passphrase", "passwordOrPassphrase": "Password or Passphrase",
"removeErrorMsg": "Remove failed: ", "removeErrorMsg": "Remove failed: ",
@@ -896,7 +899,13 @@
"LessEqualThan": "Less than or equal to", "LessEqualThan": "Less than or equal to",
"OtherRules": "Other rules", "OtherRules": "Other rules",
"BelongTo": "Belong to", "BelongTo": "Belong to",
"GreatEqualThan": "Greater than or equal to" "GreatEqualThan": "Greater than or equal to",
"PasswordRule": "PasswordRule",
"Uppercase": "Uppercase",
"Length": "Length",
"Digit": "Digit",
"Lowercase": "Lowercase",
"SpecialSymbol": "SpecialSymbol"
}, },
"dashboard": { "dashboard": {
"ActiveAsset": "Asset active", "ActiveAsset": "Asset active",
@@ -1446,7 +1455,8 @@
"DeviceUpdate": "Update Asset - Network Device", "DeviceUpdate": "Update Asset - Network Device",
"CloudCreate": "Create Asset - Cloud Platform", "CloudCreate": "Create Asset - Cloud Platform",
"DatabaseUpdate": "Update Asset - Database", "DatabaseUpdate": "Update Asset - Database",
"CloudUpdate": "Update Asset - Cloud Platform" "CloudUpdate": "Update Asset - Cloud Platform",
"OnlineUserDevices": "OnlineUserDevices"
}, },
"rbac": { "rbac": {
"Permissions": "Permissions", "Permissions": "Permissions",
@@ -1798,7 +1808,8 @@
"SystemTools": "Tools", "SystemTools": "Tools",
"BasicTools": "Basic tool", "BasicTools": "Basic tool",
"sync": "Sync", "sync": "Sync",
"AccountStorage": "Account Storage" "AccountStorage": "Account Storage",
"Passkey": "Passkey"
}, },
"tickets": { "tickets": {
"BatchApproval": "Batch approval", "BatchApproval": "Batch approval",
@@ -2199,7 +2210,8 @@
"QcloudLighthouse": "Tencent Cloud (lightweight application server)", "QcloudLighthouse": "Tencent Cloud (lightweight application server)",
"KingSoftCloud": "KingSoft Cloud", "KingSoftCloud": "KingSoft Cloud",
"CTYunPrivate": "CTYun Private", "CTYunPrivate": "CTYun Private",
"LAN": "LAN" "LAN": "LAN",
"AccountHelpText": "A cloud account is used to connect to a cloud service provider and access the provider's resource information."
}, },
"Corporation": "Corporation", "Corporation": "Corporation",
"Edition": "Edition", "Edition": "Edition",
@@ -2295,4 +2307,4 @@
"PublishStatus": "Publish status", "PublishStatus": "Publish status",
"NoPublished": "Unpublished" "NoPublished": "Unpublished"
} }
} }

View File

@@ -87,7 +87,8 @@
"SystemUserAmount": "システムユーザー数", "SystemUserAmount": "システムユーザー数",
"AssetChangeSecretUpdate": "アカウントの更新とパスワードの変更", "AssetChangeSecretUpdate": "アカウントの更新とパスワードの変更",
"Success": "成功", "Success": "成功",
"AddSystemUser": "システムユーザーを追加" "AddSystemUser": "システムユーザーを追加",
"PasswordRule": "パスワードのルール"
}, },
"AccountPush": { "AccountPush": {
"WindowsPushHelpText": "windows アセットはプッシュキーをサポートしていません", "WindowsPushHelpText": "windows アセットはプッシュキーをサポートしていません",
@@ -490,7 +491,8 @@
"ReLogin": "再ログイン", "ReLogin": "再ログイン",
"ReLoginTitle": "現在、サードパーティのログインユーザーCAS/SAMLは、MFAをバインドしておらず、パスワードチェックをサポートしていません。再ログインしてください。", "ReLoginTitle": "現在、サードパーティのログインユーザーCAS/SAMLは、MFAをバインドしておらず、パスワードチェックをサポートしていません。再ログインしてください。",
"NeedReLogin": "再ログインが必要です", "NeedReLogin": "再ログインが必要です",
"ReLoginErr": "ログイン時間が 5 分を超えました。もう一度ログインしてください" "ReLoginErr": "ログイン時間が 5 分を超えました。もう一度ログインしてください",
"AddPassKey": "パスキー(通行鍵)を追加"
}, },
"common": { "common": {
"Enterprise": "企業版", "Enterprise": "企業版",
@@ -764,7 +766,8 @@
"Download": "ダウンロード", "Download": "ダウンロード",
"UserPage": "ユーザービュー", "UserPage": "ユーザービュー",
"View": "ビュー", "View": "ビュー",
"EnterpriseEdition": "企業版" "EnterpriseEdition": "企業版",
"PassKey": "パスキー"
}, },
"passwordOrPassphrase": "パスワードまたはキーパスワード", "passwordOrPassphrase": "パスワードまたはキーパスワード",
"removeErrorMsg": "削除に失敗しました:", "removeErrorMsg": "削除に失敗しました:",
@@ -895,7 +898,13 @@
"LessEqualThan": "以下または等しい", "LessEqualThan": "以下または等しい",
"OtherRules": "他のルール", "OtherRules": "他のルール",
"BelongTo": "所属する", "BelongTo": "所属する",
"GreatEqualThan": "以上または等しい" "GreatEqualThan": "以上または等しい",
"PasswordRule": "パスワードのルール",
"Uppercase": "大文字",
"Length": "長さ",
"Digit": "数字",
"Lowercase": "小文字",
"SpecialSymbol": "特殊記号"
}, },
"dashboard": { "dashboard": {
"TotalJobLog": "ジョブ実行総数", "TotalJobLog": "ジョブ実行総数",
@@ -1791,7 +1800,8 @@
"SMSProvider": "メールサービス業者 / プロトコル", "SMSProvider": "メールサービス業者 / プロトコル",
"Applets": "リモート アプリケーション", "Applets": "リモート アプリケーション",
"sync": "同期", "sync": "同期",
"AccountStorage": "アカウントストレージ" "AccountStorage": "アカウントストレージ",
"Passkey": "パスキー"
}, },
"tickets": { "tickets": {
"BatchApproval": "大量承認です", "BatchApproval": "大量承認です",
@@ -2192,7 +2202,8 @@
"DateSync": "同期日", "DateSync": "同期日",
"Status": "ステータス", "Status": "ステータス",
"Log": "ログ", "Log": "ログ",
"DeleteReleasedAssets": "リリース済アセットの削除" "DeleteReleasedAssets": "リリース済アセットの削除",
"AccountHelpText": "クラウドアカウントはクラウドサービスプロバイダーに接続し、プロバイダーのリソース情報にアクセスするためのアカウントです"
}, },
"Template": { "Template": {
"Template": "テンプレート管理" "Template": "テンプレート管理"
@@ -2287,4 +2298,4 @@
"PublishStatus": "投稿ステータス", "PublishStatus": "投稿ステータス",
"NoPublished": "未発表" "NoPublished": "未発表"
} }
} }

View File

@@ -49,6 +49,7 @@
"RecipientHelpText": "当前只支持邮件发送, 若收件人 A B 都设置,账号的密钥将被拆分成前后两部分" "RecipientHelpText": "当前只支持邮件发送, 若收件人 A B 都设置,账号的密钥将被拆分成前后两部分"
}, },
"AccountChangeSecret": { "AccountChangeSecret": {
"PasswordRule": "密码生成规则",
"ParamsHelpText": "改密参数设置,目前仅对平台种类为主机的资产生效。", "ParamsHelpText": "改密参数设置,目前仅对平台种类为主机的资产生效。",
"ContainAttachment": "含附件", "ContainAttachment": "含附件",
"AddAsset": "添加资产", "AddAsset": "添加资产",
@@ -473,6 +474,12 @@
"ReLoginErr": "登录时长已超过 5 分钟,请重新登录" "ReLoginErr": "登录时长已超过 5 分钟,请重新登录"
}, },
"common": { "common": {
"PasswordRule": "密码生成规则",
"Length": "长度",
"Uppercase": "大写字母",
"Lowercase": "小写字母",
"Digit": "数字",
"SpecialSymbol": "特殊字符",
"Enterprise": "企业版", "Enterprise": "企业版",
"SyncTask": "同步任务", "SyncTask": "同步任务",
"New": "新建", "New": "新建",

View File

@@ -1,49 +1,14 @@
import i18n from '@/i18n/i18n' import i18n from '@/i18n/i18n'
import { CronTab } from '@/components' import { CronTab } from '@/components'
import { TagInput, UpdateToken } from '@/components/Form/FormFields' import { PasswordRule, TagInput, UpdateToken } from '@/components/Form/FormFields'
import { Required } from '@/components/Form/DataForm/rules'
var validatorInterval = (rule, value, callback) => { const validatorInterval = (rule, value, callback) => {
if (parseInt(value) < 1) { if (parseInt(value) < 1) {
return callback(new Error(i18n.t('accounts.AccountChangeSecret.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo1'))) return callback(new Error(i18n.t('accounts.AccountChangeSecret.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo1')))
} }
callback() callback()
} }
function getAssetPasswordRulesItems() {
return [
{
id: 'length',
prop: 'length',
label: i18n.t('accounts.AccountChangeSecret.PasswordLength'),
rules: [Required],
hidden: ({ secret_strategy, secret_type }) => (secret_strategy === 'specific' || secret_type !== 'password')
}
]
}
function generatePasswordRulesItemsFields(obType) {
const itemsFields = []
let items
if (obType === 'asset') {
items = getAssetPasswordRulesItems()
}
items.forEach((item, index, array) => {
itemsFields.push({
id: item.id,
prop: item.prop,
el: {},
attrs: {},
type: 'input',
label: item.label,
rules: item.rules,
helpText: item.helpText,
hidden: item.hidden
})
})
return itemsFields
}
export const getChangeSecretFields = () => { export const getChangeSecretFields = () => {
return { return {
secret_type: { secret_type: {
@@ -84,8 +49,9 @@ export const getChangeSecretFields = () => {
} }
}, },
password_rules: { password_rules: {
type: 'group', component: PasswordRule,
items: generatePasswordRulesItemsFields('asset') label: i18n.t('accounts.AccountChangeSecret.PasswordRule'),
hidden: ({ secret_strategy, secret_type }) => (secret_strategy === 'specific' || secret_type !== 'password')
}, },
recipients: { recipients: {
label: i18n.t('accounts.AccountChangeSecret.Addressee'), label: i18n.t('accounts.AccountChangeSecret.Addressee'),

View File

@@ -53,7 +53,8 @@ export default {
url: `/api/v1/accounts/account-templates/${this.object.id}/`, url: `/api/v1/accounts/account-templates/${this.object.id}/`,
excludes: ['privileged', 'secret', 'passphrase', 'spec_info'], excludes: ['privileged', 'secret', 'passphrase', 'spec_info'],
detailFields: [ detailFields: [
'id', 'name', 'username', 'secret_type', 'created_by', 'comment', 'id', 'name', 'username', 'secret_type', 'auto_push',
'secret_strategy', 'created_by', 'comment',
{ {
key: this.$t('accounts.SuFrom'), key: this.$t('accounts.SuFrom'),
formatter: () => { formatter: () => {

View File

@@ -1,14 +1,15 @@
import { getUuidUpdateFromUrl } from '@/utils/common' import { getUuidUpdateFromUrl } from '@/utils/common'
import { UpdateToken } from '@/components/Form/FormFields' import { PasswordRule, UpdateToken } from '@/components/Form/FormFields'
import Select2 from '@/components/Form/FormFields/Select2' import Select2 from '@/components/Form/FormFields/Select2'
import AutomationParams from '@/components/Apps/AutomationParams' import AutomationParams from '@/components/Apps/AutomationParams'
import i18n from '@/i18n/i18n'
export const templateFields = (vm) => { export const templateFields = (vm) => {
return [ return [
[vm.$t('common.Basic'), ['name', 'username', 'privileged', 'su_from']], [vm.$t('common.Basic'), ['name', 'username', 'privileged', 'su_from']],
[vm.$t('assets.Secret'), [ [vm.$t('assets.Secret'), [
'secret_type', 'secret_strategy', 'secret', 'ssh_key', 'token', 'secret_type', 'secret_strategy', 'password_rules',
'access_key', 'passphrase', 'api_key' 'secret', 'ssh_key', 'token', 'access_key', 'passphrase', 'api_key'
]], ]],
[vm.$t('accounts.AutoPush'), [ [vm.$t('accounts.AutoPush'), [
'auto_push', 'platforms', 'push_params' 'auto_push', 'platforms', 'push_params'
@@ -93,6 +94,11 @@ export const templateFieldsMeta = (vm) => {
}, },
hidden: (formValue) => formValue.secret_type !== 'api_key' || formValue.secret_strategy === 'random' hidden: (formValue) => formValue.secret_type !== 'api_key' || formValue.secret_strategy === 'random'
}, },
password_rules: {
component: PasswordRule,
label: i18n.t('accounts.AccountChangeSecret.PasswordRule'),
hidden: ({ secret_strategy, secret_type }) => (secret_strategy === 'specific' || secret_type !== 'password')
},
platforms: { platforms: {
el: { el: {
multiple: true, multiple: true,