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}) }