Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
const ExportVersion = 1
|
||||
|
||||
type TunnelExportItem struct {
|
||||
ClientID uint `json:"client_id"`
|
||||
ClientName string `json:"client_name,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Mode string `json:"mode"`
|
||||
ListenIP string `json:"listen_ip"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
TargetAddr string `json:"target_addr"`
|
||||
IPForwardMode string `json:"ip_forward_mode"`
|
||||
CustomHeaders string `json:"custom_headers"`
|
||||
Status bool `json:"status"`
|
||||
}
|
||||
|
||||
type HostExportItem struct {
|
||||
ClientID uint `json:"client_id"`
|
||||
ClientName string `json:"client_name,omitempty"`
|
||||
Host string `json:"host"`
|
||||
Location string `json:"location"`
|
||||
Scheme string `json:"scheme"`
|
||||
TargetAddr string `json:"target_addr"`
|
||||
AutoHTTPS bool `json:"auto_https"`
|
||||
IPForwardMode string `json:"ip_forward_mode"`
|
||||
CustomHeaders string `json:"custom_headers"`
|
||||
Status bool `json:"status"`
|
||||
}
|
||||
|
||||
type TunnelExportDoc struct {
|
||||
Version int `json:"version"`
|
||||
ExportedAt time.Time `json:"exported_at"`
|
||||
Items []TunnelExportItem `json:"items"`
|
||||
}
|
||||
|
||||
type HostExportDoc struct {
|
||||
Version int `json:"version"`
|
||||
ExportedAt time.Time `json:"exported_at"`
|
||||
Items []HostExportItem `json:"items"`
|
||||
}
|
||||
|
||||
func TunnelToExportItem(t Tunnel, clientName string) TunnelExportItem {
|
||||
return TunnelExportItem{
|
||||
ClientID: t.ClientID,
|
||||
ClientName: clientName,
|
||||
Name: t.Name,
|
||||
Mode: t.Mode,
|
||||
ListenIP: t.ListenIP,
|
||||
ListenPort: t.ListenPort,
|
||||
TargetAddr: t.TargetAddr,
|
||||
IPForwardMode: t.IPForwardMode,
|
||||
CustomHeaders: t.CustomHeaders,
|
||||
Status: t.Status,
|
||||
}
|
||||
}
|
||||
|
||||
func HostToExportItem(h Host, clientName string) HostExportItem {
|
||||
return HostExportItem{
|
||||
ClientID: h.ClientID,
|
||||
ClientName: clientName,
|
||||
Host: h.Host,
|
||||
Location: h.Location,
|
||||
Scheme: h.Scheme,
|
||||
TargetAddr: h.TargetAddr,
|
||||
AutoHTTPS: h.AutoHTTPS,
|
||||
IPForwardMode: h.IPForwardMode,
|
||||
CustomHeaders: h.CustomHeaders,
|
||||
Status: h.Status,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) FindTunnelByPort(port int) (*Tunnel, error) {
|
||||
var t Tunnel
|
||||
if err := s.db.Where("listen_port = ?", port).First(&t).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func (s *Store) FindHostByRouteGlobal(host, location string) (*Host, error) {
|
||||
if location == "" {
|
||||
location = "/"
|
||||
}
|
||||
var h Host
|
||||
if err := s.db.Where("host = ? AND location = ?", host, location).First(&h).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &h, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetClientByName(name string) (*Client, error) {
|
||||
var c Client
|
||||
if err := s.db.Where("name = ?", name).First(&c).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (s *Store) FindTunnelByListen(clientID uint, listenIP string, listenPort int) (*Tunnel, error) {
|
||||
if listenIP == "" {
|
||||
listenIP = "0.0.0.0"
|
||||
}
|
||||
var t Tunnel
|
||||
if err := s.db.Where("client_id = ? AND listen_ip = ? AND listen_port = ?", clientID, listenIP, listenPort).First(&t).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func (s *Store) FindHostByRoute(clientID uint, host, location string) (*Host, error) {
|
||||
if location == "" {
|
||||
location = "/"
|
||||
}
|
||||
var h Host
|
||||
if err := s.db.Where("client_id = ? AND host = ? AND location = ?", clientID, host, location).First(&h).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &h, nil
|
||||
}
|
||||
|
||||
func ResolveImportClientID(s *Store, clientID uint, clientName string, ownerID uint, isAdmin bool) (uint, error) {
|
||||
if clientID > 0 {
|
||||
if err := ClientOwnerCheck(s, clientID, ownerID, isAdmin); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return clientID, nil
|
||||
}
|
||||
if clientName == "" {
|
||||
return 0, errors.New("client_id or client_name required")
|
||||
}
|
||||
c, err := s.GetClientByName(clientName)
|
||||
if err != nil {
|
||||
return 0, errors.New("client not found: " + clientName)
|
||||
}
|
||||
if err := ClientOwnerCheck(s, c.ID, ownerID, isAdmin); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return c.ID, nil
|
||||
}
|
||||
Reference in New Issue
Block a user