mirror of https://github.com/bjdgyc/anylink.git
新增审计日志的搜索功能
This commit is contained in:
parent
e761c1e111
commit
b8c3d33f2e
|
@ -14,15 +14,13 @@ func SetAuditList(w http.ResponseWriter, r *http.Request) {
|
|||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
var datas []dbdata.AccessAudit
|
||||
count := dbdata.CountAll(&dbdata.AccessAudit{})
|
||||
err := dbdata.Find(&datas, dbdata.PageSize, page)
|
||||
session := dbdata.GetAuditSession(r.FormValue("search"))
|
||||
count, err := dbdata.FindAndCount(session, &datas, dbdata.PageSize, page)
|
||||
if err != nil && !dbdata.CheckErrNotFound(err) {
|
||||
RespError(w, RespInternalErr, err)
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"count": count,
|
||||
"page_size": dbdata.PageSize,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package dbdata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type SearchCon struct {
|
||||
Username string `json:"username"`
|
||||
Src string `json:"src"`
|
||||
Dst string `json:"dst"`
|
||||
DstPort string `json:"dst_port"`
|
||||
AccessProto string `json:"access_proto"`
|
||||
Date []string `json:"date"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
func GetAuditSession(search string) *xorm.Session {
|
||||
session := xdb.Where("1=1")
|
||||
if search == "" {
|
||||
return session
|
||||
}
|
||||
var searchData SearchCon
|
||||
err := json.Unmarshal([]byte(search), &searchData)
|
||||
if err != nil {
|
||||
return session
|
||||
}
|
||||
if searchData.Username != "" {
|
||||
session.And("username = ?", searchData.Username)
|
||||
}
|
||||
if searchData.Src != "" {
|
||||
session.And("src = ?", searchData.Src)
|
||||
}
|
||||
if searchData.Dst != "" {
|
||||
session.And("dst = ?", searchData.Dst)
|
||||
}
|
||||
if searchData.DstPort != "" {
|
||||
session.And("dst_port = ?", searchData.DstPort)
|
||||
}
|
||||
if searchData.AccessProto != "" {
|
||||
session.And("access_proto = ?", searchData.AccessProto)
|
||||
}
|
||||
if len(searchData.Date) > 0 && searchData.Date[0] != "" {
|
||||
session.And("created_at BETWEEN ? AND ?", searchData.Date[0], searchData.Date[1])
|
||||
}
|
||||
if searchData.Info != "" {
|
||||
session.And("info LIKE ?", "%"+searchData.Info+"%")
|
||||
}
|
||||
return session
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package dbdata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSearchAudit(t *testing.T) {
|
||||
ast := assert.New(t)
|
||||
|
||||
preIpData()
|
||||
defer closeIpdata()
|
||||
|
||||
currDateVal := "2022-07-24 00:00:00"
|
||||
CreatedAt, _ := time.Parse("2006-01-02 15:04:05", currDateVal)
|
||||
|
||||
dataTest := AccessAudit{
|
||||
Username: "Test",
|
||||
Protocol: 6,
|
||||
Src: "10.10.1.5",
|
||||
SrcPort: 0,
|
||||
Dst: "172.217.160.68",
|
||||
DstPort: 80,
|
||||
AccessProto: 4,
|
||||
Info: "www.google.com",
|
||||
CreatedAt: CreatedAt,
|
||||
}
|
||||
err := Add(dataTest)
|
||||
ast.Nil(err)
|
||||
|
||||
var datas []AccessAudit
|
||||
searchFormat := `{"username": "%s", "src":"%s", "dst": "%s", "dst_port":"%d","access_proto":"%d","info":"%s","date":["%s","%s"]}`
|
||||
search := fmt.Sprintf(searchFormat, dataTest.Username, dataTest.Src, dataTest.Dst, dataTest.DstPort, dataTest.AccessProto, dataTest.Info, currDateVal, currDateVal)
|
||||
|
||||
session := GetAuditSession(search)
|
||||
count, _ := FindAndCount(session, &datas, PageSize, 0)
|
||||
ast.Equal(count, int64(1))
|
||||
ast.Equal(datas[0].Username, dataTest.Username)
|
||||
ast.Equal(datas[0].Dst, dataTest.Dst)
|
||||
}
|
|
@ -3,6 +3,8 @@ package dbdata
|
|||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const PageSize = 10
|
||||
|
@ -82,3 +84,12 @@ func Prefix(fieldName string, prefix string, data interface{}, limit, page int)
|
|||
start := (page - 1) * limit
|
||||
return where.Limit(limit, start).Find(data)
|
||||
}
|
||||
|
||||
func FindAndCount(session *xorm.Session, data interface{}, limit, page int) (int64, error) {
|
||||
if limit == 0 {
|
||||
return session.FindAndCount(data)
|
||||
}
|
||||
start := (page - 1) * limit
|
||||
totalCount, err := session.Limit(limit, start).FindAndCount(data)
|
||||
return totalCount, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,56 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form :model="searchForm" :rules="rules" ref="searchForm" :inline="true" class="form-inner-error">
|
||||
<el-form-item label="用户名:" prop="username">
|
||||
<el-input size="small" v-model="searchForm.username" style="width: 130px" @keydown.enter.native="searchEnterFun"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="源IP地址:" prop="src">
|
||||
<el-input size="small" v-model="searchForm.src" style="width: 130px" @keydown.enter.native="searchEnterFun"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="目的IP地址:" prop="dst">
|
||||
<el-input size="small" v-model="searchForm.dst" style="width: 130px" @keydown.enter.native="searchEnterFun"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="目的端口:" prop="dst_port">
|
||||
<el-input size="small" v-model="searchForm.dst_port" style="width: 80px" @keydown.enter.native="searchEnterFun"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="访问协议:">
|
||||
<el-select size="small" v-model="searchForm.access_proto" style="width: 100px">
|
||||
<el-option v-for="(item,index) in access_proto" :key="index" :label="item.text" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-form-item label="日期范围:">
|
||||
<el-date-picker
|
||||
v-model="searchForm.date"
|
||||
type="datetimerange"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
range-separator="~"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期">
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="详情:">
|
||||
<el-input size="small" v-model="searchForm.info" placeholder="请输入关键字" style="width: 200px" @keydown.enter.native="searchEnterFun"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
@click="handleSearch">搜索
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
icon="el-icon-refresh"
|
||||
@click="rest">重置搜索
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
|
@ -104,6 +154,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.getData(1)
|
||||
this.setSearchData()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -111,13 +162,55 @@ export default {
|
|||
count: 10,
|
||||
nowIndex: 0,
|
||||
accessProtoArr:["", "UDP", "TCP", "HTTPS", "HTTP"],
|
||||
defSearchForm: {username:'', src:'', dst:'', dst_port:'', access_proto:'', info:'', date:["",""]},
|
||||
searchForm: {},
|
||||
access_proto: [
|
||||
{ text: '请选择', value: '' },
|
||||
{ text: 'UDP', value: '1' },
|
||||
{ text: 'TCP', value: '2' },
|
||||
{ text: 'HTTPS', value: '3' },
|
||||
{ text: 'HTTP', value: '4' },
|
||||
],
|
||||
rules: {
|
||||
username: [
|
||||
{max: 30, message: '长度小于 30 个字符', trigger: 'blur'}
|
||||
],
|
||||
src: [
|
||||
{ message: '请输入正确的IP地址', validator: this.validateIP, trigger: 'blur' },
|
||||
],
|
||||
dst: [
|
||||
{ message: '请输入正确的IP地址', validator: this.validateIP, trigger: 'blur' },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setSearchData() {
|
||||
this.searchForm = JSON.parse(JSON.stringify(this.defSearchForm));
|
||||
},
|
||||
handleSearch() {
|
||||
this.$refs["searchForm"].validate((valid) => {
|
||||
if (!valid) {
|
||||
console.log('error submit!!');
|
||||
return false;
|
||||
}
|
||||
this.getData(1)
|
||||
})
|
||||
},
|
||||
searchEnterFun(e) {
|
||||
var keyCode = window.event ? e.keyCode : e.which;
|
||||
if (keyCode == 13) {
|
||||
this.handleSearch()
|
||||
}
|
||||
},
|
||||
getData(p) {
|
||||
if (! this.searchForm.date) {
|
||||
this.searchForm.date = ["", ""];
|
||||
}
|
||||
axios.get('/set/audit/list', {
|
||||
params: {
|
||||
page: p,
|
||||
search: this.searchForm,
|
||||
}
|
||||
}).then(resp => {
|
||||
var data = resp.data.data
|
||||
|
@ -158,6 +251,23 @@ export default {
|
|||
}
|
||||
return this.accessProtoArr[access_proto]
|
||||
},
|
||||
rest() {
|
||||
console.log("rest");
|
||||
this.setSearchData();
|
||||
this.handleSearch();
|
||||
},
|
||||
validateIP(rule, value, callback) {
|
||||
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||
callback()
|
||||
} else {
|
||||
const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
|
||||
if ((!reg.test(value)) && value !== '') {
|
||||
callback(new Error('请输入正确的IP地址'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue