diff --git a/server/admin/api_set_audit.go b/server/admin/api_set_audit.go index 868957c..872c7a6 100644 --- a/server/admin/api_set_audit.go +++ b/server/admin/api_set_audit.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/bjdgyc/anylink/dbdata" + "github.com/gocarina/gocsv" ) func SetAuditList(w http.ResponseWriter, r *http.Request) { @@ -14,15 +15,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, @@ -31,3 +30,24 @@ func SetAuditList(w http.ResponseWriter, r *http.Request) { RespSucess(w, data) } + +func SetAuditExport(w http.ResponseWriter, r *http.Request) { + var datas []dbdata.AccessAudit + maxNum := 1000000 + session := dbdata.GetAuditSession(r.FormValue("search")) + count, err := dbdata.FindAndCount(session, &datas, maxNum, 0) + if err != nil && !dbdata.CheckErrNotFound(err) { + RespError(w, RespInternalErr, err) + return + } + if count == 0 { + RespError(w, RespParamErr, "你导出的总数量为0条,请调整搜索条件,再导出") + return + } + if count > int64(maxNum) { + RespError(w, RespParamErr, "你导出的数据量超过100万条,请调整搜索条件,再导出") + return + } + gocsv.Marshal(datas, w) + +} diff --git a/server/admin/server.go b/server/admin/server.go index 75b6ac9..807efbd 100644 --- a/server/admin/server.go +++ b/server/admin/server.go @@ -39,6 +39,7 @@ func StartAdmin() { r.HandleFunc("/set/other/smtp", SetOtherSmtp) r.HandleFunc("/set/other/smtp/edit", SetOtherSmtpEdit) r.HandleFunc("/set/audit/list", SetAuditList) + r.HandleFunc("/set/audit/export", SetAuditExport) r.HandleFunc("/user/list", UserList) r.HandleFunc("/user/detail", UserDetail) diff --git a/server/dbdata/audit.go b/server/dbdata/audit.go new file mode 100644 index 0000000..dc7e49b --- /dev/null +++ b/server/dbdata/audit.go @@ -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 +} diff --git a/server/dbdata/audit_test.go b/server/dbdata/audit_test.go new file mode 100644 index 0000000..a2ca9aa --- /dev/null +++ b/server/dbdata/audit_test.go @@ -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) +} diff --git a/server/dbdata/db_orm.go b/server/dbdata/db_orm.go index b168c36..c120b69 100644 --- a/server/dbdata/db_orm.go +++ b/server/dbdata/db_orm.go @@ -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 +} diff --git a/server/go.mod b/server/go.mod index 55df247..7065a25 100644 --- a/server/go.mod +++ b/server/go.mod @@ -7,6 +7,7 @@ require ( github.com/go-ldap/ldap v3.0.3+incompatible // indirect github.com/go-ldap/ldap/v3 v3.4.3 // indirect github.com/go-sql-driver/mysql v1.6.0 + github.com/gocarina/gocsv v0.0.0-20220712153207-8b2118da4570 // indirect github.com/golang-jwt/jwt/v4 v4.0.0 github.com/google/gopacket v1.1.19 github.com/gorilla/mux v1.8.0 diff --git a/web/src/pages/set/Audit.vue b/web/src/pages/set/Audit.vue index fe7d0e0..bbad51e 100644 --- a/web/src/pages/set/Audit.vue +++ b/web/src/pages/set/Audit.vue @@ -1,10 +1,68 @@