mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-15 14:24:39 +00:00
@@ -58,6 +58,7 @@
|
||||
"vue-cookie": "^1.1.4",
|
||||
"vue-echarts": "^5.0.0-beta.0",
|
||||
"vue-i18n": "^8.15.5",
|
||||
"vue-json-editor": "^1.4.3",
|
||||
"vue-moment": "^4.1.0",
|
||||
"vue-password-strength-meter": "^1.7.2",
|
||||
"vue-router": "3.0.6",
|
||||
|
||||
73
src/components/FormFields/JsonEditor.vue
Normal file
73
src/components/FormFields/JsonEditor.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="json-editor">
|
||||
<JsonEditor
|
||||
v-model="resultInfo"
|
||||
:show-btns="false"
|
||||
:mode="'code'"
|
||||
@json-change="onJsonChange"
|
||||
@json-save="onJsonSave"
|
||||
@has-error="onError"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JsonEditor from 'vue-json-editor'
|
||||
|
||||
export default {
|
||||
components: { JsonEditor },
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasJsonFlag: true, // json是否验证通过
|
||||
resultInfo: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.resultInfo = JSON.parse(this.value)
|
||||
},
|
||||
methods: {
|
||||
// 数据改变
|
||||
onJsonChange(value) {
|
||||
this.onJsonSave(value)
|
||||
},
|
||||
// 保存
|
||||
onJsonSave(value) {
|
||||
this.resultInfo = value
|
||||
this.hasJsonFlag = true
|
||||
setTimeout(() => {
|
||||
this.$emit('change', JSON.stringify(this.resultInfo))
|
||||
}, 500)
|
||||
},
|
||||
onError: _.debounce(function(value) {
|
||||
this.$message.error(this.$t('common.FormatError'))
|
||||
}, 1100)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.json-editor {
|
||||
&>>> .jsoneditor {
|
||||
border: 1px solid #e5e6e7;
|
||||
}
|
||||
&>>> .jsoneditor-compact {
|
||||
display: none;
|
||||
}
|
||||
&>>> .jsoneditor-modes {
|
||||
display: none;
|
||||
}
|
||||
&>>> .jsoneditor-poweredBy {
|
||||
display: none;
|
||||
}
|
||||
&>>> .jsoneditor-menu {
|
||||
background: #1ab394;
|
||||
border-bottom: 1px solid #1ab394;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -8,6 +8,7 @@ import UploadKey from './UploadKey'
|
||||
import UserPassword from './UserPassword'
|
||||
import WeekCronSelect from './WeekCronSelect'
|
||||
import UpdateToken from './UpdateToken'
|
||||
import JsonEditor from './JsonEditor'
|
||||
|
||||
export default {
|
||||
DatetimeRangePicker,
|
||||
@@ -19,7 +20,8 @@ export default {
|
||||
UploadField,
|
||||
UserPassword,
|
||||
WeekCronSelect,
|
||||
UpdateToken
|
||||
UpdateToken,
|
||||
JsonEditor
|
||||
}
|
||||
|
||||
export {
|
||||
@@ -32,5 +34,6 @@ export {
|
||||
UploadField,
|
||||
UserPassword,
|
||||
WeekCronSelect,
|
||||
UpdateToken
|
||||
UpdateToken,
|
||||
JsonEditor
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
"Disk": "硬盘",
|
||||
"AdDomain": "AD域名",
|
||||
"AdDomainHelpText": "提供给域用户登录的AD域名",
|
||||
"SetAdDomainNoDisabled": "如果设置了AD域名不能修改",
|
||||
"Domain": "网域",
|
||||
"DomainDetail": "网域详情",
|
||||
"DomainHelpMessage": "网域功能是为了解决部分环境(如:混合云)无法直接连接而新增的功能,原理是通过网关服务器进行跳转登录。JMS => 网域网关 => 目标资产",
|
||||
@@ -445,6 +446,7 @@
|
||||
"lastCannotBeDeleteMsg": "最后一项,不能被删除",
|
||||
"InvalidJson": "不是合法 JSON",
|
||||
"time_period": "时段",
|
||||
"FormatError": "格式错误",
|
||||
"WeekCronSelect": {
|
||||
"Monday": "星期一",
|
||||
"Tuesday": "星期二",
|
||||
@@ -916,6 +918,9 @@
|
||||
"authSAML2MetadataUrl": "IDP metadata URL",
|
||||
"authSAML2AdvancedSettings": "高级配置",
|
||||
"IdpMetadataHelpText": "IDP metadata URL 和 IDP metadata XML参数二选一即可,IDP metadata URL的优先级高",
|
||||
"IdpMetadataUrlHelpText": "从远端地址中加载 IDP Metadata",
|
||||
"authSAMLKeyHelpText": "SP 证书和密钥 是用来和 IDP 加密通信的",
|
||||
"authSAMLCertHelpText": "上传证书密钥后保存, 然后查看 SP Metadata",
|
||||
"authCASAttrMap": "用户属性映射",
|
||||
"SignaturesAndTemplates": "Signatures and Templates",
|
||||
"unselectedUser": "没有选择用户",
|
||||
@@ -1046,6 +1051,9 @@
|
||||
"PermissionName": "授权规则名称",
|
||||
"Accept": "同意",
|
||||
"AssignedMe": "待我审批",
|
||||
"FlowSetUp": "流程设置",
|
||||
"ApprovalProcess": "审批流程",
|
||||
"LevelApproval": "级审批",
|
||||
"Assignee": "处理人",
|
||||
"Assignees": "待处理人",
|
||||
"Close": "关闭",
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
"username_group":"Username group",
|
||||
"hostname_group":"Hostname group",
|
||||
"asset_ip_group": "Asset ip group",
|
||||
"system_users_name_group": "Systemusers name group",
|
||||
"system_users_protocol_group": "Systemusers protocol group",
|
||||
"system_users_username_group": "systemusers username group",
|
||||
"system_users_name_group": "Systemuser name",
|
||||
"system_users_protocol_group": "Systemuser protocol",
|
||||
"system_users_username_group": "systemuser username",
|
||||
"apply_login_asset": "Apply login asset",
|
||||
"apply_login_system_user": "Apply login system user",
|
||||
"apply_login_user": "Apply login user",
|
||||
@@ -136,6 +136,7 @@
|
||||
"Disk": "Disk",
|
||||
"AdDomain": "AD Domain",
|
||||
"AdDomainHelpText": "AD domain provided to domain users for login",
|
||||
"SetAdDomainNoDisabled": "If AD domain is set, it cannot be modified",
|
||||
"Domain": "Domain",
|
||||
"DomainDetail": "Domain detail",
|
||||
"DomainHelpMessage": "The domain function is added to address the fact that some environments (such as the hybrid cloud) cannot be connected directly by jumping on the gateway server.\nJMS => Domain gateway => Target assets",
|
||||
@@ -468,6 +469,7 @@
|
||||
"failedConditions": "cron expression error"
|
||||
},
|
||||
"Cycle": "Cycle",
|
||||
"FormatError": "Format error",
|
||||
"WeekCronSelect": {
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
@@ -893,6 +895,9 @@
|
||||
"authSAML2Xml": "IDP metadata XML",
|
||||
"authSAML2MetadataUrl": "IDP metadata URL",
|
||||
"IdpMetadataHelpText": "Choose one of IDP metadata URL and IDP metadata XML parameters. IDP metadata URL has high priority",
|
||||
"IdpMetadataUrlHelpText": "Load IDP Metadata from remote url",
|
||||
"authSAMLKeyHelpText": "SP cert and private key, using communicate with IDP",
|
||||
"authSAMLCertHelpText": "After upload cert and private key, View SP Metadata",
|
||||
"authSAML2AdvancedSettings": "Advanced Settings",
|
||||
"unselectedUser": "Unselected user",
|
||||
"auto": "Auto",
|
||||
@@ -1008,6 +1013,9 @@
|
||||
"PermissionName": "Permission name",
|
||||
"Accept": "Accept",
|
||||
"AssignedMe": "Assigned me",
|
||||
"FlowSetUp": "Flow set up",
|
||||
"ApprovalProcess": "Approval process",
|
||||
"LevelApproval": "Level approval",
|
||||
"Assignee": "Assignee",
|
||||
"RequestPerm":"Request Perm",
|
||||
"AssignedInfo":"Assigned Info",
|
||||
@@ -1252,6 +1260,7 @@
|
||||
"NodeAmount": "Node",
|
||||
"PasswordLength": "Password length",
|
||||
"PasswordStrategy": "Password strategy",
|
||||
"SecretKeyStrategy": "Secret key strategy",
|
||||
"RegularlyPerform": "Regularly perform",
|
||||
"Result": "Result",
|
||||
"Retry": "Retry",
|
||||
@@ -1259,6 +1268,7 @@
|
||||
"TaskList": "Task list",
|
||||
"TimeDelta": "Time delta",
|
||||
"Timer": "Timer",
|
||||
"TimerPeriod": "Timer period",
|
||||
"Username": "Username"
|
||||
},
|
||||
"Cloud": {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export function openTaskPage(taskId) {
|
||||
window.open(`/#/ops/celery/task/${taskId}/log/`, '', 'width=900,height=600')
|
||||
export function openTaskPage(taskId, type = '') {
|
||||
window.open(`/#/ops/celery/task/${taskId}/log/?type=${type}`, '', 'width=900,height=600')
|
||||
}
|
||||
|
||||
@@ -68,6 +68,9 @@ export default {
|
||||
hasImport: false,
|
||||
hasBulkDelete: true,
|
||||
createRoute: 'DatabaseAppCreate',
|
||||
searchConfig: {
|
||||
exclude: ['category', 'type']
|
||||
},
|
||||
moreCreates: {
|
||||
callback: (item) => {
|
||||
vm.$router.push({ name: 'DatabaseAppCreate', query: { type: item.name.toLowerCase() }})
|
||||
|
||||
@@ -56,7 +56,10 @@ export default {
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasBulkDelete: true,
|
||||
createRoute: 'KubernetesAppCreate'
|
||||
createRoute: 'KubernetesAppCreate',
|
||||
searchConfig: {
|
||||
exclude: ['category', 'type']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,9 @@ export default {
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
// createRoute: 'RemoteAppCreate',
|
||||
searchConfig: {
|
||||
exclude: ['category', 'type']
|
||||
},
|
||||
moreCreates: {
|
||||
dropdown: this.getCreateAppType(),
|
||||
callback: (app) => {
|
||||
|
||||
@@ -121,7 +121,7 @@ function getFields() {
|
||||
disabled: false
|
||||
},
|
||||
hidden: form => {
|
||||
if (form.login_mode === 'manual' || form.type === 'admin') {
|
||||
if (form.login_mode === 'manual' || form.type === 'admin' || (form.ad_domain && form.ad_domain !== '')) {
|
||||
this.fieldsMeta.auto_push.el.disabled = true
|
||||
} else {
|
||||
this.fieldsMeta.auto_push.el.disabled = false
|
||||
@@ -133,7 +133,8 @@ function getFields() {
|
||||
updateForm({ auto_generate_key: value })
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
helpText: this.$t('assets.SetAdDomainNoDisabled')
|
||||
}
|
||||
|
||||
const update_password = {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<el-col :span="8">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
<AssetRelationCard ref="assetSelect" type="primary" style="margin-top: 15px" v-bind="assetRelationConfig" />
|
||||
<RelationCard type="info" style="margin-top: 15px" v-bind="nodeRelationConfig" />
|
||||
<RelationCard ref="nodeRelation" type="info" style="margin-top: 15px" v-bind="nodeRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@@ -182,6 +182,12 @@ export default {
|
||||
const objectId = this.object.id
|
||||
const relationUrl = `/api/v1/assets/system-users-nodes-relations/?systemuser=${objectId}&node=${itemId}`
|
||||
return this.$axios.delete(relationUrl)
|
||||
},
|
||||
onAddSuccess: (objects, that) => {
|
||||
that.iHasObjects = [...that.iHasObjects, ...objects]
|
||||
vm.$refs.nodeRelation.$refs.select2.clearSelected()
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
vm.$refs.ListTable.reloadTable()
|
||||
}
|
||||
},
|
||||
assetRelationConfig: {
|
||||
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
hasCreate: false,
|
||||
createRoute: 'SystemUserCreate',
|
||||
searchConfig: {
|
||||
exclude: ['type']
|
||||
exclude: ['type', 'protocol']
|
||||
},
|
||||
moreCreates: {
|
||||
callback: (option) => {
|
||||
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
value: this.object.id,
|
||||
formatter: function(row, value) {
|
||||
const onClick = function() {
|
||||
openTaskPage(value)
|
||||
openTaskPage(value, 'ansible')
|
||||
}
|
||||
const title = this.$t('common.View')
|
||||
return <a onClick={onClick} >{ title }</a>
|
||||
|
||||
@@ -102,7 +102,7 @@ export default {
|
||||
value: this.object.latest_execution.id,
|
||||
formatter: function(row, value) {
|
||||
const onClick = function() {
|
||||
openTaskPage(value)
|
||||
openTaskPage(value, 'ansible')
|
||||
}
|
||||
const title = this.$t('common.View')
|
||||
return <a onClick={onClick} >{ title }</a>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<script>
|
||||
import BaseAuth from './Base'
|
||||
import { JsonRequired } from '@/components/DataForm/rules'
|
||||
import { JsonEditor } from '@/components/FormFields'
|
||||
|
||||
export default {
|
||||
name: 'Cas',
|
||||
components: {
|
||||
@@ -36,10 +38,7 @@ export default {
|
||||
],
|
||||
fieldsMeta: {
|
||||
CAS_RENAME_ATTRIBUTES: {
|
||||
component: 'el-input',
|
||||
el: {
|
||||
type: 'textarea'
|
||||
},
|
||||
component: JsonEditor,
|
||||
label: this.$t('setting.authUserAttrMap'),
|
||||
rules: [JsonRequired]
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
import BaseAuth from './Base'
|
||||
import { JsonRequired } from '@/components/DataForm/rules'
|
||||
import { UploadKey } from '@/components'
|
||||
import { JsonEditor } from '@/components/FormFields'
|
||||
|
||||
export default {
|
||||
name: 'SAML2',
|
||||
components: {
|
||||
@@ -29,8 +31,14 @@ export default {
|
||||
url: '/api/v1/settings/setting/?category=saml2',
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['AUTH_SAML2']],
|
||||
[this.$t('common.Params'), ['SAML2_IDP_METADATA_URL', 'SAML2_IDP_METADATA_XML', 'SAML2_SP_ADVANCED_SETTINGS']],
|
||||
[this.$t('common.Certificate'), ['SAML2_SP_CERT_CONTENT', 'SAML2_SP_KEY_CONTENT']],
|
||||
[this.$t('common.Certificate'), [
|
||||
'SAML2_SP_KEY_CONTENT',
|
||||
'SAML2_SP_CERT_CONTENT'
|
||||
]],
|
||||
[this.$t('common.Params'), [
|
||||
'SAML2_IDP_METADATA_URL', 'SAML2_IDP_METADATA_XML',
|
||||
'SAML2_SP_ADVANCED_SETTINGS'
|
||||
]],
|
||||
[this.$t('common.Other'), [
|
||||
'SAML2_LOGOUT_COMPLETELY', 'AUTH_SAML2_ALWAYS_UPDATE_USER',
|
||||
'SAML2_RENAME_ATTRIBUTES'
|
||||
@@ -43,36 +51,32 @@ export default {
|
||||
SAML2_IDP_METADATA_URL: {
|
||||
component: 'el-input',
|
||||
label: this.$t('setting.authSAML2MetadataUrl'),
|
||||
helpText: this.$t('setting.IdpMetadataHelpText')
|
||||
helpText: this.$t('setting.IdpMetadataUrlHelpText')
|
||||
},
|
||||
SAML2_IDP_METADATA_XML: {
|
||||
component: 'el-input',
|
||||
el: {
|
||||
type: 'textarea',
|
||||
rows: 8
|
||||
rows: 4
|
||||
},
|
||||
label: this.$t('setting.authSAML2Xml')
|
||||
label: this.$t('setting.authSAML2Xml'),
|
||||
helpText: this.$t('setting.IdpMetadataHelpText')
|
||||
},
|
||||
SAML2_SP_ADVANCED_SETTINGS: {
|
||||
component: 'el-input',
|
||||
el: {
|
||||
type: 'textarea',
|
||||
rows: 3
|
||||
},
|
||||
component: JsonEditor,
|
||||
label: this.$t('setting.authSAML2AdvancedSettings'),
|
||||
rules: [JsonRequired]
|
||||
},
|
||||
SAML2_SP_CERT_CONTENT: {
|
||||
component: UploadKey
|
||||
},
|
||||
SAML2_SP_KEY_CONTENT: {
|
||||
component: UploadKey
|
||||
component: UploadKey,
|
||||
helpText: this.$t('setting.authSAMLKeyHelpText')
|
||||
},
|
||||
SAML2_SP_CERT_CONTENT: {
|
||||
component: UploadKey,
|
||||
helpText: this.$t('setting.authSAMLCertHelpText') + ' <a href="/core/auth/saml2/metadata/" target="_blank">查看</a>'
|
||||
},
|
||||
SAML2_RENAME_ATTRIBUTES: {
|
||||
component: 'el-input',
|
||||
el: {
|
||||
type: 'textarea'
|
||||
},
|
||||
component: JsonEditor,
|
||||
label: this.$t('setting.authUserAttrMap'),
|
||||
rules: [JsonRequired],
|
||||
helpText: this.$t('setting.authUserAttrMapHelpText')
|
||||
|
||||
@@ -13,7 +13,7 @@ import TestLoginDialog from './TestLoginDialog'
|
||||
import { IBox } from '@/components'
|
||||
import rules from '@/components/DataForm/rules'
|
||||
import { JsonRequired } from '@/components/DataForm/rules'
|
||||
import { UpdateToken } from '@/components/FormFields'
|
||||
import { UpdateToken, JsonEditor } from '@/components/FormFields'
|
||||
|
||||
export default {
|
||||
name: 'Ldap',
|
||||
@@ -62,10 +62,7 @@ export default {
|
||||
]
|
||||
},
|
||||
AUTH_LDAP_USER_ATTR_MAP: {
|
||||
component: 'el-input',
|
||||
el: {
|
||||
type: 'textarea'
|
||||
},
|
||||
component: JsonEditor,
|
||||
label: this.$t('setting.authLdapUserAttrMap'),
|
||||
rules: [JsonRequired]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
disabled: true
|
||||
},
|
||||
rules: {
|
||||
label: '审批流程',
|
||||
label: this.$t('tickets.ApprovalProcess'),
|
||||
component: FlowRuleField,
|
||||
el: {
|
||||
level: 1
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div v-for="(item, i) of approveData" :key="i" style="margin-bottom: 10px">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ i + 1 + '级审批' }}</span>
|
||||
<span>{{ i + 1 + ' ' + vm.$t('tickets.LevelApproval') }}</span>
|
||||
</div>
|
||||
<el-radio-group v-model="item.strategy" @change="onChange()">
|
||||
<el-radio label="super_admin">{{ vm.$t('tickets.SuperAdmin') }}</el-radio>
|
||||
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
name: 'AssignedTicketList'
|
||||
},
|
||||
{
|
||||
title: '流程设置',
|
||||
title: this.$t('tickets.FlowSetUp'),
|
||||
icon: 'fa-gear',
|
||||
name: 'TicketFlow',
|
||||
hidden: () => {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import ListTable from '@/components/ListTable'
|
||||
import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
import { APPROVE, REJECT, CLOSED } from './const'
|
||||
export default {
|
||||
name: 'TicketListTable',
|
||||
components: {
|
||||
@@ -105,14 +106,32 @@ export default {
|
||||
hasCreate: false,
|
||||
hasBulkDelete: false,
|
||||
searchConfig: {
|
||||
default: {
|
||||
status: {
|
||||
key: 'status',
|
||||
exclude: ['state'],
|
||||
options: [
|
||||
{
|
||||
value: 'state',
|
||||
label: this.$t('tickets.action'),
|
||||
value: 'open',
|
||||
valueLabel: this.$t('tickets.Pending')
|
||||
children: [
|
||||
{
|
||||
default: true,
|
||||
value: 'open',
|
||||
label: this.$t('tickets.Pending')
|
||||
},
|
||||
{
|
||||
value: APPROVE,
|
||||
label: this.$t('tickets.Approved')
|
||||
},
|
||||
{
|
||||
value: REJECT,
|
||||
label: this.$t('tickets.Rejected')
|
||||
},
|
||||
{
|
||||
value: CLOSED,
|
||||
label: this.$t('tickets.Closed')
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
createTitle: this.$t('common.RequestTickets'),
|
||||
hasMoreActions: false,
|
||||
|
||||
Reference in New Issue
Block a user