From 4d4d197a80574a789ece9b11e666060f05317ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B4=AA=E6=B4=AA?= <2498601771@qq.com> Date: Tue, 24 Oct 2023 16:02:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Ddetection=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=92=8Cfilter=E9=97=AE=E9=A2=98=EF=BC=9A1=E3=80=81?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=8F=E6=B8=85=E9=99=A4=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=EF=BC=8C=E5=8B=BE=E9=80=89=E6=9C=AA=E5=8E=BB=E9=99=A4=EF=BC=9B?= =?UTF-8?q?2=E3=80=81filter=E9=80=89=E9=A1=B9=E5=8C=85=E5=90=AB=E5=A4=A7?= =?UTF-8?q?=E5=86=99=EF=BC=8C=E7=82=B9=E5=87=BB=E6=90=9C=E7=B4=A2=E6=97=B6?= =?UTF-8?q?=E6=8A=A5=E9=94=99=EF=BC=9B3=E3=80=81=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E7=A9=BA=E6=A0=BC=E5=AF=BC=E8=87=B4=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=A4=B1=E8=B4=A5=EF=BC=9B4=E3=80=81=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=88=B7=E6=96=B0=E4=BF=9D=E7=95=99=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/advancedSearch/meta/parser.js | 10 +- src/store/modules/user.js | 2 +- src/views/detections/DetectionList.vue | 13 ++- src/views/detections/Index.vue | 101 ++++++++++++++++--- 4 files changed, 103 insertions(+), 23 deletions(-) diff --git a/src/components/advancedSearch/meta/parser.js b/src/components/advancedSearch/meta/parser.js index 11c5098e..b61aba37 100644 --- a/src/components/advancedSearch/meta/parser.js +++ b/src/components/advancedSearch/meta/parser.js @@ -1173,7 +1173,9 @@ export default class Parser { const arr = [] // 如果出现this.columnList中的字段,如IP\Domain\App\Country等,则不进行模糊搜索,将str返回出去 this.columnList.forEach(item => { - arr.push(item.label.toLowerCase()) + // todo 取消了大小写校验,后续观察是否出现问题 + // arr.push(item.label.toLowerCase()) + arr.push(item.label) }) // 因为手动输入时可能会输入and,所以将操作符的AND转换为and,统一处理 @@ -1183,7 +1185,9 @@ export default class Parser { newStr = newStr.replace(new RegExp(arr[i], 'g'), arr[i]) } // 检查str字段在arr中是否出现,true为出现过 - const result = arr.some(item => newStr.toLowerCase().includes(item)) + // todo 取消了大小写校验,后续观察是否出现问题 + // const result = arr.some(item => newStr.toLowerCase().includes(item)) + const result = arr.some(item => newStr.includes(item)) if (newStr.indexOf(' and ') > -1) { // 将单引号包裹的and拿出来放到数组tempList里,原来的单引号包裹内容用temp即'it is test keyword{键值}'代替 // 再将字符串用and转换为数组,遍历数组,发现值为temp的,获取键值,根据键值获取tempList的值组合起来, @@ -1194,7 +1198,7 @@ export default class Parser { // 将单引号包裹的and内容集合起来 while ((match = regex.exec(newStr)) !== null) { - if (match[1].includes('and')) { + if (match[1].includes(' and ')) { tempList.push(match[1]) } } diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 33589a57..5e8157a2 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -118,7 +118,7 @@ const user = { localStorage.setItem(storageKey.linkInfo, res.page.list[0].cvalue) } }) - axios.get(api.config, { params: { ckey: 'schema_entity_explore' } }).then(response => { + axios.get(api.config, { params: { ckey: 'schema_explore' } }).then(response => { const res = response.data if (response.status === 200 && res.page.list && res.page.list.length > 0) { localStorage.setItem(storageKey.schemaEntityExplore, res.page.list[0].cvalue) diff --git a/src/views/detections/DetectionList.vue b/src/views/detections/DetectionList.vue index 2e59a8ec..04abb8c8 100644 --- a/src/views/detections/DetectionList.vue +++ b/src/views/detections/DetectionList.vue @@ -69,14 +69,16 @@ export default { this.myListData.push(this.$_.cloneDeep(item)) if (item.eventInfoObj) { axios.get(`${api.detection.securityEvent.detail}/${item.eventInfoObj.ioc_type}?resource=${item.eventInfoObj.ioc_value}`).then(res => { - if (res.status === 200) { + if (res.status === 200 && this.myListData[i]) { this.myListData[i].malwareName = (this.$_.get(res, 'data.data.malware.malwareName', '-')) || '-' - } else { + } else if (this.myListData[i]) { this.myListData[i].malwareName = '-' } }).catch(e => { console.error(e) - this.myListData[i].malwareName = '-' + if (this.myListData[i]) { + this.myListData[i].malwareName = '-' + } }) } }) @@ -116,7 +118,10 @@ export default { } else { clearTimeout(this.timeout) this.noData = false - this.initData() + const timer = setTimeout(() => { + this.initData() + clearTimeout(timer) + }, 200) } } } diff --git a/src/views/detections/Index.vue b/src/views/detections/Index.vue index 27ce8432..9d01ded7 100644 --- a/src/views/detections/Index.vue +++ b/src/views/detections/Index.vue @@ -184,8 +184,8 @@ export default { securityEvent: [ { title: this.$t('overall.status'), - column: '', - topColumn: '', // todo schema暂无标识 + column: 'status', + topColumn: 'status', collapse: false, value: [], // value之间是or的关系 data: [] // 从接口动态获取,本项在获得数据后需要特殊处理左边框颜色 @@ -303,6 +303,7 @@ export default { } return { label, value: r.status, count: r.count } }) + this.isCheckFilterByQ(params, 0) } }).catch(e => { console.error(e) @@ -390,6 +391,7 @@ export default { this.statisticsSeverityData = data if (!this.$_.isEmpty(data)) { this.filterData[this.pageType][1].data = data.map(r => ({ label: r.severity, value: r.severity, count: r.count })) + this.isCheckFilterByQ(params, 1) const eventSeverityOption = this.$_.cloneDeep(pieForSeverity) eventSeverityOption.series[0].data = data.map(d => { return { value: d.count, name: d.severity, itemStyle: { color: getSeverityColor(d.severity) } } @@ -408,7 +410,7 @@ export default { if (this.pageType === 'performanceEvent') { vm.filterData.performanceEvent[0].value = vm.triggerFilterDataValue(vm.filterData.performanceEvent[0].value, e.data.name) } else if (this.pageType === 'securityEvent') { - vm.filterData.securityEvent[0].value = vm.triggerFilterDataValue(vm.filterData.securityEvent[0].value, e.data.name) + vm.filterData.securityEvent[1].value = vm.triggerFilterDataValue(vm.filterData.securityEvent[1].value, e.data.name) } }) } @@ -464,6 +466,7 @@ export default { value: r.eventType, count: r.count })) + this.isCheckFilterByQ(params, 2) const chartDom = document.getElementById(`detectionCategoryPer${this.pageType}`) let detectionChart = echarts.getInstanceByDom(chartDom) if (detectionChart) { @@ -500,6 +503,7 @@ export default { value: r.offenderIp, count: r.count })) + this.isCheckFilterByQ(params, 4) const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][4].data) this.filterData[this.pageType][4].showMore = showMore this.filterData[this.pageType][4].showIndex = showIndex @@ -538,6 +542,7 @@ export default { axios.get(api.detection[this.pageType].victimIpStatistics, { params }).then(res => { const data = res.data.data.result this.filterData[this.pageType][3].data = data.map(r => ({ label: r.victimIp, value: r.victimIp, count: r.count })) + this.isCheckFilterByQ(params, 3) const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][3].data) this.filterData[this.pageType][3].showMore = showMore this.filterData[this.pageType][3].showIndex = showIndex @@ -719,10 +724,21 @@ export default { // 参数q,避免切换页码时,地址栏参数q为空 let urlQ = '' if (param && param.str) { - urlQ = encodeURI(param.str) + // urlQ = encodeURI(param.str) + urlQ = param.str } else if (this.q) { - urlQ = encodeURI(this.q) + // urlQ = encodeURI(this.q) + urlQ = this.q } + const mode = this.$route.query.mode || 'text' + const newUrl = urlParamsHandler(window.location.href, this.$route.query, { + startTime: this.timeFilter.startTime, + endTime: this.timeFilter.endTime, + range: this.dateRangeValue, + q: urlQ, + mode: mode + }) + overwriteUrl(newUrl) this.queryFilter(urlQ) this.queryList(urlQ) }, @@ -749,8 +765,8 @@ export default { this.initVictimIpData(params) this.initSecurityTypeData(params) } else if (this.pageType === detectionPageType.performanceEvent) { - // this.initActiveEntity(params) - // this.initEventTypeData(params) + this.initActiveEntity(params) + this.initEventTypeData(params) } }, pageSize (val) { @@ -795,12 +811,43 @@ export default { t: +new Date() } }) + }, + isCheckFilterByQ (params, index) { + if (params.resource) { + let obj + if (index === 0) { + obj = this.filterData[this.pageType][index].data.find(d => params.resource.indexOf(d.value) > -1 && params.resource.indexOf('status') > -1) + } else { + obj = this.filterData[this.pageType][index].data.find(d => params.resource.indexOf(d.value) > -1) + } + if (obj) { + this.filterData[this.pageType][index].value = [obj.value] + this.filterData[this.pageType][index].flag = true + } + } else { + this.filterData[this.pageType][index].value = [] + this.filterData[this.pageType][index].flag = true + } } }, mounted () { - this.queryFilter() + let { q } = this.$route.query + + // 如果地址栏有listMode,即列表页,并非首页,则开始搜索 + if (q) { + // %位置为0是输入中文时能解码,%20,25%分别是空格和%的情况 + if (q && (q.indexOf('%') === 0 || q.indexOf('%20') > -1 || q.indexOf('%25') > -1)) { + q = decodeURI(q) + } + // %位置不为0,即内容包含非英文时 + const str1 = q.substring(q.indexOf('%'), q.indexOf('%') + 3) + if (q && q.indexOf('%') > 0 && (str1 !== '%20' || str1 === '%25')) { + q = decodeURI(q) + } + } + this.queryFilter(q) this.initFlag = false - this.queryList() + this.queryList(q) this.debounceFunc = this.$_.debounce(this.resize, 300) window.addEventListener('resize', this.debounceFunc) }, @@ -873,37 +920,61 @@ export default { 'filterData.securityEvent.0.value': { deep: true, handler (n, o) { - this.$refs.search.changeParams({ column: this.filterData.securityEvent[0].column, oldValue: o, newValue: n }) + if (!this.filterData.securityEvent[0].flag) { + this.$refs.search.changeParams({ column: this.filterData.securityEvent[0].column, oldValue: o, newValue: n }) + } else { + this.filterData.securityEvent[0].flag = false + } } }, 'filterData.securityEvent.1.value': { deep: true, handler (n, o) { - this.$refs.search.changeParams({ column: this.filterData.securityEvent[1].column, oldValue: o, newValue: n }) + if (!this.filterData.securityEvent[1].flag) { + this.$refs.search.changeParams({ column: this.filterData.securityEvent[1].column, oldValue: o, newValue: n }) + } else { + this.filterData.securityEvent[1].flag = false + } } }, 'filterData.securityEvent.2.value': { deep: true, handler (n, o) { - this.$refs.search.changeParams({ column: this.filterData.securityEvent[2].column, oldValue: o, newValue: n }) + if (!this.filterData.securityEvent[2].flag) { + this.$refs.search.changeParams({ column: this.filterData.securityEvent[2].column, oldValue: o, newValue: n }) + } else { + this.filterData.securityEvent[2].flag = false + } } }, 'filterData.securityEvent.3.value': { deep: true, handler (n, o) { - this.$refs.search.changeParams({ column: this.filterData.securityEvent[3].column, oldValue: o, newValue: n }) + if (!this.filterData.securityEvent[3].flag) { + this.$refs.search.changeParams({ column: this.filterData.securityEvent[3].column, oldValue: o, newValue: n }) + } else { + this.filterData.securityEvent[3].flag = false + } } }, 'filterData.securityEvent.4.value': { deep: true, handler (n, o) { - this.$refs.search.changeParams({ column: this.filterData.securityEvent[4].column, oldValue: o, newValue: n }) + if (!this.filterData.securityEvent[4].flag) { + this.$refs.search.changeParams({ column: this.filterData.securityEvent[4].column, oldValue: o, newValue: n }) + } else { + this.filterData.securityEvent[4].flag = false + } } }, 'filterData.securityEvent.5.value': { deep: true, handler (n, o) { - this.$refs.search.changeParams({ column: this.filterData.securityEvent[5].column, oldValue: o, newValue: n }) + if (!this.filterData.securityEvent[5].flag) { + this.$refs.search.changeParams({ column: this.filterData.securityEvent[5].column, oldValue: o, newValue: n }) + } else { + this.filterData.securityEvent[5].flag = false + } } }, 'filterData.performanceEvent.0.value': {