612d68f56f
Go + Vue 管理台,SQLite 持久化;支持隧道/域名穿透、域名转发插件链、访客认证、 IP 规则、API Key、Docker 单镜像部署;配置通过 Web 系统设置管理,无需 YAML 文件。 Co-authored-by: Cursor <cursoragent@cursor.com>
145 lines
4.2 KiB
Go
145 lines
4.2 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/wormhole/wormhole/internal/auth"
|
|
"github.com/wormhole/wormhole/internal/forwardplugin"
|
|
"github.com/wormhole/wormhole/internal/store"
|
|
)
|
|
|
|
func (s *Server) listDomainForwards(c *gin.Context) {
|
|
if !auth.IsAdmin(getClaims(c).Role) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
p := pageParams(c)
|
|
items, total, err := s.store.ListDomainForwardsPaged(p)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"items": items, "total": total})
|
|
}
|
|
|
|
func (s *Server) createDomainForward(c *gin.Context) {
|
|
if !auth.IsAdmin(getClaims(c).Role) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
var req store.DomainForward
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
|
|
return
|
|
}
|
|
if err := store.ValidateDomainForward(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if err := s.store.RouteConflict(req.SourceHost, req.SourceLocation, 0, 0); err != nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if err := s.store.CreateDomainForward(&req); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
s.cache.UpsertDomainForward(&req)
|
|
c.JSON(http.StatusOK, req)
|
|
}
|
|
|
|
func (s *Server) updateDomainForward(c *gin.Context) {
|
|
if !auth.IsAdmin(getClaims(c).Role) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
existing, err := s.store.GetDomainForwardByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
|
return
|
|
}
|
|
var req store.DomainForward
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
|
|
return
|
|
}
|
|
req.ID = existing.ID
|
|
if req.Socks5Pass == "" {
|
|
req.Socks5Pass = existing.Socks5Pass
|
|
}
|
|
if req.HTTPProxyPass == "" {
|
|
req.HTTPProxyPass = existing.HTTPProxyPass
|
|
}
|
|
if err := store.ValidateDomainForward(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if err := s.store.RouteConflict(req.SourceHost, req.SourceLocation, uint(id), 0); err != nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if err := s.store.UpdateDomainForward(&req); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
forwardplugin.InvalidateForwardCache(uint(id))
|
|
s.cache.UpsertDomainForward(&req)
|
|
c.JSON(http.StatusOK, req)
|
|
}
|
|
|
|
func (s *Server) deleteDomainForward(c *gin.Context) {
|
|
if !auth.IsAdmin(getClaims(c).Role) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if _, err := s.store.GetDomainForwardByID(uint(id)); err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
|
return
|
|
}
|
|
if err := s.store.DeleteDomainForward(uint(id)); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
forwardplugin.InvalidateForwardCache(uint(id))
|
|
s.cache.DeleteDomainForward(uint(id))
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
}
|
|
|
|
func (s *Server) pauseDomainForward(c *gin.Context) {
|
|
if !auth.IsAdmin(getClaims(c).Role) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
existing, err := s.store.GetDomainForwardByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
|
return
|
|
}
|
|
existing.Status = false
|
|
_ = s.store.UpdateDomainForward(existing)
|
|
s.cache.UpsertDomainForward(existing)
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
}
|
|
|
|
func (s *Server) resumeDomainForward(c *gin.Context) {
|
|
if !auth.IsAdmin(getClaims(c).Role) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
|
|
return
|
|
}
|
|
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
existing, err := s.store.GetDomainForwardByID(uint(id))
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
|
return
|
|
}
|
|
existing.Status = true
|
|
_ = s.store.UpdateDomainForward(existing)
|
|
s.cache.UpsertDomainForward(existing)
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
}
|