11 Commits
Author SHA1 Message Date
Li4n0 acbdbee26a chore(release): 0.2.0 2021-07-22 22:47:22 +08:00
Li4n0 9863821dbc feat: support deleting logs based on filtering results (#35)
* feat: support deleting logs based on filtering results

* fix(record): fix the problem of wrong number of parameters when outputting delete logs
2021-07-22 22:46:11 +08:00
Li4n0 206808e83a chore(release): 0.1.7 2021-07-11 16:24:57 +08:00
Li4n0 a248c6e39e chore: release 0.1.7 2021-07-11 16:24:44 +08:00
Li4n0 5e2020efff ci: remove architectures other than amd64 2021-07-11 16:23:15 +08:00
Li4n0 c0bda707b7 fix(mysql): fix the bug that crashes when mysql port conflicts 2021-07-11 14:49:35 +08:00
Li4n0 ffc4318725 fix(http): fix the bug that http record url search does not work 2021-07-11 13:55:20 +08:00
Li4n0 8023a9b021 chore(release): 0.1.6 2021-06-25 22:38:27 +08:00
Li4n0 56153510e1 fix(cli): fix the bug that the prompt may not be output when generating config file 2021-06-25 22:37:58 +08:00
Li4n0 be7343191d ci(release.yml): use -tags netgo when compiling on linux platform
fix #32
2021-06-25 22:32:41 +08:00
Li4n0 b1773ee5e9 fix(ipinfo): fix a potential panic when downloading ip location database (#33) 2021-06-25 21:15:47 +08:00
30 changed files with 392 additions and 58 deletions
+7 -15
View File
@@ -12,14 +12,11 @@ jobs:
with:
go-version: '^1.16.0'
- name: compile
env:
CGO_ENABLE: 1
CGO_LDFLAGS: -static
run: |
GOARCH="amd64" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_amd64" ./cmd/revsuit/revsuit.go
GOARCH="386" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_i386" ./cmd/revsuit/revsuit.go
GOARCH="arm" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_arm" ./cmd/revsuit/revsuit.go
GOARCH="arm64" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_arm64" ./cmd/revsuit/revsuit.go
GOARCH="amd64" go build -v -ldflags="-s -w -extldflags=-static" -tags netgo -trimpath -o "bin/revsuit_linux_amd64" ./cmd/revsuit/revsuit.go
# GOARCH="386" go build -v -ldflags="-s -w -extldflags=-static" -tags netgo -trimpath -o "bin/revsuit_linux_i386" ./cmd/revsuit/revsuit.go
# GOARCH="arm" go build -v -ldflags="-s -w -extldflags=-static" -tags netgo -trimpath -o "bin/revsuit_linux_arm" ./cmd/revsuit/revsuit.go
# GOARCH="arm64" go build -v -ldflags="-s -w -extldflags=-static" -tags netgo -trimpath -o "bin/revsuit_linux_arm64" ./cmd/revsuit/revsuit.go
- name: Upload the artifacts
uses: li4n0/upload-release-action@v2
with:
@@ -37,11 +34,9 @@ jobs:
with:
go-version: '^1.16.0'
- name: compile
env:
CGO_ENABLE: 1
run: |
GOARCH="amd64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
GOARCH="arm64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
# GOARCH="arm64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
- name: Upload the artifacts
uses: li4n0/upload-release-action@v2
with:
@@ -59,13 +54,10 @@ jobs:
with:
go-version: '^1.16.0'
- name: compile
env:
CGO_ENABLE: 1
CGO_LDFLAGS: -static
run: |
env GOARCH=amd64 go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_amd64.exe" ./cmd/revsuit/revsuit.go
env GOARCH=386 go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_i386.exe" ./cmd/revsuit/revsuit.go
env GOARCH=arm go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_arm.exe" ./cmd/revsuit/revsuit.go
# env GOARCH=386 go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_i386.exe" ./cmd/revsuit/revsuit.go
# env GOARCH=arm go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_arm.exe" ./cmd/revsuit/revsuit.go
- name: Upload the artifacts
uses: li4n0/upload-release-action@v2
with:
+23
View File
@@ -2,6 +2,29 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [0.2.0](https://github.com/Li4n0/revsuit/compare/v0.1.7...v0.2.0) (2021-07-22)
### Features
* support deleting logs based on filtering results ([#35](https://github.com/Li4n0/revsuit/issues/35)) ([9863821](https://github.com/Li4n0/revsuit/commit/9863821dbc351734569b7ec1eda2b6712bd02bb0))
### [0.1.7](https://github.com/Li4n0/revsuit/compare/v0.1.6...v0.1.7) (2021-07-11)
### Bug Fixes
* **http:** fix the bug that http record url search does not work ([ffc4318](https://github.com/Li4n0/revsuit/commit/ffc4318725017c7eda7ec11ca67d5de16ad1e8a8))
* **mysql:** fix the bug that crashes when mysql port conflicts ([c0bda70](https://github.com/Li4n0/revsuit/commit/c0bda707b750b7858fdd4efc414b726ee37e71da))
### [0.1.6](https://github.com/Li4n0/revsuit/compare/v0.1.5...v0.1.6) (2021-06-25)
### Bug Fixes
* **cli:** fix the bug that the prompt may not be output when generating config file ([5615351](https://github.com/Li4n0/revsuit/commit/56153510e11783c08843cbb8b0f827d5f8567842))
* **ipinfo:** fix a potential panic when downloading ip location database ([#33](https://github.com/Li4n0/revsuit/issues/33)) ([b1773ee](https://github.com/Li4n0/revsuit/commit/b1773ee5e9ebd8c8be72f315981268992c08b3f1))
### [0.1.5](https://github.com/Li4n0/revsuit/compare/v0.1.5-beta...v0.1.5) (2021-06-22 公开该项目以庆祝毕业,愿工作多年后的我,归来时仍是少年)
+2 -1
View File
@@ -26,7 +26,8 @@ Powerful:
### Preparation
Download the latest release firstly.
Download the latest release firstly. For the time being, only the binary for amd64 architecture is available for
download, if you need to use it in other architectures, you can compile it yourself.
RevSuit will generate default configuration file on first run. Modify the configuration file according to your needs,
then re-run.
+1 -1
View File
@@ -23,7 +23,7 @@ RevSuit 是一款灵活并且强大的反连平台。目前支持 HTTP、DNS、R
### 安装
在 Releases 里下载最新版本的 RevSuit。
在 Releases 里下载最新版本的 RevSuit。暂时只提供 amd64 架构下的二进制文件下载,如需要在其它架构下使用,可以自行编译。
RevSuit 首次运行时将会生成配置文件模板,你需要编辑其中的内容然后重新运行。
+1 -1
View File
@@ -1 +1 @@
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-1bc6d13e],html[data-v-1bc6d13e]{height:100%;margin:0}.fade-transform-enter-active[data-v-1bc6d13e],.fade-transform-leave-active[data-v-1bc6d13e]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-1bc6d13e],.fade-transform-leave[data-v-1bc6d13e]{opacity:0}.fade-transform-enter-to[data-v-1bc6d13e]{opacity:0}.ant-menu-item>span>a[data-v-1bc6d13e]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-1bc6d13e]{color:#fff}#app[data-v-1bc6d13e]{min-height:100%}#app .trigger[data-v-1bc6d13e]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#app .trigger[data-v-1bc6d13e]:hover{color:#1890ff}#app .logo[data-v-1bc6d13e]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-1bc6d13e]{color:#888;text-align:right;margin-right:1rem}
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-3b44ba10],html[data-v-3b44ba10]{height:100%;margin:0}.fade-transform-enter-active[data-v-3b44ba10],.fade-transform-leave-active[data-v-3b44ba10]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-3b44ba10],.fade-transform-leave[data-v-3b44ba10]{opacity:0}.fade-transform-enter-to[data-v-3b44ba10]{opacity:0}.ant-menu-item>span>a[data-v-3b44ba10]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-3b44ba10]{color:#fff}#app[data-v-3b44ba10]{min-height:100%}#app .trigger[data-v-3b44ba10]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#app .trigger[data-v-3b44ba10]:hover{color:#1890ff}#app .logo[data-v-3b44ba10]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-3b44ba10]{color:#888;text-align:right;margin-right:1rem}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+27 -4
View File
@@ -62,7 +62,7 @@
/>
<div v-if="isLogMode" style="float: right; min-width:60% ;padding: 12px 0;line-height: 24px;">
<a-row :gutter="24" type="flex">
<a-col :span="21">
<a-col :span="20">
<a-form-model v-show="showSettings" ref="settings" layout="inline">
<a-row :gutter="24" type="flex">
<a-col :span="9" :offset="2">
@@ -80,9 +80,23 @@
</a-row>
</a-form-model>
</a-col>
<a-col :span="3">
<a-col :span="4">
<a-popconfirm
:title="showLogNum?`This will delete all logs in the current filtered state, a total of ${this.$refs.content.pagination.total}, are you sure?`:'This will delete all logs in the current filtered state, a total of 0, are you sure?'"
ok-text="Yes"
cancel-text="No"
@visibleChange="showLogNum?delayChangeShowLogNum():showLogNum=!showLogNum"
@confirm="deleteLogs"
>
<a-icon slot="icon" type="question-circle-o" style="color: red"/>
<a-icon
:style="'font-size: 18px;padding: 12px 0;'"
type="delete"
@click="()=>{}"
/>
</a-popconfirm>
<a-icon
:style="'font-size: 18px;padding: 12px 0;'+(showSettings?'color: #1b90ff;':'')"
:style="'font-size: 18px;padding:12px 15px;'+(showSettings?'color: #1b90ff;':'')"
type="setting"
@click="showSettings = !showSettings"
/>
@@ -123,6 +137,7 @@ export default {
pageSize: store.pageSize,
collapsed: false,
showSettings: false,
showLogNum: false,
openKeys: [],
version: "",
};
@@ -130,7 +145,7 @@ export default {
computed: {
isLogMode() {
return this.$route.path.includes('logs')
}
},
},
methods: {
timing() {
@@ -145,6 +160,14 @@ export default {
getVersion().then(res => {
this.version = res.data.result
})
},
deleteLogs() {
this.$refs.content.delete()
},
delayChangeShowLogNum() {
setTimeout(() => {
this.showLogNum = !this.showLogNum
}, 1000)
}
},
mounted() {
+41
View File
@@ -9,6 +9,15 @@ export function getHttpRecord(params) {
})
}
export function deleteHttpRecord(params) {
return request({
url: '/record/http',
params: params,
method: 'delete',
})
}
export function getDnsRecord(params) {
return request({
url: '/record/dns',
@@ -17,6 +26,14 @@ export function getDnsRecord(params) {
})
}
export function deleteDnsRecord(params) {
return request({
url: '/record/dns',
params: params,
method: 'delete'
})
}
export function getMysqlRecord(params) {
return request({
url: '/record/mysql',
@@ -25,6 +42,14 @@ export function getMysqlRecord(params) {
})
}
export function deleteMysqlRecord(params) {
return request({
url: '/record/mysql',
params: params,
method: 'delete'
})
}
export function getRmiRecord(params) {
return request({
url: '/record/rmi',
@@ -33,10 +58,26 @@ export function getRmiRecord(params) {
})
}
export function deleteRmiRecord(params) {
return request({
url: '/record/rmi',
params: params,
method: 'delete'
})
}
export function getFtpRecord(params) {
return request({
url: '/record/ftp',
params: params,
method: 'get'
})
}
export function deleteFtpRecord(params) {
return request({
url: '/record/ftp',
params: params,
method: 'delete'
})
}
+16 -1
View File
@@ -37,7 +37,7 @@
</style>
<script>
import {getDnsRecord} from '@/api/record'
import {deleteDnsRecord, getDnsRecord} from '@/api/record'
import {store} from '@/main'
import FilterDropdown from '@/components/FilterDropdown'
@@ -145,6 +145,21 @@ export default {
}
})
},
delete: function () {
let params = {
...this.filters,
}
this.loading = true;
deleteDnsRecord(params).then(() => {
this.$message.success('Deleted successfully')
this.filters = {}
this.fetch()
}).catch(e => {
if (e.response.status !== 403) {
this.$message.error('Failed to delete: ' + e.response.data.error)
}
})
},
},
mounted() {
this.fetch();
+16 -1
View File
@@ -72,7 +72,7 @@
</style>
<script>
import {getFtpRecord} from '@/api/record'
import {deleteFtpRecord, getFtpRecord} from '@/api/record'
import {store} from '@/main'
import FilterDropdown from '@/components/FilterDropdown'
@@ -234,6 +234,21 @@ export default {
}
})
},
delete: function () {
let params = {
...this.filters,
}
this.loading = true;
deleteFtpRecord(params).then(() => {
this.$message.success('Deleted successfully')
this.filters = {}
this.fetch()
}).catch(e => {
if (e.response.status !== 403) {
this.$message.error('Failed to delete: ' + e.response.data.error)
}
})
},
},
mounted() {
this.fetch();
+16 -1
View File
@@ -49,7 +49,7 @@
</style>
<script>
import {getHttpRecord} from '@/api/record'
import {getHttpRecord, deleteHttpRecord} from '@/api/record'
import {store} from '@/main'
import FilterDropdown from '@/components/FilterDropdown'
@@ -179,6 +179,21 @@ export default {
}
})
},
delete: function () {
let params = {
...this.filters,
}
this.loading = true;
deleteHttpRecord(params).then(() => {
this.$message.success('Deleted successfully')
this.filters = {}
this.fetch()
}).catch(e => {
if (e.response.status !== 403) {
this.$message.error('Failed to delete: ' + e.response.data.error)
}
})
},
},
mounted() {
this.fetch();
+16 -1
View File
@@ -70,7 +70,7 @@
</style>
<script>
import {getMysqlRecord} from '@/api/record'
import {deleteMysqlRecord, getMysqlRecord} from '@/api/record'
import {store} from '@/main'
import FilterDropdown from '@/components/FilterDropdown'
@@ -231,6 +231,21 @@ export default {
}
})
},
delete: function () {
let params = {
...this.filters,
}
this.loading = true;
deleteMysqlRecord(params).then(() => {
this.$message.success('Deleted successfully')
this.filters = {}
this.fetch()
}).catch(e => {
if (e.response.status !== 403) {
this.$message.error('Failed to delete: ' + e.response.data.error)
}
})
},
},
mounted() {
this.fetch();
+18 -2
View File
@@ -37,7 +37,7 @@
</style>
<script>
import {getRmiRecord} from '@/api/record'
import {deleteRmiRecord, getRmiRecord} from '@/api/record'
import {store} from '@/main'
import FilterDropdown from '@/components/FilterDropdown'
@@ -110,7 +110,8 @@ export default {
onShowSizeChange: (current, size) => {
store.pageSize = size
}
}, filters: {},
},
filters: {},
order: "desc",
loading: false,
columns,
@@ -146,6 +147,21 @@ export default {
}
})
},
delete: function () {
let params = {
...this.filters,
}
this.loading = true;
deleteRmiRecord(params).then(() => {
this.$message.success('Deleted successfully')
this.filters = {}
this.fetch()
}).catch(e => {
if (e.response.status !== 403) {
this.$message.error('Failed to delete: ' + e.response.data.error)
}
})
},
},
mounted() {
this.fetch();
+1
View File
@@ -16,6 +16,7 @@ func Start() {
log.ConsoleConfig{
Level: log.LevelInfo,
})
defer log.Stop()
app := &cli.App{
Name: "RevSuit",
Usage: "An Open-Sourced Reverse Platform Designed for Receive Various Kinds of Connection",
+11 -3
View File
@@ -2,11 +2,19 @@ package database
import "gorm.io/gorm"
var DB *gorm.DB
var (
DB *gorm.DB
Driver DriverType
)
func InitDB(driver, dsn string) (err error) {
type DriverType = string
const Sqlite = "sqlite"
func InitDB(driver DriverType, dsn string) (err error) {
Driver = driver
switch driver {
case "sqlite":
case Sqlite:
DB, err = NewSqlite3(dsn)
}
return err
+14 -3
View File
@@ -20,6 +20,7 @@ const (
)
func get(url string) (b []byte, err error) {
var resp *http.Response
client := http.Client{
Timeout: 90 * time.Second,
Transport: &http.Transport{
@@ -28,11 +29,17 @@ func get(url string) (b []byte, err error) {
request, _ := http.NewRequest(http.MethodGet, url, nil)
request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36")
resp, err := client.Do(request)
resp, err = client.Do(request)
if err != nil {
return
}
defer resp.Body.Close()
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Warn("%v", err)
}
}(resp.Body)
return io.ReadAll(resp.Body)
}
@@ -65,10 +72,14 @@ func extractTarGz(gzipStream io.Reader) error {
if err != nil {
return err
}
defer outFile.Close()
if _, err := io.Copy(outFile, tarReader); err != nil {
_ = outFile.Close()
return err
}
err = outFile.Close()
if err != nil {
log.Warn("%v", err)
}
}
}
return nil
+19 -4
View File
@@ -21,6 +21,7 @@ const (
)
func get(url string) (b []byte, err error) {
var resp *http.Response
client := http.Client{
Timeout: 90 * time.Second,
Transport: &http.Transport{
@@ -29,11 +30,17 @@ func get(url string) (b []byte, err error) {
request, _ := http.NewRequest("GET", url, nil)
request.Header.Add("User-Agent", "Nali/2.1.2 (Nali CLI, https://nali.skk.moe)")
resp, err := client.Do(request)
resp, err = client.Do(request)
if err != nil {
return
}
defer resp.Body.Close()
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Warn("%v", err)
}
}(resp.Body)
return io.ReadAll(resp.Body)
}
@@ -47,17 +54,25 @@ func getKey(b []byte) (key uint32, err error) {
}
func decrypt(b []byte, key uint32) (_ []byte, err error) {
var rc io.ReadCloser
for i := 0; i < 0x200; i++ {
key *= uint32(0x805)
key++
key &= uint32(0xff)
b[i] = b[i] ^ byte(key)
}
rc, err := zlib.NewReader(bytes.NewBuffer(b))
rc, err = zlib.NewReader(bytes.NewBuffer(b))
if err != nil {
return
}
defer rc.Close()
defer func(rc io.ReadCloser) {
err := rc.Close()
if err != nil {
log.Warn("%v", err)
}
}(rc)
return io.ReadAll(rc)
}
+29 -1
View File
@@ -1,6 +1,7 @@
package dns
import (
"net/http"
"strconv"
"time"
@@ -8,6 +9,8 @@ import (
"github.com/li4n0/revsuit/internal/database"
"github.com/li4n0/revsuit/internal/notice"
"github.com/li4n0/revsuit/internal/record"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
)
var _ record.Record = (*Record)(nil)
@@ -41,7 +44,7 @@ func newRecord(rule *Rule, flag, domain, remoteIp, ipArea string) (r *Record, er
return r, database.DB.Create(r).Error
}
func ListRecords(c *gin.Context) {
func Records(c *gin.Context) {
var (
dnsRecord Record
res []Record
@@ -80,6 +83,31 @@ func ListRecords(c *gin.Context) {
db.Where("rule_name = ?", dnsRecord.RuleName)
}
//Delete records
if c.Request.Method == http.MethodDelete {
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
c.JSON(400, gin.H{
"status": "failed",
"error": err.Error(),
"data": nil,
})
return
}
if database.Driver == database.Sqlite {
db.Exec("VACUUM")
}
c.JSON(200, gin.H{
"status": "succeed",
"error": nil,
})
log.Info("%d dns records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
return
}
//List records
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
c.JSON(400, gin.H{
+28 -1
View File
@@ -1,6 +1,7 @@
package ftp
import (
"net/http"
"strconv"
"time"
@@ -10,6 +11,7 @@ import (
"github.com/li4n0/revsuit/internal/ipinfo"
"github.com/li4n0/revsuit/internal/notice"
"github.com/li4n0/revsuit/internal/record"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
)
@@ -53,7 +55,7 @@ func NewRecord(rule *Rule, flag, user, password, method, path, ip, area string,
return r, database.DB.Create(r).Error
}
func ListRecords(c *gin.Context) {
func Records(c *gin.Context) {
var (
ftpRecord Record
res []Record
@@ -105,6 +107,31 @@ func ListRecords(c *gin.Context) {
db.Where("rule_name = ?", ftpRecord.RuleName)
}
//Delete records
if c.Request.Method == http.MethodDelete {
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
c.JSON(400, gin.H{
"status": "failed",
"error": err.Error(),
"data": nil,
})
return
}
if database.Driver == database.Sqlite {
db.Exec("VACUUM")
}
c.JSON(200, gin.H{
"status": "succeed",
"error": nil,
})
log.Info("%d ftp records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
return
}
//List records
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
c.JSON(400, gin.H{
+2 -1
View File
@@ -302,10 +302,11 @@ func (s *Server) Run() {
s.listener, err = vmysql.NewListener("tcp", s.Addr, authServer, s, s.VersionString, 0, 0)
if err != nil {
log.Error("New MySQL Server failed: %s", err)
return
}
go func() {
s.livingLock.Lock()
if !s.Enable {
s.listener.Close()
}
+28 -1
View File
@@ -1,6 +1,7 @@
package mysql
import (
"net/http"
"strconv"
"time"
@@ -9,6 +10,8 @@ import (
"github.com/li4n0/revsuit/internal/file"
"github.com/li4n0/revsuit/internal/notice"
"github.com/li4n0/revsuit/internal/record"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
)
var _ record.Record = (*Record)(nil)
@@ -51,7 +54,7 @@ func newRecord(rule *Rule, flag, username, schema, clientName, clientOS, remoteI
return r, database.DB.Create(r).Error
}
func ListRecords(c *gin.Context) {
func Records(c *gin.Context) {
var (
mysqlRecord Record
res []Record
@@ -103,6 +106,30 @@ func ListRecords(c *gin.Context) {
}
}
//Delete records
if c.Request.Method == http.MethodDelete {
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
c.JSON(400, gin.H{
"status": "failed",
"error": err.Error(),
"data": nil,
})
return
}
if database.Driver == database.Sqlite {
db.Exec("VACUUM")
}
c.JSON(200, gin.H{
"status": "succeed",
"error": nil,
})
log.Info("%d mysql records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
return
}
//List records
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
c.JSON(400, gin.H{
+29 -2
View File
@@ -1,6 +1,7 @@
package rhttp
import (
"net/http"
"strconv"
"time"
@@ -8,6 +9,8 @@ import (
"github.com/li4n0/revsuit/internal/database"
"github.com/li4n0/revsuit/internal/notice"
"github.com/li4n0/revsuit/internal/record"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
)
var _ record.Record = (*Record)(nil)
@@ -44,7 +47,7 @@ func NewRecord(rule *Rule, flag, method, url, ip, area, raw string) (r *Record,
return r, database.DB.Create(r).Error
}
func ListRecords(c *gin.Context) {
func Records(c *gin.Context) {
var (
httpRecord Record
res []Record
@@ -78,7 +81,7 @@ func ListRecords(c *gin.Context) {
db.Where("method = ?", httpRecord.Method)
}
if httpRecord.URI != "" {
db.Where("path like ?", "%"+httpRecord.URI+"%")
db.Where("uri like ?", "%"+httpRecord.URI+"%")
}
if httpRecord.RemoteIP != "" {
db.Where("remote_ip = ?", httpRecord.RemoteIP)
@@ -87,6 +90,30 @@ func ListRecords(c *gin.Context) {
db.Where("rule_name = ?", httpRecord.RuleName)
}
//Delete records
if c.Request.Method == http.MethodDelete {
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
c.JSON(400, gin.H{
"status": "failed",
"error": err.Error(),
"data": nil,
})
return
}
if database.Driver == database.Sqlite {
db.Exec("VACUUM")
}
c.JSON(200, gin.H{
"status": "succeed",
"error": nil,
})
log.Info("%d http records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
return
}
//List records
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
c.JSON(400, gin.H{
+29 -1
View File
@@ -1,6 +1,7 @@
package rmi
import (
"net/http"
"strconv"
"time"
@@ -8,6 +9,8 @@ import (
"github.com/li4n0/revsuit/internal/database"
"github.com/li4n0/revsuit/internal/notice"
"github.com/li4n0/revsuit/internal/record"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
)
var _ record.Record = (*Record)(nil)
@@ -40,7 +43,7 @@ func NewRecord(rule *Rule, flag, path, ip, area string) (r *Record, err error) {
return r, database.DB.Create(r).Error
}
func ListRecords(c *gin.Context) {
func Records(c *gin.Context) {
var (
rmiRecord Record
res []Record
@@ -80,6 +83,31 @@ func ListRecords(c *gin.Context) {
db.Where("rule_name = ?", rmiRecord.RuleName)
}
//Delete records
if c.Request.Method == http.MethodDelete {
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
c.JSON(400, gin.H{
"status": "failed",
"error": err.Error(),
"data": nil,
})
return
}
if database.Driver == database.Sqlite {
db.Exec("VACUUM")
}
c.JSON(200, gin.H{
"status": "succeed",
"error": nil,
})
log.Info("%d rmi records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
return
}
//List records
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
c.JSON(400, gin.H{
+10 -5
View File
@@ -77,19 +77,24 @@ func (revsuit *Revsuit) registerHttpRouter() {
recordGroup := revsuit.http.ApiGroup.Group("/record")
httpGroup := recordGroup.Group("/http")
httpGroup.GET("", rhttp.ListRecords)
httpGroup.GET("", rhttp.Records)
httpGroup.DELETE("", rhttp.Records)
dnsGroup := recordGroup.Group("/dns")
dnsGroup.GET("", dns.ListRecords)
dnsGroup.GET("", dns.Records)
dnsGroup.DELETE("", dns.Records)
mysqlGroup := recordGroup.Group("/mysql")
mysqlGroup.GET("", mysql.ListRecords)
mysqlGroup.GET("", mysql.Records)
mysqlGroup.DELETE("", mysql.Records)
rmiGroup := recordGroup.Group("/rmi")
rmiGroup.GET("", rmi.ListRecords)
rmiGroup.GET("", rmi.Records)
rmiGroup.DELETE("", rmi.Records)
ftpGroup := recordGroup.Group("/ftp")
ftpGroup.GET("", ftp.ListRecords)
ftpGroup.GET("", ftp.Records)
ftpGroup.DELETE("", ftp.Records)
// init rule router group
ruleGroup := revsuit.http.ApiGroup.Group("/rule")
+2 -2
View File
@@ -18,7 +18,7 @@ import (
log "unknwon.dev/clog/v2"
)
const VERSION = "0.1.5"
const VERSION = "0.2.0"
type Revsuit struct {
config *Config
@@ -60,7 +60,7 @@ func initDatabase(dsn string) {
Level: log.LevelInfo,
})
err := database.InitDB("sqlite", dsn)
err := database.InitDB(database.Sqlite, dsn)
if err != nil {
log.Fatal(err.Error())
}