package handlers import ( "net/netip" "platform/pkg/env" "platform/web/auth" "platform/web/core" "platform/web/globals" s "platform/web/services" "time" "github.com/gofiber/fiber/v2" ) func DebugRegisterProxyBaiYin(c *fiber.Ctx) error { if env.RunMode != env.RunModeDev { return fiber.ErrNotFound } err := s.Proxy.RegisterBaiyin("1a:2b:3c:4d:5e:6f", netip.AddrFrom4([4]byte{127, 0, 0, 1}), "test", "test") if err != nil { return core.NewServErr("注册失败", err) } return nil } // 注册白银代理网关 func ProxyRegisterBaiYin(c *fiber.Ctx) error { _, err := auth.GetAuthCtx(c).PermitOfficialClient() if err != nil { return err } req := new(RegisterProxyBaiyinReq) err = globals.Validator.ParseBody(c, req) if err != nil { return err } addr, err := netip.ParseAddr(req.IP) if err != nil { return core.NewServErr("IP地址格式错误", err) } err = s.Proxy.RegisterBaiyin(req.Name, addr, req.Username, req.Password) if err != nil { return core.NewServErr("注册失败", err) } return nil } type RegisterProxyBaiyinReq struct { Name string `json:"name" validate:"required"` IP string `json:"ip" validate:"required"` Username string `json:"username" validate:"required"` Password string `json:"password" validate:"required"` } // region 报告上线 func ProxyReportOnline(c *fiber.Ctx) (err error) { return c.JSON(map[string]any{ "error": "接口暂不可用", }) // // 检查接口权限 // _, err = auth2.GetAuthCtx(c).PermitSecretClient() // if err != nil { // return err // } // // 验证请求参数 // var req = new(ProxyReportOnlineReq) // err = g.Validator.Validate(c, req) // if err != nil { // return err // } // // 创建代理 // var ip = c.Context().RemoteIP() // var secretBytes = make([]byte, 16) // if _, err := rand.Read(secretBytes); err != nil { // return err // } // var secret = base32.StdEncoding. // WithPadding(base32.NoPadding). // EncodeToString(secretBytes) // slog.Debug("生成随机密钥", "ip", ip, "secret", secret) // var proxy = &m.Proxy{ // Mac: req.Name, // Version: int32(req.Version), // Type: m.ProxyTypeSelfHosted, // IP: ip, // Secret: &secret, // Status: 1, // } // err = q.Proxy. // Clauses(clause.OnConflict{ // UpdateAll: true, // Columns: []clause.Column{ // {Name: q.Proxy.Mac.ColumnName().String()}, // }, // }). // Create(proxy) // if err != nil { // return err // } // // 获取边缘节点信息 // data, err := q.Edge.Where( // q.Edge.ProxyID.Eq(proxy.ID), // ).Find() // if err != nil { // return err // } // edges := make([]*ProxyEdge, len(data)) // for i, edge := range data { // edges[i] = &ProxyEdge{ // Id: edge.ID, // Port: edge.ProxyPort, // Prov: &edge.Prov, // City: &edge.City, // Isp: u.P(edge2.ISP(edge.Isp).String()), // Status: &edge.Status, // Loss: edge.Loss, // Rtt: edge.Rtt, // } // } // // 获取许可配置 // channels, err := q.Channel.Where( // q.Channel.ProxyID.Eq(proxy.ID), // q.Channel.Expiration.Gt(orm.LocalDateTime(time.Now())), // ).Find() // if err != nil { // return err // } // var permits = make([]*ProxyPermit, len(channels)) // for i, channel := range channels { // if channel.EdgeID == nil { // return core.NewBizErr(fmt.Sprintf("权限解析异常,通道缺少边缘节点ID %d", channel.ID)) // } // permits[i] = &ProxyPermit{ // Id: *channel.EdgeID, // Expire: time.Time(channel.Expiration), // Whitelists: u.P(strings.Split(u.Z(channel.Whitelists), ",")), // Username: channel.Username, // Password: channel.Password, // } // } // slog.Debug("注册转发服务", "ip", ip, "id", proxy.ID) // return c.JSON(&ProxyReportOnlineResp{ // Id: proxy.ID, // Secret: secret, // Edges: edges, // Permits: permits, // }) } type ProxyReportOnlineReq struct { Name string `json:"name" validate:"required"` Version int `json:"version" validate:"required"` } type ProxyReportOnlineResp struct { Id int32 `json:"id"` Secret string `json:"secret"` Permits []*ProxyPermit `json:"permits"` Edges []*ProxyEdge `json:"edges"` } // region 报告下线 func ProxyReportOffline(c *fiber.Ctx) (err error) { return c.JSON(map[string]any{ "error": "接口暂不可用", }) // // 检查接口权限 // _, err = auth2.GetAuthCtx(c).PermitSecretClient() // if err != nil { // return err // } // // 验证请求参数 // var req = new(ProxyReportOfflineReq) // err = g.Validator.Validate(c, req) // if err != nil { // return err // } // // 下线转发服务 // _, err = q.Proxy. // Where(q.Proxy.ID.Eq(req.Id)). // UpdateSimple(q.Proxy.Status.Value(0)) // if err != nil { // return err // } // // 下线所有相关的边缘节点 // _, err = q.Edge. // Where(q.Edge.ProxyID.Eq(req.Id)). // UpdateSimple(q.Edge.Status.Value(0)) // if err != nil { // return err // } // return nil } type ProxyReportOfflineReq struct { Id int32 `json:"id" validate:"required"` } // region 报告更新 func ProxyReportUpdate(c *fiber.Ctx) (err error) { return c.JSON(map[string]any{ "error": "接口暂不可用", }) // // 检查接口权限 // _, err = auth2.GetAuthCtx(c).PermitSecretClient() // if err != nil { // return err // } // // 验证请求参数 // var req = new(ProxyReportUpdateReq) // err = g.Validator.Validate(c, req) // if err != nil { // return err // } // // 更新节点信息 // var idsActive = make([]int32, 0, len(req.Edges)) // var idsInactive = make([]int32, 0, len(req.Edges)) // var idsIspUnknown = make([]int32, 0, len(req.Edges)) // var idsIspTelecom = make([]int32, 0, len(req.Edges)) // var idsIspUnicom = make([]int32, 0, len(req.Edges)) // var idsIspMobile = make([]int32, 0, len(req.Edges)) // var otherEdges = make([]*ProxyEdge, 0, len(req.Edges)) // for _, edge := range req.Edges { // // 检查更新ISP // if edge.Isp != nil { // switch edge2.ISPFromStr(*edge.Isp) { // case edge2.IspUnknown: // idsIspUnknown = append(idsIspUnknown, edge.Id) // case edge2.IspChinaTelecom: // idsIspTelecom = append(idsIspTelecom, edge.Id) // case edge2.IspChinaUnicom: // idsIspUnicom = append(idsIspUnicom, edge.Id) // case edge2.IspChinaMobile: // idsIspMobile = append(idsIspMobile, edge.Id) // } // } // // 检查更新状态 // if edge.Status != nil { // if *edge.Status == 1 { // idsActive = append(idsActive, edge.Id) // } else { // idsInactive = append(idsInactive, edge.Id) // } // } // // 无法分类更新 // if edge.Host != nil || edge.Port != nil || edge.Prov != nil || edge.City != nil { // otherEdges = append(otherEdges, edge) // continue // } // } // slog.Debug("更新边缘节点信息", // "active", len(idsActive), // "inactive", len(idsInactive), // "isp_unknown", len(idsIspUnknown), // "isp_telecom", len(idsIspTelecom), // "isp_unicom", len(idsIspUnicom), // "isp_mobile", len(idsIspMobile), // "other_edges", len(otherEdges), // ) // err = q.Q.Transaction(func(q *q.Query) error { // // 更新边缘节点状态 // if len(idsActive) > 0 { // _, err = q.Edge.Debug(). // Where(q.Edge.ID.In(idsActive...)). // UpdateSimple(q.Edge.Status.Value(1)) // if err != nil { // return err // } // } // if len(idsInactive) > 0 { // _, err = q.Edge.Debug(). // Where(q.Edge.ID.In(idsInactive...)). // UpdateSimple(q.Edge.Status.Value(0)) // if err != nil { // return err // } // } // // 更新边缘节点ISP // if len(idsIspUnknown) > 0 { // _, err = q.Edge.Debug(). // Where(q.Edge.ID.In(idsIspUnknown...)). // UpdateSimple(q.Edge.Isp.Value(int32(edge2.IspUnknown))) // if err != nil { // return err // } // } // if len(idsIspTelecom) > 0 { // _, err = q.Edge.Debug(). // Where(q.Edge.ID.In(idsIspTelecom...)). // UpdateSimple(q.Edge.Isp.Value(int32(edge2.IspChinaTelecom))) // if err != nil { // return err // } // } // if len(idsIspUnicom) > 0 { // _, err = q.Edge.Debug(). // Where(q.Edge.ID.In(idsIspUnicom...)). // UpdateSimple(q.Edge.Isp.Value(int32(edge2.IspChinaUnicom))) // if err != nil { // return err // } // } // if len(idsIspMobile) > 0 { // _, err = q.Edge.Debug(). // Where(q.Edge.ID.In(idsIspMobile...)). // UpdateSimple(q.Edge.Isp.Value(int32(edge2.IspChinaMobile))) // if err != nil { // return err // } // } // // 更新其他边缘节点信息 // for _, edge := range otherEdges { // do := q.Edge.Debug().Where(q.Edge.ID.Eq(edge.Id)) // var assigns = make([]field.AssignExpr, 0, 5) // if edge.Host != nil { // assigns = append(assigns, q.Edge.Host.Value(*edge.Host)) // } // if edge.Port != nil { // assigns = append(assigns, q.Edge.ProxyPort.Value(*edge.Port)) // } // if edge.Prov != nil { // assigns = append(assigns, q.Edge.Prov.Value(*edge.Prov)) // } // if edge.City != nil { // assigns = append(assigns, q.Edge.City.Value(*edge.City)) // } // // 更新边缘节点 // _, err := do.UpdateSimple(assigns...) // if err != nil { // return fmt.Errorf("更新边缘节点 %d 失败: %w", edge.Id, err) // } // } // return nil // }) // if err != nil { // return err // } // return nil } type ProxyReportUpdateReq struct { Id int32 `json:"id" validate:"required"` Edges []*ProxyEdge `json:"edges" validate:"required"` } type ProxyPermit struct { Id int32 `json:"id"` Expire time.Time `json:"expire"` Whitelists *[]string `json:"whitelists"` Username *string `json:"username"` Password *string `json:"password"` } type ProxyEdge struct { Id int32 `json:"id"` Host *string `json:"host,omitempty"` // 边缘节点地址 Port *int32 `json:"port,omitempty"` // 边缘节点代理端口 Prov *string `json:"prov,omitempty"` City *string `json:"city,omitempty"` Isp *string `json:"isp,omitempty"` Status *int32 `json:"status,omitempty"` Loss *int32 `json:"loss,omitempty"` // 丢包率 Rtt *int32 `json:"latency,omitempty"` // 延迟 }