feat: 添加IP白名单/黑名单功能 - 支持单IP、CIDR、IP范围

This commit is contained in:
Your Name
2026-05-07 10:05:03 +08:00
parent 0f9663045c
commit d92cf341b8
5 changed files with 467 additions and 0 deletions
+82
View File
@@ -62,6 +62,8 @@ func (s *Server) Start() error {
mux.HandleFunc("/api/online", s.authMiddleware(s.handleOnline))
mux.HandleFunc("/api/config", s.authMiddleware(s.handleConfig))
mux.HandleFunc("/api/upload", s.authMiddleware(s.handleUpload))
mux.HandleFunc("/api/ip-rules", s.authMiddleware(s.handleIPRules))
mux.HandleFunc("/api/ip-rules/", s.authMiddleware(s.handleIPRuleOperation))
addr := fmt.Sprintf("%s:%d", webCfg.Host, webCfg.Port)
log.Printf("Web管理界面已启动: http://localhost:%d", webCfg.Port)
@@ -583,3 +585,83 @@ func GenerateToken() string {
rand.Read(b)
return hex.EncodeToString(b)
}
// handleIPRules IP规则列表和创建
func (s *Server) handleIPRules(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
ruleType := r.URL.Query().Get("type")
rules, err := s.db.ListIPRules(ruleType)
if err != nil {
s.jsonError(w, err.Error(), http.StatusInternalServerError)
return
}
if rules == nil {
rules = []database.IPAccessRule{}
}
s.jsonResponse(w, http.StatusOK, rules)
case http.MethodPost:
var rule database.IPAccessRule
if err := json.NewDecoder(r.Body).Decode(&rule); err != nil {
s.jsonError(w, "请求格式错误", http.StatusBadRequest)
return
}
if rule.IP == "" {
s.jsonError(w, "IP不能为空", http.StatusBadRequest)
return
}
if rule.Type != "whitelist" && rule.Type != "blacklist" {
rule.Type = "blacklist"
}
rule.Enabled = true
if err := s.db.CreateIPRule(&rule); err != nil {
s.jsonError(w, err.Error(), http.StatusInternalServerError)
return
}
s.jsonResponse(w, http.StatusOK, rule)
default:
s.jsonError(w, "方法不允许", http.StatusMethodNotAllowed)
}
}
// handleIPRuleOperation 单条IP规则操作
func (s *Server) handleIPRuleOperation(w http.ResponseWriter, r *http.Request) {
pathParts := strings.Split(strings.TrimPrefix(r.URL.Path, "/api/ip-rules/"), "/")
idStr := pathParts[0]
if idStr == "" {
s.jsonError(w, "ID不能为空", http.StatusBadRequest)
return
}
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
s.jsonError(w, "无效的ID", http.StatusBadRequest)
return
}
switch r.Method {
case http.MethodPut:
var rule database.IPAccessRule
if err := json.NewDecoder(r.Body).Decode(&rule); err != nil {
s.jsonError(w, "请求格式错误", http.StatusBadRequest)
return
}
rule.ID = id
if err := s.db.UpdateIPRule(&rule); err != nil {
s.jsonError(w, err.Error(), http.StatusInternalServerError)
return
}
s.jsonResponse(w, http.StatusOK, map[string]string{"message": "规则已更新"})
case http.MethodDelete:
if err := s.db.DeleteIPRule(id); err != nil {
s.jsonError(w, err.Error(), http.StatusInternalServerError)
return
}
s.jsonResponse(w, http.StatusOK, map[string]string{"message": "规则已删除"})
default:
s.jsonError(w, "方法不允许", http.StatusMethodNotAllowed)
}
}