612d68f56f
Go + Vue 管理台,SQLite 持久化;支持隧道/域名穿透、域名转发插件链、访客认证、 IP 规则、API Key、Docker 单镜像部署;配置通过 Web 系统设置管理,无需 YAML 文件。 Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
2.1 KiB
Go
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()})
|
|
}
|