CN-544 feat: 实体详情增加dns筛选(部分)

This commit is contained in:
chenjinsong
2022-05-11 17:50:40 +08:00
parent b3f6b5c7ea
commit 1077ea09b0
12 changed files with 205 additions and 7741 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "cn-icon"; /* Project id 2614877 */ font-family: "cn-icon"; /* Project id 2614877 */
src: url('iconfont.woff2?t=1649728125883') format('woff2'), src: url('iconfont.woff2?t=1652249170229') format('woff2'),
url('iconfont.woff?t=1649728125883') format('woff'), url('iconfont.woff?t=1652249170229') format('woff'),
url('iconfont.ttf?t=1649728125883') format('truetype'); url('iconfont.ttf?t=1652249170229') format('truetype');
} }
.cn-icon { .cn-icon {
@@ -13,6 +13,22 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.cn-icon-org:before {
content: "\e770";
}
.cn-icon-role:before {
content: "\e771";
}
.cn-icon-os:before {
content: "\e772";
}
.cn-icon-software:before {
content: "\e773";
}
.cn-icon-report:before { .cn-icon-report:before {
content: "\e76f"; content: "\e76f";
} }

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -34,14 +34,14 @@
<template #default="scope" :column="item"> <template #default="scope" :column="item">
<span v-if="item.prop === 'dataRange'"> <span v-if="item.prop === 'dataRange'">
<template v-if="scope.row.startTime && scope.row.endTime"> <template v-if="scope.row.startTime && scope.row.endTime">
{{dateFormatByAppearance(scope.row.startTime)}}-{{dateFormatByAppearance(scope.row.endTime)}} {{dateFormatByAppearance(scope.row.startTime)}}<span style="padding: 0 5px">-</span>{{dateFormatByAppearance(scope.row.endTime)}}
</template> </template>
</span> </span>
<span v-else-if="item.prop === 'type'"> <span v-else-if="item.prop === 'type'">
{{scope.row.reportTemp.name}} {{scope.row.reportTemp.name}}
</span> </span>
<span v-else-if="item.prop === 'state'"> <span v-else-if="item.prop === 'state'">
{{getJobStatus(scope.row.state)}} {{getJobStatus(scope.row)}}
</span> </span>
<span v-else>{{scope.row[item.prop]}}</span> <span v-else>{{scope.row[item.prop]}}</span>
</template> </template>
@@ -56,18 +56,24 @@
</template> </template>
<template #default="scope"> <template #default="scope">
<div class="table-operation-items" v-if="scope.row.state === 1"> <div class="table-operation-items" v-if="scope.row.state === 1">
<div class="table-operation-item--down" @click="tableOperation(['download', scope.row, 1])"> <div class="table-operation-item--no-border" @click="tableOperation(['download', scope.row, 1])">
<loading :loading="loadingTableId === scope.row.id"></loading> <loading :loading="loadingTableId === scope.row.id"></loading>
<svg class="icon" aria-hidden="true" :class="{'table-operation-all-loading': loadingTableId}"> <svg class="icon" aria-hidden="true" :class="{'table-operation-all-loading': loadingTableId}">
<use xlink:href="#cn-icon-download2"></use> <use xlink:href="#cn-icon-download2"></use>
</svg> </svg>
</div> </div>
<div class="table-operation-item--preview" @click="tableOperation(['preview', scope.row])"> <div class="table-operation-item--no-border" @click="tableOperation(['preview', scope.row])">
<loading :loading="loadingPreviewId === scope.row.id"></loading> <loading :loading="loadingPreviewId === scope.row.id"></loading>
<svg class="icon" aria-hidden="true" :class="{'table-operation-all-loading': loadingPreviewId}"> <svg class="icon" aria-hidden="true" :class="{'table-operation-all-loading': loadingPreviewId}">
<use xlink:href="#cn-icon-preview"></use> <use xlink:href="#cn-icon-preview"></use>
</svg> </svg>
</div> </div>
<div class="table-operation-item--no-border" @click="tableOperation(['rerun', scope.row])">
<loading :loading="loadingPreviewId === scope.row.id"></loading>
<svg class="icon2" aria-hidden="true" :class="{'table-operation-all-loading': loadingPreviewId}">
<use xlink:href="#cn-icon-refresh"></use>
</svg>
</div>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@@ -101,11 +107,11 @@ export default {
prop: 'name', prop: 'name',
show: true, show: true,
sortable: 'custom' sortable: 'custom'
}, { }, /* {
label: this.$t('config.chart.remark'), label: this.$t('config.chart.remark'),
prop: 'remark', prop: 'remark',
show: true show: true
}, { }, */{
label: this.$t('overall.type'), label: this.$t('overall.type'),
prop: 'type', prop: 'type',
show: true, show: true,
@@ -115,6 +121,10 @@ export default {
prop: 'dataRange', prop: 'dataRange',
show: true, show: true,
minWidth: 110 minWidth: 110
}, {
label: this.$t('overall.completionTime'),
prop: 'finishTime',
show: true
}, { }, {
label: this.$t('overall.status'), label: this.$t('overall.status'),
prop: 'state', prop: 'state',
@@ -135,11 +145,11 @@ export default {
} }
}, },
methods: { methods: {
getJobStatus (state) { getJobStatus (report) {
if (state === 0) { if (report.state === 1 && report.upload === 1) {
return this.$t('overall.inProgress')
} else if (state === 1) {
return this.$t('overall.completed') return this.$t('overall.completed')
} else {
return this.$t('overall.inProgress')
} }
}, },
selectionChange (objs) { selectionChange (objs) {

View File

@@ -77,65 +77,6 @@ export const echartsFontSize = {
labelThirdFontSize: 14// >=2560 labelThirdFontSize: 14// >=2560
} }
export const entityFilterType = {
ip: [
{
column: 'country_distinct_count',
labelI18nCode: 'overall.country',
icon: 'cn-icon cn-icon-country'
},
{
column: 'province_distinct_count',
labelI18nCode: 'overall.province',
icon: 'cn-icon cn-icon-position'
},
{
column: 'city_distinct_count',
labelI18nCode: 'overall.city',
icon: 'cn-icon cn-icon-city'
},
{
column: 'asn_distinct_count',
labelI18nCode: 'entities.asn',
icon: 'cn-icon cn-icon-cloud'
}
],
domain: [
{
column: 'categoryGroupDistinctCount',
labelI18nCode: 'entities.domainDetail.categoryGroup',
icon: 'cn-icon cn-icon-category'
},
{
column: 'categoryDistinctCount',
labelI18nCode: 'entities.category',
icon: 'cn-icon cn-icon-sub-category'
},
{
column: 'categoryGroupDistinctCount',
labelI18nCode: 'entities.reputationLevel',
icon: 'cn-icon cn-icon-credit'
}
],
app: [
{
column: 'categoryDistinctCount',
labelI18nCode: 'entities.category',
icon: 'cn-icon cn-icon-category'
},
{
column: 'subcategoryDistinctCount',
labelI18nCode: 'entities.subcategory',
icon: 'cn-icon cn-icon-sub-category'
},
{
column: 'riskDistinctCount',
labelI18nCode: 'entities.risk',
icon: 'cn-icon cn-icon-risk'
}
]
}
export const unitTypes = { export const unitTypes = {
time: 'time', time: 'time',
number: 'number', number: 'number',

View File

@@ -4,7 +4,7 @@
<div class="explorer-search__input"> <div class="explorer-search__input">
<advanced-search <advanced-search
ref="search" ref="search"
:column-list="columnList" :column-list="columnList[pageType]"
:operator-list="operatorList" :operator-list="operatorList"
:connection-list="connectionList" :connection-list="connectionList"
:full-text="false" :full-text="false"
@@ -22,50 +22,79 @@
<script> <script>
import AdvancedSearch from '@/components/advancedSearch/Index' import AdvancedSearch from '@/components/advancedSearch/Index'
import { humpToLine } from '@/utils/tools' import { humpToLine } from '@/utils/tools'
import {columnType} from "@/components/advancedSearch/meta/meta";
import SqlParser from "@/components/advancedSearch/meta/sql-parser";
export default { export default {
name: 'DetectionSearch', name: 'DetectionSearch',
props: {
pageType: String
},
components: { components: {
AdvancedSearch AdvancedSearch
}, },
data () { data () {
return { return {
columnList: [ columnList: {
{ securityEvent: [
name: 'event_severity', {
type: 'string', name: 'event_severity',
label: 'Event severity' type: 'string',
}, label: 'Event severity'
{ },
name: 'security_type', {
type: 'string', name: 'security_type',
label: 'Security type' type: 'string',
}, label: 'Security type'
{ },
name: 'event_type', {
type: 'string', name: 'victim_ip',
label: 'Event type' type: 'string',
}, label: 'Victim IP'
{ },
name: 'victim_ip', {
type: 'string', name: 'victim_location_country',
label: 'Victim IP' type: 'string',
}, label: 'Victim location'
{ },
name: 'victim_location_country', {
type: 'string', name: 'offender_ip',
label: 'Victim location' type: 'string',
}, label: 'Offender IP'
{ },
name: 'offender_ip', {
type: 'string', name: 'offender_location_country',
label: 'Offender IP' type: 'string',
}, label: 'Offender location'
{ }
name: 'offender_location_country', ],
type: 'string', performanceEvent: [
label: 'Offender location' {
} name: 'event_severity',
], type: 'string',
label: 'Event severity'
},
{
name: 'event_type',
type: 'string',
label: 'Event type'
},
{
name: 'app_name',
type: 'string',
label: 'APP name'
},
{
name: 'domain',
type: 'string',
label: 'Domain'
},
{
name: 'server_ip',
type: 'string',
label: 'IP'
}
]
},
operatorList: ['=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE'], operatorList: ['=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE'],
connectionList: [ connectionList: [
{ {
@@ -81,7 +110,18 @@ export default {
}, },
methods: { methods: {
search (metaList, formatSql) { search (metaList, formatSql) {
this.$emit('search', metaList, formatSql) let sql = formatSql
// 全文搜索处理
if (metaList && this.$_.isArray(metaList)) {
const hasFullText = metaList.some(meta => {
return meta.column && meta.column.type === columnType.fullText
})
if (hasFullText) {
const parser = new SqlParser(metaList, this.columnList[this.pageType])
sql = parser.parseMetaToSql(metaList, true)
}
}
this.$emit('search', metaList, sql)
}, },
changeParams (params) { // params: { column: columnName, oldValue: [...], newValue: [...] } changeParams (params) { // params: { column: columnName, oldValue: [...], newValue: [...] }
// 向下传递时需要再转换一次param格式为[{column, operator, value}, ...] // 向下传递时需要再转换一次param格式为[{column, operator, value}, ...]

View File

@@ -10,6 +10,7 @@
<!-- 搜索组件 --> <!-- 搜索组件 -->
<detection-search <detection-search
ref="search" ref="search"
:page-type="pageType"
@search="search" @search="search"
></detection-search> ></detection-search>
<!-- 内容区 --> <!-- 内容区 -->
@@ -230,7 +231,9 @@ export default {
isStatisticsSeverityNoData: false, isStatisticsSeverityNoData: false,
isStatisticsCategoryNoData: false, isStatisticsCategoryNoData: false,
isStatisticsActiveAttackNoData: false, isStatisticsActiveAttackNoData: false,
loading: false loading: false,
oldActiveEntitySearchValue: ''
} }
}, },
methods: { methods: {
@@ -462,7 +465,7 @@ export default {
data.sort(reverseSortBy('count')) data.sort(reverseSortBy('count'))
data = data.slice(0, 5) data = data.slice(0, 5)
option.series[0].data = data.map(d => { option.series[0].data = data.map(d => {
return [d.count, d.name] return [d.count, d.name, d.entityType]
}).reverse() }).reverse()
detectionChart.setOption(option) detectionChart.setOption(option)
extensionEchartY(detectionChart)// y轴标签过长时鼠标悬浮显示所有内容 extensionEchartY(detectionChart)// y轴标签过长时鼠标悬浮显示所有内容
@@ -470,7 +473,41 @@ export default {
const vm = this const vm = this
detectionChart.off('click') detectionChart.off('click')
detectionChart.on('click', e => { detectionChart.on('click', e => {
vm.filterData.performanceEvent[0].value = vm.triggerFilterDataValue(vm.filterData.performanceEvent[0].value, e.data[1]) const entityType = e.data[2]
let column = ''
if (entityType) {
switch (entityType) {
case 'app': {
column = 'app_name'
break
}
case 'domain': {
column = 'domain'
break
}
case 'ip': {
column = 'server_ip'
break
}
default: {
break
}
}
if (column) {
// 点击的name和上次的name一致则清空该项条件
if (vm.oldActiveEntitySearchValue === e.data[1]) {
vm.$refs.search.changeParams({ column: column, oldValue: [vm.oldActiveEntitySearchValue], newValue: [] })
vm.$nextTick(() => {
vm.oldActiveEntitySearchValue = ''
})
} else {
vm.$refs.search.changeParams({ column: column, oldValue: vm.oldActiveEntitySearchValue ? [vm.oldActiveEntitySearchValue] : [], newValue: [e.data[1]] })
vm.$nextTick(() => {
vm.oldActiveEntitySearchValue = e.data[1]
})
}
}
}
}) })
} }
}).catch(error => { }).catch(error => {

View File

@@ -149,7 +149,7 @@ import DateTimeRange from '@/components/common/TimeRange/DateTimeRange'
import TimeRefresh from '@/components/common/TimeRange/TimeRefresh' import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
import EntityFilter from '@/views/entityExplorer/EntityFilter' import EntityFilter from '@/views/entityExplorer/EntityFilter'
import EntityList from '@/views/entityExplorer/entityList/EntityList' import EntityList from '@/views/entityExplorer/entityList/EntityList'
import { entityType, entityFilterType, defaultPageSize, riskLevelMapping } from '@/utils/constants' import { entityType, defaultPageSize, riskLevelMapping } from '@/utils/constants'
import { get } from '@/utils/http' import { get } from '@/utils/http'
import { api } from '@/utils/api' import { api } from '@/utils/api'
import { getNowTime, getSecond } from '@/utils/date-util' import { getNowTime, getSecond } from '@/utils/date-util'
@@ -202,28 +202,28 @@ export default {
label: this.$t('overall.country'), label: this.$t('overall.country'),
column: 'countryDistinctCount', column: 'countryDistinctCount',
topColumn: 'ip_location_country', // top弹框查询字段 topColumn: 'ip_location_country', // top弹框查询字段
icon: entityFilterType.ip[0].icon, icon: 'cn-icon cn-icon-country',
value: 0 value: 0
}, },
{ {
label: this.$t('overall.province'), label: this.$t('overall.province'),
column: 'provinceDistinctCount', column: 'provinceDistinctCount',
topColumn: 'ip_location_province', // top弹框查询字段 topColumn: 'ip_location_province', // top弹框查询字段
icon: entityFilterType.ip[1].icon, icon: 'cn-icon cn-icon-position',
value: 0 value: 0
}, },
{ {
label: this.$t('overall.city'), label: this.$t('overall.city'),
column: 'cityDistinctCount', column: 'cityDistinctCount',
topColumn: 'ip_location_city', // top弹框查询字段 topColumn: 'ip_location_city', // top弹框查询字段
icon: entityFilterType.ip[2].icon, icon: 'cn-icon cn-icon-city',
value: 0 value: 0
}, },
{ {
label: this.$t('entities.asn'), label: this.$t('entities.asn'),
column: 'asnDistinctCount', column: 'asnDistinctCount',
topColumn: 'ip_asn', // top弹框查询字段 topColumn: 'ip_asn', // top弹框查询字段
icon: entityFilterType.ip[3].icon, icon: 'cn-icon cn-icon-cloud',
value: 0 value: 0
} }
] ]
@@ -237,21 +237,21 @@ export default {
label: this.$t('entities.category'), label: this.$t('entities.category'),
column: 'categoryDistinctCount', column: 'categoryDistinctCount',
topColumn: 'app_category', // top弹框查询字段 topColumn: 'app_category', // top弹框查询字段
icon: entityFilterType.app[0].icon, icon: 'cn-icon cn-icon-category',
value: 0 value: 0
}, },
{ {
label: this.$t('entities.subcategory'), label: this.$t('entities.subcategory'),
column: 'subcategoryDistinctCount', column: 'subcategoryDistinctCount',
topColumn: 'app_subcategory', // top弹框查询字段 topColumn: 'app_subcategory', // top弹框查询字段
icon: entityFilterType.app[1].icon, icon: 'cn-icon cn-icon-sub-category',
value: 0 value: 0
}, },
{ {
label: this.$t('entities.risk'), label: this.$t('entities.risk'),
column: 'riskDistinctCount', column: 'riskDistinctCount',
topColumn: 'app_risk', // top弹框查询字段 topColumn: 'app_risk', // top弹框查询字段
icon: entityFilterType.app[2].icon, icon: 'cn-icon cn-icon-risk',
value: 0 value: 0
} }
] ]
@@ -265,21 +265,56 @@ export default {
label: this.$t('entities.domainDetail.categoryGroup'), label: this.$t('entities.domainDetail.categoryGroup'),
column: 'categoryGroupDistinctCount', column: 'categoryGroupDistinctCount',
topColumn: 'domain_category_group', // top弹框查询字段 topColumn: 'domain_category_group', // top弹框查询字段
icon: entityFilterType.domain[0].icon, icon: 'cn-icon cn-icon-category',
value: 0 value: 0
}, },
{ {
label: this.$t('entities.category'), label: this.$t('entities.category'),
column: 'categoryDistinctCount', column: 'categoryDistinctCount',
topColumn: 'domain_category', // top弹框查询字段 topColumn: 'domain_category', // top弹框查询字段
icon: entityFilterType.domain[1].icon, icon: 'cn-icon cn-icon-sub-category',
value: 0 value: 0
}, },
{ {
label: this.$t('entities.reputationLevel'), label: this.$t('entities.reputationLevel'),
column: 'reputationLevelDistinctCount', column: 'reputationLevelDistinctCount',
topColumn: 'domain_reputation_level', // top弹框查询字段 topColumn: 'domain_reputation_level', // top弹框查询字段
icon: entityFilterType.domain[2].icon, icon: 'cn-icon cn-icon-credit',
value: 0
}
]
},
{
type: 'dns',
title: 'DNS',
totalCount: 0,
data: [
{
label: this.$t('overall.dnsServerInfo.role'),
column: 'dnsServerRoleCount',
topColumn: 'dns_server_role',
icon: 'cn-icon cn-icon-role',
value: 0
},
{
label: this.$t('dns.managementOrganization'),
column: 'dnsServerOrgCount',
topColumn: 'dns_server_org',
icon: 'cn-icon cn-icon-org',
value: 0
},
{
label: this.$t('overall.dnsServerInfo.software'),
column: 'dnsServerSoftwareCount',
topColumn: 'dns_server_software',
icon: 'cn-icon cn-icon-software',
value: 0
},
{
label: this.$t('overall.dnsServerInfo.system'),
column: 'dnsServerOsCount',
topColumn: 'dns_server_os',
icon: 'cn-icon cn-icon-os',
value: 0 value: 0
} }
] ]