Merge pull request #202 from jumpserver/dev

merge(master): Merge from dev to master
This commit is contained in:
八千流 2020-07-16 11:12:33 +08:00 committed by GitHub
commit aad23f3de5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 185 additions and 86 deletions

View File

@ -176,7 +176,7 @@ export default {
this.$axios.delete(`/api/v1/assets/asset-users/${val.cellValue}/`).then(() => {
this.$message.success(this.$t('common.deleteSuccessMsg'))
this.$refs.ListTable.reloadTable()
}).catch(() => this.$message.error(this.$t('common.deleteFailedMsg')))
})
}
},
{

View File

@ -10,6 +10,7 @@
<script>
import BaseFormatter from './base'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'ChoicesFormatter',
extends: BaseFormatter,
@ -54,7 +55,7 @@ export default {
return this.formatterArgs.tipStatus(this.cellValue, vm)
},
tipTime() {
return this.cellValue.datetime
return toSafeLocalDateStr(this.cellValue.datetime)
}
}
}

View File

@ -4,14 +4,14 @@
<script>
import BaseFormatter from './base'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'DateFormatter',
extends: BaseFormatter,
data() {
let value
if (this.cellValue) {
const dt = new Date(this.cellValue)
value = this.$d(dt, 'medium')
value = toSafeLocalDateStr(this.cellValue)
} else {
value = ''
}

View File

@ -546,6 +546,7 @@
"terminalDetail": "终端详情",
"terminalUpdate": "更新终端",
"terminate": "终断",
"sessionTerminate": "会话终断",
"test": "测试",
"type": "类型",
"user": "用户",
@ -553,7 +554,8 @@
"common": "普通"
},
"Monitor": "监控",
"TerminateTaskSendSuccessMsg": "终断任务已下发,请稍后刷新表格查看"
"sessionMonitor": "监控",
"TerminateTaskSendSuccessMsg": "终断任务已下发,请稍后刷新查看"
},
"setting": {
"ApiKeyList": "API Key 列表",
@ -584,6 +586,7 @@
"authLdapSearchOu": "用户OU",
"authLdapServerUri": "LDAP地址",
"authLdapUserAttrMap": "LDAP属性映射",
"unselectedUser": "没有选择用户",
"auto": "自动",
"basicSetting": "基本设置",
"communityEdition": "社区版",
@ -636,6 +639,11 @@
"securityPasswordUpperCase": "开启后,用户密码修改、重置必须包含大写字母",
"securityServiceAccountRegistration": "允许使用bootstrap token注册终端, 当终端注册成功后可以禁止"
},
"validatorMessage": {
"EnsureThisValueIsGreaterThanOrEqualTo3": "请确保该值大于或者等于 3",
"EnsureThisValueIsGreaterThanOrEqualTo5": "请确保该值大于或者等于 5",
"EnsureThisValueIsGreaterThanOrEqualTo6": "请确保该值大于或者等于 6"
},
"import": "导入",
"importLdapUserTip": "请先提交LDAP配置再进行导入",
"importLdapUserTitle": "LDAP 用户列表",
@ -805,6 +813,9 @@
"ExecutionDetail": "执行详情",
"ExecutionList": "执行列表",
"ExecutionTimes": "执行次数",
"validatorMessage": {
"EnsureThisValueIsGreaterThanOrEqualTo1": "请确保该值大于或者等于 1"
},
"HelpText": {
"CrontabOfCreateUpdatePage": "例如:每周日 03:05 执行 <5 3 * * 0> <br/> 使用5位 Linux crontab 表达式 <分 时 日 月 星期> <a href=\"https://tool.lu/crontab/\" target=\"_blank\">在线工具</a> <br/> 如果同时设置了定期执行和周期执行,优先使用定期执行",
"IntervalOfCreateUpdatePage": "单位:时",

View File

@ -545,6 +545,7 @@
"terminalDetail": "Terminal detail",
"terminalUpdate": "Update terminal",
"terminate": "Terminate",
"sessionTerminate": "Session Terminate",
"test": "Test",
"type": "Type",
"user": "Use",
@ -552,6 +553,7 @@
"common": "common"
},
"Monitor": "Monitor",
"sessionMonitor": "Session Monitor",
"TerminateTaskSendSuccessMsg": "Terminate task has been send, Please check later"
},
"setting": {
@ -583,6 +585,7 @@
"authLdapSearchOu": "User OU",
"authLdapServerUri": "LDAP server",
"authLdapUserAttrMap": "User attr map",
"unselectedUser": "Unselected user",
"auto": "Auto",
"basicSetting": "Basic setting",
"communityEdition": "Community edition",
@ -635,6 +638,11 @@
"securityPasswordUpperCase": "After opening, the user password changes and resets must contain uppercase letters",
"securityServiceAccountRegistration": "Allow using bootstrap token register service account, when terminal setup, can disable it"
},
"validatorMessage": {
"EnsureThisValueIsGreaterThanOrEqualTo3": "Ensure this value is greater than or equal to 3",
"EnsureThisValueIsGreaterThanOrEqualTo5": "Ensure this value is greater than or equal to 5",
"EnsureThisValueIsGreaterThanOrEqualTo6": "Ensure this value is greater than or equal to 6"
},
"import": "Import",
"importLdapUserTip": "Please submit the LDAP configuration before import",
"importLdapUserTitle": "LDAP user list",
@ -803,6 +811,9 @@
"ExecutionDetail": "Execution detail",
"ExecutionList": "Execution list",
"ExecutionTimes": "Execution times",
"validatorMessage": {
"EnsureThisValueIsGreaterThanOrEqualTo1": "Ensure this value is greater than or equal to 1"
},
"HelpText": {
"CrontabOfCreateUpdatePage": "For example: every Sunday at 03:05 execute <5 3 * * 0> <br/> Using the 5-bit Linux crontab expression <minute hour day month week> (<a href=\"https://tool.lu/crontab/\" target=\"_blank\"> Online tool </a>) <br/> If both regularly perform and cycle perform execution are set, use regularly perform first",
"IntervalOfCreateUpdatePage": "Unit: hour",

View File

@ -11,7 +11,7 @@ export default [
{
path: '',
name: 'RemoteAppList',
meta: { title: i18n.t('route.RemoteApp') },
meta: { title: i18n.t('route.RemoteApp'), activeMenu: '/applications/remote-apps' },
component: () => import('@/views/applications/RemoteApp/RemoteAppList')
},
{

View File

@ -12,7 +12,7 @@ export default [
path: '',
name: 'AssetList',
component: () => import('@/views/assets/Asset/AssetList.vue'),
meta: { title: i18n.t('route.AssetList') }
meta: { title: i18n.t('route.AssetList'), activeMenu: '/assets/assets' }
},
{
path: 'create',
@ -47,7 +47,7 @@ export default [
path: '',
name: 'DomainList',
component: () => import('@/views/assets/Domain/DomainList.vue'),
meta: { title: i18n.t('route.DomainList') }
meta: { title: i18n.t('route.DomainList'), activeMenu: '/assets/domains' }
},
{
path: 'create',
@ -104,7 +104,7 @@ export default [
path: '',
name: 'AdminUserList',
component: () => import('@/views/assets/AdminUser/AdminUserList'),
meta: { title: i18n.t('route.AdminUserList') }
meta: { title: i18n.t('route.AdminUserList'), activeMenu: '/assets/admin-users' }
},
{
path: 'create',
@ -174,7 +174,7 @@ export default [
path: '',
name: 'CommandFilterList',
component: () => import('@/views/assets/CommandFilter/CommandFilterList.vue'),
meta: { title: i18n.t('route.CommandFilterList') }
meta: { title: i18n.t('route.CommandFilterList'), activeMenu: '/assets/cmd-filters' }
},
{
path: ':id/update',
@ -265,7 +265,7 @@ export default [
path: '',
name: 'LabelList',
component: () => import('@/views/assets/Label/LabelList.vue'),
meta: { title: i18n.t('route.LabelList') }
meta: { title: i18n.t('route.LabelList'), activeMenu: '/assets/labels' }
},
{
path: 'create',

View File

@ -42,7 +42,7 @@ const remoteAppPermissionRoutes = [
path: '',
name: 'RemoteAppPermissionList',
component: () => import('@/views/perms/RemoteAppPermission/RemoteAppPermissionList'),
meta: { title: i18n.t('route.RemoteAppPermission') }
meta: { title: i18n.t('route.RemoteAppPermission'), activeMenu: '/perms/remote-app-permissions' }
},
{

View File

@ -96,7 +96,7 @@ td .el-button.el-button--mini {
font-weight: 600;
}
.el-button.el-button--default:focus:not(.is-disabled), .el-button.el-button--default:hover:not(.is-disabled) {
.el-button.el-button--default:hover:not(.is-disabled) {
color: #606266;
border-color: #d2d2d2;
background-color: #e6e6e6;
@ -431,7 +431,7 @@ a {
.el-button--danger.is-plain {
color: $--color-danger;
background: white;
background: #ffffff;
border-color: $--color-danger;
}

View File

@ -86,6 +86,12 @@ export default {
}
}
},
{
prop: 'comment',
label: this.$t('assets.Comment'),
showOverflowTooltip: true,
width: '180px'
},
{
prop: 'id',
align: 'center',
@ -136,10 +142,10 @@ export default {
},
methods: {
refreshAllFavorites() {
this.tableConfig.columns[3].formatterArgs.loading = true
this.tableConfig.columns[4].formatterArgs.loading = true
this.$axios.get('/api/v1/assets/favorite-assets/').then(resp => {
this.allFavorites = resp
this.tableConfig.columns[3].formatterArgs.loading = false
this.tableConfig.columns[4].formatterArgs.loading = false
})
},
addOrDeleteFavorite(assetId) {

View File

@ -7,6 +7,7 @@
:url="url"
:get-method="getMethod"
class="password-update"
:update-success-next-route="updateSuccessNextRoute"
/>
</IBox>
</template>
@ -50,6 +51,9 @@ export default {
type: 'password'
}
}
},
updateSuccessNextRoute: {
path: '/'
}
}
},

View File

@ -50,6 +50,7 @@ export default {
domain: {
el: {
multiple: false,
clearable: true,
ajax: {
url: '/api/v1/assets/domains/'
}

View File

@ -9,7 +9,7 @@
<script type="text/jsx">
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { getDaysAgo } from '@/utils/common'
import { Dialog, ListTable } from '@/components'
import { DisplayFormatter } from '@/components/ListTable/formatters'
import { setUrlParam } from '@/utils/common'
@ -66,10 +66,7 @@ export default {
}
},
date_start: {
width: '160px',
formatter: function(row, cell, value) {
return toSafeLocalDateStr(value)
}
width: '160px'
}
},
extraQuery: {

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { getDaysAgo } from '@/utils/common'
export default {
components: {
@ -42,11 +42,6 @@ export default {
},
is_success: {
width: '80px'
},
date_start: {
formatter: function(row, cell, value) {
return toSafeLocalDateStr(value)
}
}
},
extraQuery: {

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { getDaysAgo } from '@/utils/common'
export default {
components: {
@ -40,10 +40,7 @@ export default {
width: '100px'
},
datetime: {
width: '160px',
formatter: function(row, cell, value) {
return toSafeLocalDateStr(value)
}
width: '160px'
},
reason: {
showOverflowTooltip: true

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { getDaysAgo } from '@/utils/common'
export default {
components: {
@ -29,10 +29,7 @@ export default {
showOverflowTooltip: true
},
datetime: {
width: '160px',
formatter: function(row, cell, value) {
return toSafeLocalDateStr(value)
}
width: '160px'
},
remote_addr: {
width: '140px'

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { getDaysAgo } from '@/utils/common'
export default {
components: {
@ -29,10 +29,7 @@ export default {
showOverflowTooltip: true
},
datetime: {
width: '180px',
formatter: function(row, cell, value) {
return toSafeLocalDateStr(value)
}
width: '180px'
}
},
extraQuery: {

View File

@ -14,6 +14,7 @@
import DetailCard from '@/components/DetailCard'
import RunInfoCard from '../RunInfoCard/index'
import { toLastFailureDisplay, toLastSucessDisplay } from './business'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'TaskDetail',
@ -58,7 +59,7 @@ export default {
},
{
key: this.$t('common.dateCreated'),
value: this.$d(new Date(this.object.date_created))
value: toSafeLocalDateStr(this.object.date_created)
},
{
key: this.$t('ops.totalVersions'),
@ -74,7 +75,7 @@ export default {
},
{
key: this.$t('ops.lastRun'),
value: this.$d(new Date(this.object.latest_execution.date_finished))
value: toSafeLocalDateStr(this.object.latest_execution.date_finished)
},
{
key: this.$t('ops.timeDelta'),

View File

@ -5,6 +5,7 @@
<script type="text/jsx">
import ListTable from '@/components/ListTable'
import { DetailFormatter } from '@/components/ListTable/formatters'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'TaskHistory',
@ -25,6 +26,9 @@ export default {
'date_start', 'stat', 'ratio', 'is_finished', 'is_success', 'timedelta', 'adhoc_short_id', 'actions'
],
columnsMeta: {
date_start: {
formatter: (row) => toSafeLocalDateStr(row.date_start)
},
stat: {
label: this.$t('ops.stat'),
align: 'center',

View File

@ -12,6 +12,7 @@
<script>
import DetailCard from '@/components/DetailCard/index'
import QuickActions from '@/components/QuickActions'
import { terminateSession } from '@/api/sessions'
export default {
name: 'SessionDetailCard',
components: {
@ -68,33 +69,75 @@ export default {
},
quickActions() {
const vm = this
return [
{
title: this.$t('sessions.replaySession'),
attrs: {
type: 'primary',
label: this.$t('sessions.go')
},
callbacks: {
click: function() {
vm.openReplaySession(vm.sessionData.id)
}
if (vm.sessionData.is_finished) {
return [
{
title: this.$t('sessions.replaySession'),
attrs: {
type: 'primary',
label: this.$t('sessions.go')
},
callbacks: {
click: function() {
vm.openReplaySession(vm.sessionData.id)
}
}
},
{
title: this.$t('sessions.downloadReplay'),
attrs: {
type: 'primary',
label: this.$t('sessions.download')
}
},
callbacks: {
click: function() {
vm.openReplayDownload(vm.sessionData.id)
{
title: this.$t('sessions.downloadReplay'),
attrs: {
type: 'primary',
label: this.$t('sessions.download')
},
callbacks: {
click: function() {
vm.openReplayDownload(vm.sessionData.id)
}
}
}
}
]
]
} else {
return [
{
title: this.$t('sessions.sessionTerminate'),
attrs: {
type: 'danger',
label: this.$t('sessions.terminate')
},
callbacks: {
click: function() {
// session reload
terminateSession(vm.sessionData.id).then(res => {
const msg = vm.$t('sessions.TerminateTaskSendSuccessMsg')
vm.$message.success(msg)
window.setTimeout(function() {
window.location.reload()
}, 50000)
}
)
}
}
},
{
title: this.$t('sessions.sessionMonitor'),
attrs: {
type: 'primary',
label: this.$t('sessions.Monitor')
},
can: () => {
return vm.sessionData.can_join
},
callbacks: {
click: function() {
// luna
const joinUrl = '/luna/join/?shareroom=' + vm.sessionData.id
window.open(joinUrl, 'height=600, width=800, top=400, left=400, toolbar=no, menubar=no, scrollbars=no, location=no, status=no')
}
}
}
]
}
}
},
methods: {

View File

@ -4,7 +4,7 @@
<script type="text/jsx">
import ListTable from '@/components/ListTable'
import { timeOffset, toSafeLocalDateStr, getDaysAgo } from '@/utils/common'
import { timeOffset, getDaysAgo } from '@/utils/common'
import { ActionsFormatter } from '@/components/ListTable/formatters'
export default {
name: 'BaseList',
@ -71,10 +71,7 @@ export default {
formatter: null
},
date_start: {
width: '100px',
formatter: function(row) {
return toSafeLocalDateStr(row.date_start)
}
width: '100px'
},
duration: {
label: this.$t('sessions.duration'),

View File

@ -48,7 +48,7 @@
<el-button type="primary" @click="testUerLoginClick">{{ $t('common.Confirm') }}</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="dialogLdapUserImport" center>
<el-dialog :visible.sync="dialogLdapUserImport" :destroy-on-close="true" center>
<div slot="title">
{{ $t('setting.importLdapUserTitle') }}
<el-alert type="success"> {{ $t('setting.importLdapUserTip') }}</el-alert>
@ -60,7 +60,7 @@
@error="handlerListTableXHRError($event)"
/>
<div slot="footer">
<el-button @click="dialogLdapUserImport = false">{{ $t('common.Cancel') }}</el-button>
<el-button @click="dialogLdapUserImport=false">{{ $t('common.Cancel') }}</el-button>
<el-button type="primary" @click="importUserClick">{{ $t('common.Import') }}</el-button>
</div>
</el-dialog>
@ -237,9 +237,13 @@ export default {
const data = {
username_list: selectIds
}
importLdapUser(data).then(res => {
this.$message.success(res.msg)
})
if (selectIds.length === 0) {
this.$message.error(this.$t('setting.unselectedUser'))
} else {
importLdapUser(data).then(res => {
this.$message.success(res.msg)
})
}
},
handlerListTableXHRError(errMsg) {
if (this.dialogLdapUserImport) {

View File

@ -29,6 +29,21 @@ export default {
}
},
data() {
var validatorLoginLimitCount = (rule, value, callback) => {
if (parseInt(value) < 3) {
return callback(new Error(this.$t('setting.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo3')))
}
}
var validatorLoginLimitTime = (rule, value, callback) => {
if (parseInt(value) < 5) {
return callback(new Error(this.$t('setting.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo5')))
}
}
var validatorPasswordMinLength = (rule, value, callback) => {
if (parseInt(value) < 6) {
return callback(new Error(this.$t('setting.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo6')))
}
}
return {
selectFields: [
[this.$t('setting.SecuritySetting'), ['SECURITY_MFA_AUTH', 'SECURITY_COMMAND_EXECUTION', 'SECURITY_SERVICE_ACCOUNT_REGISTRATION',
@ -57,13 +72,15 @@ export default {
SECURITY_LOGIN_LIMIT_COUNT: {
label: this.$t('setting.securityLoginLimitCount'),
rules: [
{ required: true }
{ required: true },
{ validator: validatorLoginLimitCount }
]
},
SECURITY_LOGIN_LIMIT_TIME: {
label: this.$t('setting.securityLoginLimitTime'),
rules: [
{ required: true }
{ required: true },
{ validator: validatorLoginLimitTime }
],
helpText: this.$t('setting.helpText.securityLoginLimitTime')
},
@ -81,7 +98,8 @@ export default {
SECURITY_PASSWORD_MIN_LENGTH: {
label: this.$t('setting.securityPasswordMinLength'),
rules: [
{ required: true }
{ required: true },
{ validator: validatorPasswordMinLength }
]
},
SECURITY_PASSWORD_UPPER_CASE: {

View File

@ -12,6 +12,8 @@
<script>
import DetailCard from '@/components/DetailCard'
import RelationCard from '@/components/RelationCard'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'GroupInfo',
components: {
@ -69,7 +71,7 @@ export default {
},
{
key: this.$t('common.dateCreated'),
value: this.object.date_created
value: toSafeLocalDateStr(this.object.date_created)
},
{
key: this.$t('common.Comment'),

View File

@ -40,7 +40,7 @@ export default {
if (formValue.update_password) {
return true
}
return this.$route.meta.action !== 'update'
return this.$route.meta.action !== 'update' || formValue.source !== 'local'
}
},
password: {

View File

@ -15,6 +15,8 @@
import DetailCard from '@/components/DetailCard'
import QuickActions from '@/components/QuickActions'
import RelationCard from '@/components/RelationCard'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'UserInfo',
components: {
@ -56,6 +58,7 @@ export default {
title: this.$t('users.quickUpdate.resetMFA'),
attrs: {
type: 'primary',
disabled: !this.object.mfa_enabled,
label: this.$t('common.Reset')
},
callbacks: {
@ -87,6 +90,7 @@ export default {
title: this.$t('users.quickUpdate.resetPassword'),
attrs: {
type: 'primary',
disabled: this.object.source !== 'local',
label: this.$t('users.quickUpdate.send')
},
callbacks: {
@ -250,19 +254,19 @@ export default {
},
{
key: this.$t('users.DateJoined'),
value: this.object.date_joined
value: toSafeLocalDateStr(this.object.date_joined)
},
{
key: this.$t('users.DateExpired'),
value: this.object.date_expired
value: toSafeLocalDateStr(this.object.date_expired)
},
{
key: this.$t('users.DatePasswordUpdated'),
value: this.object.date_password_last_updated
value: toSafeLocalDateStr(this.object.date_password_last_updated)
},
{
key: this.$t('users.DateLastLogin'),
value: this.object.last_login
value: toSafeLocalDateStr(this.object.last_login)
},
{
key: this.$t('common.Comment'),

View File

@ -46,12 +46,21 @@ export default {
actions: {
formatterArgs: {
hasDelete: () => this.currentOrgIsDefault,
canUpdate: function(row, cellValue) {
return row.can_update
},
canDelete: function(row, cellValue) {
return row.can_delete
},
extraActions: [
{
title: this.$t('users.Remove'),
name: 'remove',
type: 'warning',
has: () => !this.currentOrgIsDefault,
can: function(row, cellValue) {
return row.can_delete
},
callback: this.removeUserFromOrg
}
]