Files
Wormhole/internal/api/visitor_helpers.go
T
rose_cat707 612d68f56f feat: Wormhole 内网穿透与反向代理网关
Go + Vue 管理台,SQLite 持久化;支持隧道/域名穿透、域名转发插件链、访客认证、
IP 规则、API Key、Docker 单镜像部署;配置通过 Web 系统设置管理,无需 YAML 文件。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 12:15:02 +08:00

90 lines
2.1 KiB
Go

package api
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/wormhole/wormhole/internal/store"
)
type hostRequest struct {
store.Host
VisitorIDs []uint `json:"visitor_ids"`
}
type tunnelRequest struct {
store.Tunnel
VisitorIDs []uint `json:"visitor_ids"`
}
type hostView struct {
store.Host
VisitorIDs []uint `json:"visitor_ids"`
}
type tunnelView struct {
store.Tunnel
VisitorIDs []uint `json:"visitor_ids"`
}
func (s *Server) enrichHostView(h store.Host) (hostView, error) {
ids, err := s.store.ListResourceVisitorIDs("host", h.ID)
if err != nil {
return hostView{}, err
}
return hostView{Host: h, VisitorIDs: ids}, nil
}
func (s *Server) enrichTunnelView(t store.Tunnel) (tunnelView, error) {
ids, err := s.store.ListResourceVisitorIDs("tunnel", t.ID)
if err != nil {
return tunnelView{}, err
}
return tunnelView{Tunnel: t, VisitorIDs: ids}, nil
}
func (s *Server) saveResourceVisitors(resourceType string, resourceID uint, enabled bool, bindMode string, visitorIDs []uint) error {
if !enabled {
_ = s.store.SetResourceVisitors(resourceType, resourceID, nil)
s.cache.SetResourceVisitors(resourceType, resourceID, nil)
return nil
}
if bindMode == "" {
bindMode = "all"
}
if bindMode == "selected" {
if len(visitorIDs) == 0 {
return fmt.Errorf("请至少选择一个访客用户")
}
if err := s.validateVisitorIDs(visitorIDs); err != nil {
return err
}
if err := s.store.SetResourceVisitors(resourceType, resourceID, visitorIDs); err != nil {
return err
}
s.cache.SetResourceVisitors(resourceType, resourceID, visitorIDs)
return nil
}
_ = s.store.SetResourceVisitors(resourceType, resourceID, nil)
s.cache.SetResourceVisitors(resourceType, resourceID, nil)
return nil
}
func (s *Server) validateVisitorIDs(ids []uint) error {
for _, id := range ids {
user, err := s.store.GetUserByID(id)
if err != nil {
return fmt.Errorf("访客用户 #%d 不存在", id)
}
if user.Role != "visitor" {
return fmt.Errorf("用户 %s 不是访客账号", user.Username)
}
}
return nil
}
func writeVisitorSaveError(c *gin.Context, err error) {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}