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 }