屏蔽表已创建
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type nodeBlockingRequest struct {
|
||||
NodeID string `json:"node_id"`
|
||||
NodeNum *int64 `json:"node_num"`
|
||||
Reason string `json:"reason"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type ipBlockingRequest struct {
|
||||
IPValue string `json:"ip_value"`
|
||||
Reason string `json:"reason"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type forbiddenWordBlockingRequest struct {
|
||||
Word string `json:"word"`
|
||||
MatchType string `json:"match_type"`
|
||||
CaseSensitive bool `json:"case_sensitive"`
|
||||
Reason string `json:"reason"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
func registerAdminBlockingRoutes(r gin.IRouter, store *store) {
|
||||
r.GET("/blocking/nodes", func(c *gin.Context) {
|
||||
opts, ok := parseListOptions(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
rows, err := store.ListNodeBlocking(opts)
|
||||
if err != nil {
|
||||
writeListResponse(c, rows, opts, err, nodeBlockingDTO)
|
||||
return
|
||||
}
|
||||
total, err := store.CountNodeBlocking(opts)
|
||||
writeListResponseWithTotal(c, rows, opts, total, err, nodeBlockingDTO)
|
||||
})
|
||||
r.POST("/blocking/nodes", func(c *gin.Context) {
|
||||
var req nodeBlockingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid node blocking request"})
|
||||
return
|
||||
}
|
||||
row, err := store.CreateNodeBlocking(req.NodeID, req.NodeNum, req.Reason, req.Enabled)
|
||||
writeBlockingMutationResponse(c, http.StatusCreated, row, err, nodeBlockingDTO)
|
||||
})
|
||||
r.PUT("/blocking/nodes/:id", func(c *gin.Context) {
|
||||
id, ok := parseBlockingID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req nodeBlockingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid node blocking request"})
|
||||
return
|
||||
}
|
||||
row, err := store.UpdateNodeBlocking(id, req.NodeID, req.NodeNum, req.Reason, req.Enabled)
|
||||
writeBlockingMutationResponse(c, http.StatusOK, row, err, nodeBlockingDTO)
|
||||
})
|
||||
r.DELETE("/blocking/nodes/:id", func(c *gin.Context) {
|
||||
id, ok := parseBlockingID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
writeBlockingDeleteResponse(c, store.DeleteNodeBlocking(id))
|
||||
})
|
||||
|
||||
r.GET("/blocking/ips", func(c *gin.Context) {
|
||||
opts, ok := parseListOptions(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
rows, err := store.ListIPBlocking(opts)
|
||||
if err != nil {
|
||||
writeListResponse(c, rows, opts, err, ipBlockingDTO)
|
||||
return
|
||||
}
|
||||
total, err := store.CountIPBlocking(opts)
|
||||
writeListResponseWithTotal(c, rows, opts, total, err, ipBlockingDTO)
|
||||
})
|
||||
r.POST("/blocking/ips", func(c *gin.Context) {
|
||||
var req ipBlockingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid ip blocking request"})
|
||||
return
|
||||
}
|
||||
row, err := store.CreateIPBlocking(req.IPValue, req.Reason, req.Enabled)
|
||||
writeBlockingMutationResponse(c, http.StatusCreated, row, err, ipBlockingDTO)
|
||||
})
|
||||
r.PUT("/blocking/ips/:id", func(c *gin.Context) {
|
||||
id, ok := parseBlockingID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req ipBlockingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid ip blocking request"})
|
||||
return
|
||||
}
|
||||
row, err := store.UpdateIPBlocking(id, req.IPValue, req.Reason, req.Enabled)
|
||||
writeBlockingMutationResponse(c, http.StatusOK, row, err, ipBlockingDTO)
|
||||
})
|
||||
r.DELETE("/blocking/ips/:id", func(c *gin.Context) {
|
||||
id, ok := parseBlockingID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
writeBlockingDeleteResponse(c, store.DeleteIPBlocking(id))
|
||||
})
|
||||
|
||||
r.GET("/blocking/words", func(c *gin.Context) {
|
||||
opts, ok := parseListOptions(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
rows, err := store.ListForbiddenWordBlocking(opts)
|
||||
if err != nil {
|
||||
writeListResponse(c, rows, opts, err, forbiddenWordBlockingDTO)
|
||||
return
|
||||
}
|
||||
total, err := store.CountForbiddenWordBlocking(opts)
|
||||
writeListResponseWithTotal(c, rows, opts, total, err, forbiddenWordBlockingDTO)
|
||||
})
|
||||
r.POST("/blocking/words", func(c *gin.Context) {
|
||||
var req forbiddenWordBlockingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid forbidden word blocking request"})
|
||||
return
|
||||
}
|
||||
row, err := store.CreateForbiddenWordBlocking(req.Word, req.MatchType, req.CaseSensitive, req.Reason, req.Enabled)
|
||||
writeBlockingMutationResponse(c, http.StatusCreated, row, err, forbiddenWordBlockingDTO)
|
||||
})
|
||||
r.PUT("/blocking/words/:id", func(c *gin.Context) {
|
||||
id, ok := parseBlockingID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req forbiddenWordBlockingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid forbidden word blocking request"})
|
||||
return
|
||||
}
|
||||
row, err := store.UpdateForbiddenWordBlocking(id, req.Word, req.MatchType, req.CaseSensitive, req.Reason, req.Enabled)
|
||||
writeBlockingMutationResponse(c, http.StatusOK, row, err, forbiddenWordBlockingDTO)
|
||||
})
|
||||
r.DELETE("/blocking/words/:id", func(c *gin.Context) {
|
||||
id, ok := parseBlockingID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
writeBlockingDeleteResponse(c, store.DeleteForbiddenWordBlocking(id))
|
||||
})
|
||||
}
|
||||
|
||||
func parseBlockingID(c *gin.Context) (uint64, bool) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid blocking rule id"})
|
||||
return 0, false
|
||||
}
|
||||
return id, true
|
||||
}
|
||||
|
||||
func writeBlockingMutationResponse[T any](c *gin.Context, status int, row *T, err error, convert func(T) gin.H) {
|
||||
if errors.Is(err, errBlockingAlreadyExists) {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "blocking rule already exists"})
|
||||
return
|
||||
}
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "blocking rule not found"})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(status, gin.H{"item": convert(*row)})
|
||||
}
|
||||
|
||||
func writeBlockingDeleteResponse(c *gin.Context, err error) {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "blocking rule not found"})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
||||
}
|
||||
|
||||
func nodeBlockingDTO(row nodeBlockingRecord) gin.H {
|
||||
return gin.H{"id": row.ID, "node_id": row.NodeID, "node_num": ptrInt64(row.NodeNum), "reason": row.Reason, "enabled": row.Enabled, "created_at": row.CreatedAt, "updated_at": row.UpdatedAt}
|
||||
}
|
||||
|
||||
func ipBlockingDTO(row ipBlockingRecord) gin.H {
|
||||
return gin.H{"id": row.ID, "ip_value": row.IPValue, "reason": row.Reason, "enabled": row.Enabled, "created_at": row.CreatedAt, "updated_at": row.UpdatedAt}
|
||||
}
|
||||
|
||||
func forbiddenWordBlockingDTO(row forbiddenWordBlockingRecord) gin.H {
|
||||
return gin.H{"id": row.ID, "word": row.Word, "match_type": row.MatchType, "case_sensitive": row.CaseSensitive, "reason": row.Reason, "enabled": row.Enabled, "created_at": row.CreatedAt, "updated_at": row.UpdatedAt}
|
||||
}
|
||||
Reference in New Issue
Block a user