Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22d15bcb27 | ||
|
|
361fb9b868 | ||
|
|
2d675f4281 | ||
|
|
e19bbdf891 | ||
|
|
d48c0a2328 | ||
|
|
a70b20cf13 | ||
|
|
eb83017ed4 | ||
|
|
98ba31174b | ||
|
|
aa28e84507 | ||
|
|
da8fe918fe | ||
|
|
2b26bed97c | ||
|
|
5e50518bd9 | ||
|
|
e49db916f8 | ||
|
|
16083fd0d7 | ||
|
|
e0e2729fef | ||
|
|
9b95042936 | ||
|
|
44d45c53a1 | ||
|
|
c5fb340eb7 | ||
|
|
cbb61d2f0e | ||
|
|
a143714370 | ||
|
|
0e1a98c5d8 | ||
|
|
707a9f8caf | ||
|
|
da391f565b | ||
|
|
78f396129f |
@@ -1,7 +1,7 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "1.3.1"
|
||||
Version = "1.3.2"
|
||||
|
||||
ProductName = "Edge API"
|
||||
ProcessName = "edge-api"
|
||||
@@ -20,7 +20,7 @@ const (
|
||||
|
||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||
|
||||
NodeVersion = "1.3.1"
|
||||
NodeVersion = "1.3.2"
|
||||
|
||||
// SQLVersion SQL版本号
|
||||
SQLVersion = "11"
|
||||
|
||||
9
internal/const/const_community.go
Normal file
9
internal/const/const_community.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
// DefaultMaxNodes 节点数限制
|
||||
DefaultMaxNodes int32 = 50
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
package acme
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -31,7 +32,7 @@ func init() {
|
||||
func (this *ACMETaskLogDAO) CreateACMETaskLog(tx *dbs.Tx, taskId int64, isOk bool, errMsg string) error {
|
||||
var op = NewACMETaskLogOperator()
|
||||
op.TaskId = taskId
|
||||
op.Error = errMsg
|
||||
op.Error = utils.LimitString(errMsg, 1024)
|
||||
op.IsOk = isOk
|
||||
err := this.Save(tx, op)
|
||||
return err
|
||||
|
||||
@@ -260,7 +260,7 @@ func (this *AdminDAO) FindAllAdminModules(tx *dbs.Tx) (result []*Admin, err erro
|
||||
_, err = this.Query(tx).
|
||||
State(AdminStateEnabled).
|
||||
Attr("isOn", true).
|
||||
Result("id", "modules", "isSuper", "fullname", "theme").
|
||||
Result("id", "modules", "isSuper", "fullname", "theme", "lang").
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
@@ -313,6 +313,14 @@ func (this *AdminDAO) UpdateAdminTheme(tx *dbs.Tx, adminId int64, theme string)
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// UpdateAdminLang 设置管理员语言
|
||||
func (this *AdminDAO) UpdateAdminLang(tx *dbs.Tx, adminId int64, langCode string) error {
|
||||
return this.Query(tx).
|
||||
Pk(adminId).
|
||||
Set("lang", langCode).
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// CheckSuperAdmin 检查管理员是否为超级管理员
|
||||
func (this *AdminDAO) CheckSuperAdmin(tx *dbs.Tx, adminId int64) (bool, error) {
|
||||
if adminId <= 0 {
|
||||
|
||||
@@ -444,6 +444,7 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
|
||||
|
||||
var config = &firewallconfigs.HTTPFirewallPolicy{}
|
||||
config.Id = int64(policy.Id)
|
||||
config.ServerId = int64(policy.ServerId)
|
||||
config.IsOn = policy.IsOn
|
||||
config.Name = policy.Name
|
||||
config.Description = policy.Description
|
||||
@@ -667,6 +668,19 @@ func (this *HTTPFirewallPolicyDAO) FindFirewallPolicyIdsWithServerId(tx *dbs.Tx,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithFirewallPolicyId 根据策略查找网站ID
|
||||
func (this *HTTPFirewallPolicyDAO) FindServerIdWithFirewallPolicyId(tx *dbs.Tx, policyId int64) (serverId int64, err error) {
|
||||
if policyId <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
serverId, err = this.Query(tx).
|
||||
Pk(policyId).
|
||||
Result("serverId").
|
||||
FindInt64Col(0)
|
||||
return
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *HTTPFirewallPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
|
||||
webIds, err := SharedHTTPWebDAO.FindAllWebIdsWithHTTPFirewallPolicyId(tx, policyId)
|
||||
|
||||
@@ -1299,6 +1299,61 @@ func (this *HTTPWebDAO) UpdateWebRequestScripts(tx *dbs.Tx, webId int64, config
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
// UpdateWebRequestScriptsAsPassed 设置请求脚本为审核通过
|
||||
func (this *HTTPWebDAO) UpdateWebRequestScriptsAsPassed(tx *dbs.Tx, webId int64, codeMD5 string) error {
|
||||
if webId <= 0 || len(codeMD5) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
configString, err := this.Query(tx).
|
||||
Pk(webId).
|
||||
Result("requestScripts").
|
||||
FindStringCol("")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var config = &serverconfigs.HTTPRequestScriptsConfig{}
|
||||
if len(configString) == 0 {
|
||||
return nil
|
||||
}
|
||||
err = json.Unmarshal([]byte(configString), config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var found bool
|
||||
|
||||
for _, group := range config.AllGroups() {
|
||||
for _, script := range group.Scripts {
|
||||
if script.AuditingCodeMD5 == codeMD5 {
|
||||
script.Code = script.AuditingCode
|
||||
script.AuditingCode = ""
|
||||
script.AuditingCodeMD5 = ""
|
||||
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = this.Query(tx).
|
||||
Pk(webId).
|
||||
Set("requestScripts", configJSON).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindWebRequestScripts 查找服务的脚本设置
|
||||
func (this *HTTPWebDAO) FindWebRequestScripts(tx *dbs.Tx, webId int64) (*serverconfigs.HTTPRequestScriptsConfig, error) {
|
||||
configString, err := this.Query(tx).
|
||||
|
||||
@@ -582,6 +582,62 @@ func (this *IPItemDAO) ListAllEnabledIPItems(tx *dbs.Tx, sourceUserId int64, key
|
||||
return
|
||||
}
|
||||
|
||||
// ListAllIPItemIds 搜索所有IP Id列表
|
||||
func (this *IPItemDAO) ListAllIPItemIds(tx *dbs.Tx, sourceUserId int64, keyword string, ip string, listId int64, unread bool, eventLevel string, listType string, offset int64, size int64) (itemIds []int64, err error) {
|
||||
var query = this.Query(tx)
|
||||
if sourceUserId > 0 {
|
||||
if listId <= 0 {
|
||||
query.Where("((listId=" + types.String(firewallconfigs.GlobalListId) + " AND sourceUserId=:sourceUserId) OR listId IN (SELECT id FROM " + SharedIPListDAO.Table + " WHERE userId=:sourceUserId AND state=1))")
|
||||
query.Param("sourceUserId", sourceUserId)
|
||||
} else if listId == firewallconfigs.GlobalListId {
|
||||
query.Attr("sourceUserId", sourceUserId)
|
||||
query.UseIndex("sourceUserId")
|
||||
}
|
||||
}
|
||||
if len(keyword) > 0 {
|
||||
if net.ParseIP(keyword) != nil { // 是一个IP地址
|
||||
query.Attr("ipFrom", keyword)
|
||||
} else {
|
||||
query.Like("ipFrom", dbutils.QuoteLike(keyword))
|
||||
}
|
||||
}
|
||||
if len(ip) > 0 {
|
||||
query.Attr("ipFrom", ip)
|
||||
}
|
||||
if listId > 0 {
|
||||
query.Attr("listId", listId)
|
||||
} else {
|
||||
if len(listType) > 0 {
|
||||
query.Where("(listId=" + types.String(firewallconfigs.GlobalListId) + " OR listId IN (SELECT id FROM " + SharedIPListDAO.Table + " WHERE state=1 AND type=:listType))")
|
||||
query.Param("listType", listType)
|
||||
} else {
|
||||
query.Where("(listId=" + types.String(firewallconfigs.GlobalListId) + " OR listId IN (SELECT id FROM " + SharedIPListDAO.Table + " WHERE state=1))")
|
||||
}
|
||||
}
|
||||
if unread {
|
||||
query.Attr("isRead", 0)
|
||||
}
|
||||
if len(eventLevel) > 0 {
|
||||
query.Attr("eventLevel", eventLevel)
|
||||
}
|
||||
result, err := query.
|
||||
ResultPk().
|
||||
State(IPItemStateEnabled).
|
||||
Where("(expiredAt=0 OR expiredAt>:expiredAt)").
|
||||
Param("expiredAt", time.Now().Unix()).
|
||||
DescPk().
|
||||
Offset(offset).
|
||||
Size(size).
|
||||
FindAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, itemOne := range result {
|
||||
itemIds = append(itemIds, int64(itemOne.(*IPItem).Id))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateItemsRead 设置所有未已读
|
||||
func (this *IPItemDAO) UpdateItemsRead(tx *dbs.Tx, sourceUserId int64) error {
|
||||
var query = this.Query(tx).
|
||||
|
||||
@@ -339,3 +339,16 @@ func (this *IPListDAO) NotifyUpdate(tx *dbs.Tx, listId int64, taskType NodeTaskT
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindServerIdWithListId 查找IP名单对应的网站ID
|
||||
func (this *IPListDAO) FindServerIdWithListId(tx *dbs.Tx, listId int64) (serverId int64, err error) {
|
||||
if listId <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
serverId, err = this.Query(tx).
|
||||
Pk(listId).
|
||||
Result("serverId").
|
||||
FindInt64Col(0)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1043,7 +1043,7 @@ func (this *NodeClusterDAO) UpdateClusterWebPPolicy(tx *dbs.Tx, clusterId int64,
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, clusterId)
|
||||
return this.NotifyWebPPolicyUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
webpPolicyJSON, err := json.Marshal(webpPolicy)
|
||||
@@ -1058,7 +1058,7 @@ func (this *NodeClusterDAO) UpdateClusterWebPPolicy(tx *dbs.Tx, clusterId int64,
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, clusterId)
|
||||
return this.NotifyWebPPolicyUpdate(tx, clusterId)
|
||||
}
|
||||
|
||||
// FindClusterWebPPolicy 查询WebP设置
|
||||
@@ -1083,7 +1083,7 @@ func (this *NodeClusterDAO) FindClusterWebPPolicy(tx *dbs.Tx, clusterId int64, c
|
||||
return nodeconfigs.DefaultWebPImagePolicy, nil
|
||||
}
|
||||
|
||||
var policy = &nodeconfigs.WebPImagePolicy{}
|
||||
var policy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(webpJSON, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1518,6 +1518,11 @@ func (this *NodeClusterDAO) NotifyTOAUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeTOAChanged)
|
||||
}
|
||||
|
||||
// NotifyWebPPolicyUpdate 通知WebP策略更新
|
||||
func (this *NodeClusterDAO) NotifyWebPPolicyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeWebPPolicyChanged)
|
||||
}
|
||||
|
||||
// NotifyDNSUpdate 通知DNS更新
|
||||
// TODO 更新新的DNS解析记录的同时,需要删除老的DNS解析记录
|
||||
func (this *NodeClusterDAO) NotifyDNSUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||
|
||||
@@ -1151,7 +1151,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
||||
|
||||
// webp
|
||||
if IsNotNull(nodeCluster.Webp) {
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
var webpPolicy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(nodeCluster.Webp, webpPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
func (this *NodeDAO) CountAllAuthorityNodes(tx *dbs.Tx) (int64, error) {
|
||||
@@ -15,5 +18,18 @@ func (this *NodeDAO) CountAllAuthorityNodes(tx *dbs.Tx) (int64, error) {
|
||||
}
|
||||
|
||||
func (this *NodeDAO) CheckNodesLimit(tx *dbs.Tx) error {
|
||||
var maxNodes = teaconst.DefaultMaxNodes
|
||||
|
||||
// 检查节点数量
|
||||
if maxNodes > 0 {
|
||||
count, err := this.CountAllAuthorityNodes(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count >= int64(maxNodes) {
|
||||
return errors.New("超出最大节点数限制:" + types.String(maxNodes) + ",当前已用:" + types.String(count) + ",请自行修改源码修改此限制(EdgeAPI/internal/const/const_community.go) 或者 购买商业版本授权。")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ const (
|
||||
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化
|
||||
NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3策略变化
|
||||
NodeTaskTypeNetworkSecurityPolicyChanged NodeTaskType = "networkSecurityPolicyChanged" // 网络安全策略变化
|
||||
NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP策略变化
|
||||
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
||||
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化
|
||||
|
||||
|
||||
@@ -3,70 +3,82 @@ package models
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
PlanField_Id dbs.FieldName = "id" // ID
|
||||
PlanField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||
PlanField_Name dbs.FieldName = "name" // 套餐名
|
||||
PlanField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||
PlanField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||
PlanField_Features dbs.FieldName = "features" // 允许的功能
|
||||
PlanField_TrafficPrice dbs.FieldName = "trafficPrice" // 流量价格设定
|
||||
PlanField_BandwidthPrice dbs.FieldName = "bandwidthPrice" // 带宽价格
|
||||
PlanField_MonthlyPrice dbs.FieldName = "monthlyPrice" // 月付
|
||||
PlanField_SeasonallyPrice dbs.FieldName = "seasonallyPrice" // 季付
|
||||
PlanField_YearlyPrice dbs.FieldName = "yearlyPrice" // 年付
|
||||
PlanField_PriceType dbs.FieldName = "priceType" // 价格类型
|
||||
PlanField_Order dbs.FieldName = "order" // 排序
|
||||
PlanField_State dbs.FieldName = "state" // 状态
|
||||
PlanField_TotalServers dbs.FieldName = "totalServers" // 可以绑定的网站数量
|
||||
PlanField_TotalServerNamesPerServer dbs.FieldName = "totalServerNamesPerServer" // 每个网站可以绑定的域名数量
|
||||
PlanField_TotalServerNames dbs.FieldName = "totalServerNames" // 总域名数量
|
||||
PlanField_MonthlyRequests dbs.FieldName = "monthlyRequests" // 每月访问量额度
|
||||
PlanField_DailyRequests dbs.FieldName = "dailyRequests" // 每日访问量额度
|
||||
PlanField_Id dbs.FieldName = "id" // ID
|
||||
PlanField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||
PlanField_Name dbs.FieldName = "name" // 套餐名
|
||||
PlanField_Description dbs.FieldName = "description" // 描述
|
||||
PlanField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||
PlanField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||
PlanField_Features dbs.FieldName = "features" // 允许的功能
|
||||
PlanField_HasFullFeatures dbs.FieldName = "hasFullFeatures" // 是否有完整的功能
|
||||
PlanField_TrafficPrice dbs.FieldName = "trafficPrice" // 流量价格设定
|
||||
PlanField_BandwidthPrice dbs.FieldName = "bandwidthPrice" // 带宽价格
|
||||
PlanField_MonthlyPrice dbs.FieldName = "monthlyPrice" // 月付
|
||||
PlanField_SeasonallyPrice dbs.FieldName = "seasonallyPrice" // 季付
|
||||
PlanField_YearlyPrice dbs.FieldName = "yearlyPrice" // 年付
|
||||
PlanField_PriceType dbs.FieldName = "priceType" // 价格类型
|
||||
PlanField_Order dbs.FieldName = "order" // 排序
|
||||
PlanField_State dbs.FieldName = "state" // 状态
|
||||
PlanField_TotalServers dbs.FieldName = "totalServers" // 可以绑定的网站数量
|
||||
PlanField_TotalServerNamesPerServer dbs.FieldName = "totalServerNamesPerServer" // 每个网站可以绑定的域名数量
|
||||
PlanField_TotalServerNames dbs.FieldName = "totalServerNames" // 总域名数量
|
||||
PlanField_MonthlyRequests dbs.FieldName = "monthlyRequests" // 每月访问量额度
|
||||
PlanField_DailyRequests dbs.FieldName = "dailyRequests" // 每日访问量额度
|
||||
PlanField_DailyWebsocketConnections dbs.FieldName = "dailyWebsocketConnections" // 每日Websocket连接数
|
||||
PlanField_MonthlyWebsocketConnections dbs.FieldName = "monthlyWebsocketConnections" // 每月Websocket连接数
|
||||
)
|
||||
|
||||
// Plan 用户套餐
|
||||
type Plan struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 套餐名
|
||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||
TrafficLimit dbs.JSON `field:"trafficLimit"` // 流量限制
|
||||
Features dbs.JSON `field:"features"` // 允许的功能
|
||||
TrafficPrice dbs.JSON `field:"trafficPrice"` // 流量价格设定
|
||||
BandwidthPrice dbs.JSON `field:"bandwidthPrice"` // 带宽价格
|
||||
MonthlyPrice float64 `field:"monthlyPrice"` // 月付
|
||||
SeasonallyPrice float64 `field:"seasonallyPrice"` // 季付
|
||||
YearlyPrice float64 `field:"yearlyPrice"` // 年付
|
||||
PriceType string `field:"priceType"` // 价格类型
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 状态
|
||||
TotalServers uint32 `field:"totalServers"` // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer uint32 `field:"totalServerNamesPerServer"` // 每个网站可以绑定的域名数量
|
||||
TotalServerNames uint32 `field:"totalServerNames"` // 总域名数量
|
||||
MonthlyRequests uint64 `field:"monthlyRequests"` // 每月访问量额度
|
||||
DailyRequests uint64 `field:"dailyRequests"` // 每日访问量额度
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 套餐名
|
||||
Description string `field:"description"` // 描述
|
||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||
TrafficLimit dbs.JSON `field:"trafficLimit"` // 流量限制
|
||||
Features dbs.JSON `field:"features"` // 允许的功能
|
||||
HasFullFeatures bool `field:"hasFullFeatures"` // 是否有完整的功能
|
||||
TrafficPrice dbs.JSON `field:"trafficPrice"` // 流量价格设定
|
||||
BandwidthPrice dbs.JSON `field:"bandwidthPrice"` // 带宽价格
|
||||
MonthlyPrice float64 `field:"monthlyPrice"` // 月付
|
||||
SeasonallyPrice float64 `field:"seasonallyPrice"` // 季付
|
||||
YearlyPrice float64 `field:"yearlyPrice"` // 年付
|
||||
PriceType string `field:"priceType"` // 价格类型
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 状态
|
||||
TotalServers uint32 `field:"totalServers"` // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer uint32 `field:"totalServerNamesPerServer"` // 每个网站可以绑定的域名数量
|
||||
TotalServerNames uint32 `field:"totalServerNames"` // 总域名数量
|
||||
MonthlyRequests uint64 `field:"monthlyRequests"` // 每月访问量额度
|
||||
DailyRequests uint64 `field:"dailyRequests"` // 每日访问量额度
|
||||
DailyWebsocketConnections uint64 `field:"dailyWebsocketConnections"` // 每日Websocket连接数
|
||||
MonthlyWebsocketConnections uint64 `field:"monthlyWebsocketConnections"` // 每月Websocket连接数
|
||||
}
|
||||
|
||||
type PlanOperator struct {
|
||||
Id any // ID
|
||||
IsOn any // 是否启用
|
||||
Name any // 套餐名
|
||||
ClusterId any // 集群ID
|
||||
TrafficLimit any // 流量限制
|
||||
Features any // 允许的功能
|
||||
TrafficPrice any // 流量价格设定
|
||||
BandwidthPrice any // 带宽价格
|
||||
MonthlyPrice any // 月付
|
||||
SeasonallyPrice any // 季付
|
||||
YearlyPrice any // 年付
|
||||
PriceType any // 价格类型
|
||||
Order any // 排序
|
||||
State any // 状态
|
||||
TotalServers any // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer any // 每个网站可以绑定的域名数量
|
||||
TotalServerNames any // 总域名数量
|
||||
MonthlyRequests any // 每月访问量额度
|
||||
DailyRequests any // 每日访问量额度
|
||||
Id any // ID
|
||||
IsOn any // 是否启用
|
||||
Name any // 套餐名
|
||||
Description any // 描述
|
||||
ClusterId any // 集群ID
|
||||
TrafficLimit any // 流量限制
|
||||
Features any // 允许的功能
|
||||
HasFullFeatures any // 是否有完整的功能
|
||||
TrafficPrice any // 流量价格设定
|
||||
BandwidthPrice any // 带宽价格
|
||||
MonthlyPrice any // 月付
|
||||
SeasonallyPrice any // 季付
|
||||
YearlyPrice any // 年付
|
||||
PriceType any // 价格类型
|
||||
Order any // 排序
|
||||
State any // 状态
|
||||
TotalServers any // 可以绑定的网站数量
|
||||
TotalServerNamesPerServer any // 每个网站可以绑定的域名数量
|
||||
TotalServerNames any // 总域名数量
|
||||
MonthlyRequests any // 每月访问量额度
|
||||
DailyRequests any // 每日访问量额度
|
||||
DailyWebsocketConnections any // 每日Websocket连接数
|
||||
MonthlyWebsocketConnections any // 每月Websocket连接数
|
||||
}
|
||||
|
||||
func NewPlanOperator() *PlanOperator {
|
||||
|
||||
@@ -59,7 +59,7 @@ func init() {
|
||||
|
||||
// UpdateUserPlanBandwidth 写入数据
|
||||
// 暂时不使用region区分
|
||||
func (this *UserPlanBandwidthStatDAO) UpdateUserPlanBandwidth(tx *dbs.Tx, userId int64, userPlanId int64, regionId int64, day string, timeAt string, bandwidthBytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64) error {
|
||||
func (this *UserPlanBandwidthStatDAO) UpdateUserPlanBandwidth(tx *dbs.Tx, userId int64, userPlanId int64, regionId int64, day string, timeAt string, bandwidthBytes int64, totalBytes int64, cachedBytes int64, attackBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64, countWebsocketConnections int64) error {
|
||||
if userId <= 0 || userPlanId <= 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -73,29 +73,32 @@ func (this *UserPlanBandwidthStatDAO) UpdateUserPlanBandwidth(tx *dbs.Tx, userId
|
||||
Param("countRequests", countRequests).
|
||||
Param("countCachedRequests", countCachedRequests).
|
||||
Param("countAttackRequests", countAttackRequests).
|
||||
Param("countWebsocketConnections", countWebsocketConnections).
|
||||
InsertOrUpdateQuickly(maps.Map{
|
||||
"userId": userId,
|
||||
"userPlanId": userPlanId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bandwidthBytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"cachedBytes": cachedBytes,
|
||||
"attackBytes": attackBytes,
|
||||
"countRequests": countRequests,
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
"userId": userId,
|
||||
"userPlanId": userPlanId,
|
||||
"regionId": regionId,
|
||||
"day": day,
|
||||
"timeAt": timeAt,
|
||||
"bytes": bandwidthBytes,
|
||||
"totalBytes": totalBytes,
|
||||
"avgBytes": totalBytes / 300,
|
||||
"cachedBytes": cachedBytes,
|
||||
"attackBytes": attackBytes,
|
||||
"countRequests": countRequests,
|
||||
"countCachedRequests": countCachedRequests,
|
||||
"countAttackRequests": countAttackRequests,
|
||||
"countWebsocketConnections": countWebsocketConnections,
|
||||
}, maps.Map{
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前,所以这里不用担心先后顺序的问题
|
||||
"totalBytes": dbs.SQL("totalBytes+:totalBytes"),
|
||||
"cachedBytes": dbs.SQL("cachedBytes+:cachedBytes"),
|
||||
"attackBytes": dbs.SQL("attackBytes+:attackBytes"),
|
||||
"countRequests": dbs.SQL("countRequests+:countRequests"),
|
||||
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
|
||||
"countAttackRequests": dbs.SQL("countAttackRequests+:countAttackRequests"),
|
||||
"bytes": dbs.SQL("bytes+:bytes"),
|
||||
"avgBytes": dbs.SQL("(totalBytes+:totalBytes)/300"), // 因为生成SQL语句时会自动将avgBytes排在totalBytes之前,所以这里不用担心先后顺序的问题
|
||||
"totalBytes": dbs.SQL("totalBytes+:totalBytes"),
|
||||
"cachedBytes": dbs.SQL("cachedBytes+:cachedBytes"),
|
||||
"attackBytes": dbs.SQL("attackBytes+:attackBytes"),
|
||||
"countRequests": dbs.SQL("countRequests+:countRequests"),
|
||||
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
|
||||
"countAttackRequests": dbs.SQL("countAttackRequests+:countAttackRequests"),
|
||||
"countWebsocketConnections": dbs.SQL("countWebsocketConnections+:countWebsocketConnections"),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,55 +3,58 @@ package models
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
UserPlanBandwidthStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanBandwidthStatField_UserId dbs.FieldName = "userId" // 用户ID
|
||||
UserPlanBandwidthStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanBandwidthStatField_Day dbs.FieldName = "day" // 日期YYYYMMDD
|
||||
UserPlanBandwidthStatField_TimeAt dbs.FieldName = "timeAt" // 时间点HHII
|
||||
UserPlanBandwidthStatField_Bytes dbs.FieldName = "bytes" // 带宽
|
||||
UserPlanBandwidthStatField_RegionId dbs.FieldName = "regionId" // 区域ID
|
||||
UserPlanBandwidthStatField_TotalBytes dbs.FieldName = "totalBytes" // 总流量
|
||||
UserPlanBandwidthStatField_AvgBytes dbs.FieldName = "avgBytes" // 平均流量
|
||||
UserPlanBandwidthStatField_CachedBytes dbs.FieldName = "cachedBytes" // 缓存的流量
|
||||
UserPlanBandwidthStatField_AttackBytes dbs.FieldName = "attackBytes" // 攻击流量
|
||||
UserPlanBandwidthStatField_CountRequests dbs.FieldName = "countRequests" // 请求数
|
||||
UserPlanBandwidthStatField_CountCachedRequests dbs.FieldName = "countCachedRequests" // 缓存的请求数
|
||||
UserPlanBandwidthStatField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 攻击请求数
|
||||
UserPlanBandwidthStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanBandwidthStatField_UserId dbs.FieldName = "userId" // 用户ID
|
||||
UserPlanBandwidthStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanBandwidthStatField_Day dbs.FieldName = "day" // 日期YYYYMMDD
|
||||
UserPlanBandwidthStatField_TimeAt dbs.FieldName = "timeAt" // 时间点HHII
|
||||
UserPlanBandwidthStatField_Bytes dbs.FieldName = "bytes" // 带宽
|
||||
UserPlanBandwidthStatField_RegionId dbs.FieldName = "regionId" // 区域ID
|
||||
UserPlanBandwidthStatField_TotalBytes dbs.FieldName = "totalBytes" // 总流量
|
||||
UserPlanBandwidthStatField_AvgBytes dbs.FieldName = "avgBytes" // 平均流量
|
||||
UserPlanBandwidthStatField_CachedBytes dbs.FieldName = "cachedBytes" // 缓存的流量
|
||||
UserPlanBandwidthStatField_AttackBytes dbs.FieldName = "attackBytes" // 攻击流量
|
||||
UserPlanBandwidthStatField_CountRequests dbs.FieldName = "countRequests" // 请求数
|
||||
UserPlanBandwidthStatField_CountCachedRequests dbs.FieldName = "countCachedRequests" // 缓存的请求数
|
||||
UserPlanBandwidthStatField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 攻击请求数
|
||||
UserPlanBandwidthStatField_CountWebsocketConnections dbs.FieldName = "countWebsocketConnections" // Websocket连接数
|
||||
)
|
||||
|
||||
// UserPlanBandwidthStat 用户套餐带宽峰值
|
||||
type UserPlanBandwidthStat struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHII
|
||||
Bytes uint64 `field:"bytes"` // 带宽
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
TotalBytes uint64 `field:"totalBytes"` // 总流量
|
||||
AvgBytes uint64 `field:"avgBytes"` // 平均流量
|
||||
CachedBytes uint64 `field:"cachedBytes"` // 缓存的流量
|
||||
AttackBytes uint64 `field:"attackBytes"` // 攻击流量
|
||||
CountRequests uint64 `field:"countRequests"` // 请求数
|
||||
CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存的请求数
|
||||
CountAttackRequests uint64 `field:"countAttackRequests"` // 攻击请求数
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Day string `field:"day"` // 日期YYYYMMDD
|
||||
TimeAt string `field:"timeAt"` // 时间点HHII
|
||||
Bytes uint64 `field:"bytes"` // 带宽
|
||||
RegionId uint32 `field:"regionId"` // 区域ID
|
||||
TotalBytes uint64 `field:"totalBytes"` // 总流量
|
||||
AvgBytes uint64 `field:"avgBytes"` // 平均流量
|
||||
CachedBytes uint64 `field:"cachedBytes"` // 缓存的流量
|
||||
AttackBytes uint64 `field:"attackBytes"` // 攻击流量
|
||||
CountRequests uint64 `field:"countRequests"` // 请求数
|
||||
CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存的请求数
|
||||
CountAttackRequests uint64 `field:"countAttackRequests"` // 攻击请求数
|
||||
CountWebsocketConnections uint64 `field:"countWebsocketConnections"` // Websocket连接数
|
||||
}
|
||||
|
||||
type UserPlanBandwidthStatOperator struct {
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHII
|
||||
Bytes any // 带宽
|
||||
RegionId any // 区域ID
|
||||
TotalBytes any // 总流量
|
||||
AvgBytes any // 平均流量
|
||||
CachedBytes any // 缓存的流量
|
||||
AttackBytes any // 攻击流量
|
||||
CountRequests any // 请求数
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Day any // 日期YYYYMMDD
|
||||
TimeAt any // 时间点HHII
|
||||
Bytes any // 带宽
|
||||
RegionId any // 区域ID
|
||||
TotalBytes any // 总流量
|
||||
AvgBytes any // 平均流量
|
||||
CachedBytes any // 缓存的流量
|
||||
AttackBytes any // 攻击流量
|
||||
CountRequests any // 请求数
|
||||
CountCachedRequests any // 缓存的请求数
|
||||
CountAttackRequests any // 攻击请求数
|
||||
CountWebsocketConnections any // Websocket连接数
|
||||
}
|
||||
|
||||
func NewUserPlanBandwidthStatOperator() *UserPlanBandwidthStatOperator {
|
||||
|
||||
@@ -5,6 +5,6 @@ package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
func (this *UserPlanStatDAO) IncreaseUserPlanStat(tx *dbs.Tx, userPlanId int64, trafficBytes int64, countRequests int64) error {
|
||||
func (this *UserPlanStatDAO) IncreaseUserPlanStat(tx *dbs.Tx, userPlanId int64, trafficBytes int64, countRequests int64, countWebsocketConnections int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,34 +3,37 @@ package models
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
UserPlanStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanStatField_Date dbs.FieldName = "date" // 日期:YYYYMMDD或YYYYMM
|
||||
UserPlanStatField_DateType dbs.FieldName = "dateType" // 日期类型:day|month
|
||||
UserPlanStatField_TrafficBytes dbs.FieldName = "trafficBytes" // 流量
|
||||
UserPlanStatField_CountRequests dbs.FieldName = "countRequests" // 总请求数
|
||||
UserPlanStatField_IsProcessed dbs.FieldName = "isProcessed" // 是否已处理
|
||||
UserPlanStatField_Id dbs.FieldName = "id" // ID
|
||||
UserPlanStatField_UserPlanId dbs.FieldName = "userPlanId" // 用户套餐ID
|
||||
UserPlanStatField_Date dbs.FieldName = "date" // 日期:YYYYMMDD或YYYYMM
|
||||
UserPlanStatField_DateType dbs.FieldName = "dateType" // 日期类型:day|month
|
||||
UserPlanStatField_TrafficBytes dbs.FieldName = "trafficBytes" // 流量
|
||||
UserPlanStatField_CountRequests dbs.FieldName = "countRequests" // 总请求数
|
||||
UserPlanStatField_CountWebsocketConnections dbs.FieldName = "countWebsocketConnections" // Websocket连接数
|
||||
UserPlanStatField_IsProcessed dbs.FieldName = "isProcessed" // 是否已处理
|
||||
)
|
||||
|
||||
// UserPlanStat 用户套餐统计
|
||||
type UserPlanStat struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Date string `field:"date"` // 日期:YYYYMMDD或YYYYMM
|
||||
DateType string `field:"dateType"` // 日期类型:day|month
|
||||
TrafficBytes uint64 `field:"trafficBytes"` // 流量
|
||||
CountRequests uint64 `field:"countRequests"` // 总请求数
|
||||
IsProcessed bool `field:"isProcessed"` // 是否已处理
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserPlanId uint64 `field:"userPlanId"` // 用户套餐ID
|
||||
Date string `field:"date"` // 日期:YYYYMMDD或YYYYMM
|
||||
DateType string `field:"dateType"` // 日期类型:day|month
|
||||
TrafficBytes uint64 `field:"trafficBytes"` // 流量
|
||||
CountRequests uint64 `field:"countRequests"` // 总请求数
|
||||
CountWebsocketConnections uint64 `field:"countWebsocketConnections"` // Websocket连接数
|
||||
IsProcessed bool `field:"isProcessed"` // 是否已处理
|
||||
}
|
||||
|
||||
type UserPlanStatOperator struct {
|
||||
Id any // ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Date any // 日期:YYYYMMDD或YYYYMM
|
||||
DateType any // 日期类型:day|month
|
||||
TrafficBytes any // 流量
|
||||
CountRequests any // 总请求数
|
||||
IsProcessed any // 是否已处理
|
||||
Id any // ID
|
||||
UserPlanId any // 用户套餐ID
|
||||
Date any // 日期:YYYYMMDD或YYYYMM
|
||||
DateType any // 日期类型:day|month
|
||||
TrafficBytes any // 流量
|
||||
CountRequests any // 总请求数
|
||||
CountWebsocketConnections any // Websocket连接数
|
||||
IsProcessed any // 是否已处理
|
||||
}
|
||||
|
||||
func NewUserPlanStatOperator() *UserPlanStatOperator {
|
||||
|
||||
33
internal/db/models/user_script_dao.go
Normal file
33
internal/db/models/user_script_dao.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
UserScriptStateEnabled = 1 // 已启用
|
||||
UserScriptStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type UserScriptDAO dbs.DAO
|
||||
|
||||
func NewUserScriptDAO() *UserScriptDAO {
|
||||
return dbs.NewDAO(&UserScriptDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeUserScripts",
|
||||
Model: new(UserScript),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*UserScriptDAO)
|
||||
}
|
||||
|
||||
var SharedUserScriptDAO *UserScriptDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedUserScriptDAO = NewUserScriptDAO()
|
||||
})
|
||||
}
|
||||
6
internal/db/models/user_script_dao_test.go
Normal file
6
internal/db/models/user_script_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
56
internal/db/models/user_script_model.go
Normal file
56
internal/db/models/user_script_model.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
const (
|
||||
UserScriptField_Id dbs.FieldName = "id" // ID
|
||||
UserScriptField_UserId dbs.FieldName = "userId" // 用户ID
|
||||
UserScriptField_AdminId dbs.FieldName = "adminId" // 操作管理员
|
||||
UserScriptField_Code dbs.FieldName = "code" // 代码
|
||||
UserScriptField_CodeMD5 dbs.FieldName = "codeMD5" // 代码MD5
|
||||
UserScriptField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||
UserScriptField_IsRejected dbs.FieldName = "isRejected" // 是否已驳回
|
||||
UserScriptField_RejectedAt dbs.FieldName = "rejectedAt" // 驳回时间
|
||||
UserScriptField_RejectedReason dbs.FieldName = "rejectedReason" // 驳回原因
|
||||
UserScriptField_IsPassed dbs.FieldName = "isPassed" // 是否通过审核
|
||||
UserScriptField_PassedAt dbs.FieldName = "passedAt" // 通过时间
|
||||
UserScriptField_State dbs.FieldName = "state" // 状态
|
||||
UserScriptField_WebIds dbs.FieldName = "webIds" // WebId列表
|
||||
)
|
||||
|
||||
// UserScript 用户脚本审核
|
||||
type UserScript struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
AdminId uint64 `field:"adminId"` // 操作管理员
|
||||
Code string `field:"code"` // 代码
|
||||
CodeMD5 string `field:"codeMD5"` // 代码MD5
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
IsRejected bool `field:"isRejected"` // 是否已驳回
|
||||
RejectedAt uint64 `field:"rejectedAt"` // 驳回时间
|
||||
RejectedReason string `field:"rejectedReason"` // 驳回原因
|
||||
IsPassed bool `field:"isPassed"` // 是否通过审核
|
||||
PassedAt uint64 `field:"passedAt"` // 通过时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
WebIds dbs.JSON `field:"webIds"` // WebId列表
|
||||
}
|
||||
|
||||
type UserScriptOperator struct {
|
||||
Id any // ID
|
||||
UserId any // 用户ID
|
||||
AdminId any // 操作管理员
|
||||
Code any // 代码
|
||||
CodeMD5 any // 代码MD5
|
||||
CreatedAt any // 创建时间
|
||||
IsRejected any // 是否已驳回
|
||||
RejectedAt any // 驳回时间
|
||||
RejectedReason any // 驳回原因
|
||||
IsPassed any // 是否通过审核
|
||||
PassedAt any // 通过时间
|
||||
State any // 状态
|
||||
WebIds any // WebId列表
|
||||
}
|
||||
|
||||
func NewUserScriptOperator() *UserScriptOperator {
|
||||
return &UserScriptOperator{}
|
||||
}
|
||||
1
internal/db/models/user_script_model_ext.go
Normal file
1
internal/db/models/user_script_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -128,7 +128,7 @@ func (this *AliDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route,
|
||||
}
|
||||
for _, line := range resp.RecordLines.RecordLine {
|
||||
routes = append(routes, &dnstypes.Route{
|
||||
Name: line.LineName,
|
||||
Name: line.LineDisplayName,
|
||||
Code: line.LineCode,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -177,13 +177,12 @@ func (this *HuaweiDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Rout
|
||||
|
||||
{
|
||||
Code: "Pengboshi",
|
||||
|
||||
Name: "鹏博士",
|
||||
},
|
||||
|
||||
{
|
||||
Code: "CN",
|
||||
Name: "中国",
|
||||
Name: "中国大陆",
|
||||
},
|
||||
|
||||
{
|
||||
@@ -192,6 +191,944 @@ func (this *HuaweiDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Rout
|
||||
},
|
||||
}...)
|
||||
|
||||
// 运营商线路细分
|
||||
routes = append(routes, []*dnstypes.Route{
|
||||
{
|
||||
Code: "Dianxin_Huabei",
|
||||
Name: "电信_华北地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Dongbei",
|
||||
Name: "电信_东北地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Huadong",
|
||||
Name: "电信_华东地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Huazhong",
|
||||
Name: "电信_华中地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Huanan",
|
||||
Name: "电信_华南地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Xinan",
|
||||
Name: "电信_西南地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Xibei",
|
||||
Name: "电信_西北地区",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Beijing",
|
||||
Name: "电信_北京",
|
||||
},
|
||||
|
||||
{
|
||||
Code: "Dianxin_Hebei",
|
||||
Name: "电信_河北",
|
||||
},
|
||||
{
|
||||
|
||||
Code: "Dianxin_Tianjin",
|
||||
Name: "电信_天津",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shanxi",
|
||||
Name: "电信_山西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Neimenggu",
|
||||
Name: "电信_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Heilongjiang",
|
||||
Name: "电信_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Jilin",
|
||||
Name: "电信_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Liaoning",
|
||||
Name: "电信_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Jiangsu",
|
||||
Name: "电信_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shanghai",
|
||||
Name: "电信_上海",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Zhejiang",
|
||||
Name: "电信_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Anhui",
|
||||
Name: "电信_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Fujian",
|
||||
Name: "电信_福建",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Jiangxi",
|
||||
Name: "电信_江西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shandong",
|
||||
Name: "电信_山东",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Hubei",
|
||||
Name: "电信_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Hunan",
|
||||
Name: "电信_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Henan",
|
||||
Name: "电信_河南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Guangdong",
|
||||
Name: "电信_广东",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Guangxi",
|
||||
Name: "电信_广西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Hainan",
|
||||
Name: "电信_海南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Sichuan",
|
||||
Name: "电信_四川",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Xizang",
|
||||
Name: "电信_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Chongqing",
|
||||
Name: "电信_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Yunnan",
|
||||
Name: "电信_云南",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Guizhou",
|
||||
Name: "电信_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Gansu",
|
||||
Name: "电信_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Xinjiang",
|
||||
Name: "电信_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Shaanxi",
|
||||
Name: "电信_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Qinghai",
|
||||
Name: "电信_青海",
|
||||
},
|
||||
{
|
||||
Code: "Dianxin_Ningxia",
|
||||
Name: "电信_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huabei",
|
||||
Name: "移动_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Dongbei",
|
||||
Name: "移动_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huadong",
|
||||
Name: "移动_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huazhong",
|
||||
Name: "移动_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Huanan",
|
||||
Name: "移动_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xinan",
|
||||
Name: "移动_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xibei",
|
||||
Name: "移动_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Beijing",
|
||||
Name: "移动_北京",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hebei",
|
||||
Name: "移动_河北",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Tianjin",
|
||||
Name: "移动_天津",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shanxi",
|
||||
Name: "移动_山西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Neimenggu",
|
||||
Name: "移动_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Heilongjiang",
|
||||
Name: "移动_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Jilin",
|
||||
Name: "移动_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Liaoning",
|
||||
Name: "移动_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Jiangsu",
|
||||
Name: "移动_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shanghai",
|
||||
Name: "移动_上海",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Zhejiang",
|
||||
Name: "移动_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Anhui",
|
||||
Name: "移动_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Fujian",
|
||||
Name: "移动_福建",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Jiangxi",
|
||||
Name: "移动_江西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shandong",
|
||||
Name: "移动_山东",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hubei",
|
||||
Name: "移动_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hunan",
|
||||
Name: "移动_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Henan",
|
||||
Name: "移动_河南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Guangdong",
|
||||
Name: "移动_广东",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Guangxi",
|
||||
Name: "移动_广西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Hainan",
|
||||
Name: "移动_海南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Sichuan",
|
||||
Name: "移动_四川",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xizang",
|
||||
Name: "移动_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Chongqing",
|
||||
Name: "移动_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Yunnan",
|
||||
Name: "移动_云南",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Guizhou",
|
||||
Name: "移动_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Gansu",
|
||||
Name: "移动_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Xinjiang",
|
||||
Name: "移动_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Shaanxi",
|
||||
Name: "移动_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Qinghai",
|
||||
Name: "移动_青海",
|
||||
},
|
||||
{
|
||||
Code: "Yidong_Ningxia",
|
||||
Name: "移动_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huabei",
|
||||
Name: "联通_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Dongbei",
|
||||
Name: "联通_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huadong",
|
||||
Name: "联通_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huazhong",
|
||||
Name: "联通_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Huanan",
|
||||
Name: "联通_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xinan",
|
||||
Name: "联通_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xibei",
|
||||
Name: "联通_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Beijing",
|
||||
Name: "联通_北京",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hebei",
|
||||
Name: "联通_河北",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Tianjin",
|
||||
Name: "联通_天津",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shanxi",
|
||||
Name: "联通_山西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Neimenggu",
|
||||
Name: "联通_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Heilongjiang",
|
||||
Name: "联通_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Jilin",
|
||||
Name: "联通_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Liaoning",
|
||||
Name: "联通_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Jiangsu",
|
||||
Name: "联通_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shanghai",
|
||||
Name: "联通_上海",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Zhejiang",
|
||||
Name: "联通_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Anhui",
|
||||
Name: "联通_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Fujian",
|
||||
Name: "联通_福建",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Jiangxi",
|
||||
Name: "联通_江西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shandong",
|
||||
Name: "联通_山东",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hubei",
|
||||
Name: "联通_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hunan",
|
||||
Name: "联通_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Henan",
|
||||
Name: "联通_河南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Guangdong",
|
||||
Name: "联通_广东",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Guangxi",
|
||||
Name: "联通_广西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Hainan",
|
||||
Name: "联通_海南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Sichuan",
|
||||
Name: "联通_四川",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xizang",
|
||||
Name: "联通_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Chongqing",
|
||||
Name: "联通_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Yunnan",
|
||||
Name: "联通_云南",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Guizhou",
|
||||
Name: "联通_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Gansu",
|
||||
Name: "联通_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Xinjiang",
|
||||
Name: "联通_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Shaanxi",
|
||||
Name: "联通_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Qinghai",
|
||||
Name: "联通_青海",
|
||||
},
|
||||
{
|
||||
Code: "Liantong_Ningxia",
|
||||
Name: "联通_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang",
|
||||
Name: "教育网默认",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huabei",
|
||||
Name: "教育网_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Dongbei",
|
||||
Name: "教育网_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huadong",
|
||||
Name: "教育网_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huazhong",
|
||||
Name: "教育网_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Huanan",
|
||||
Name: "教育网_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xinan",
|
||||
Name: "教育网_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xibei",
|
||||
Name: "教育网_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Beijing",
|
||||
Name: "教育网_北京",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hebei",
|
||||
Name: "教育网_河北",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Tianjin",
|
||||
Name: "教育网_天津",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shanxi",
|
||||
Name: "教育网_山西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Neimenggu",
|
||||
Name: "教育网_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Heilongjiang",
|
||||
Name: "教育网_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Jilin",
|
||||
Name: "教育网_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Liaoning",
|
||||
Name: "教育网_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Jiangsu",
|
||||
Name: "教育网_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shanghai",
|
||||
Name: "教育网_上海",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Zhejiang",
|
||||
Name: "教育网_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Anhui",
|
||||
Name: "教育网_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Fujian",
|
||||
Name: "教育网_福建",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Jiangxi",
|
||||
Name: "教育网_江西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shandong",
|
||||
Name: "教育网_山东",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hubei",
|
||||
Name: "教育网_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hunan",
|
||||
Name: "教育网_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Henan",
|
||||
Name: "教育网_河南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Guangdong",
|
||||
Name: "教育网_广东",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Guangxi",
|
||||
Name: "教育网_广西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Hainan",
|
||||
Name: "教育网_海南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Sichuan",
|
||||
Name: "教育网_四川",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xizang",
|
||||
Name: "教育网_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Chongqing",
|
||||
Name: "教育网_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Yunnan",
|
||||
Name: "教育网_云南",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Guizhou",
|
||||
Name: "教育网_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Gansu",
|
||||
Name: "教育网_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Xinjiang",
|
||||
Name: "教育网_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Shaanxi",
|
||||
Name: "教育网_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Qinghai",
|
||||
Name: "教育网_青海",
|
||||
},
|
||||
{
|
||||
Code: "Jiaoyuwang_Ningxia",
|
||||
Name: "教育网_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi",
|
||||
Name: "鹏博士默认",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huabei",
|
||||
Name: "鹏博士_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Dongbei",
|
||||
Name: "鹏博士_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huadong",
|
||||
Name: "鹏博士_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huazhong",
|
||||
Name: "鹏博士_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Huanan",
|
||||
Name: "鹏博士_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xinan",
|
||||
Name: "鹏博士_西南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xibei",
|
||||
Name: "鹏博士_西北",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Beijing",
|
||||
Name: "鹏博士_北京",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hebei",
|
||||
Name: "鹏博士_河北",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Tianjin",
|
||||
Name: "鹏博士_天津",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shanxi",
|
||||
Name: "鹏博士_山西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Neimenggu",
|
||||
Name: "鹏博士_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Heilongjiang",
|
||||
Name: "鹏博士_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Jilin",
|
||||
Name: "鹏博士_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Liaoning",
|
||||
Name: "鹏博士_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Jiangsu",
|
||||
Name: "鹏博士_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shanghai",
|
||||
Name: "鹏博士_上海",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Zhejiang",
|
||||
Name: "鹏博士_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Anhui",
|
||||
Name: "鹏博士_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Fujian",
|
||||
Name: "鹏博士_福建",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Jiangxi",
|
||||
Name: "鹏博士_江西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shandong",
|
||||
Name: "鹏博士_山东",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hubei",
|
||||
Name: "鹏博士_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hunan",
|
||||
Name: "鹏博士_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Henan",
|
||||
Name: "鹏博士_河南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Guangdong",
|
||||
Name: "鹏博士_广东",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Guangxi",
|
||||
Name: "鹏博士_广西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Hainan",
|
||||
Name: "鹏博士_海南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Sichuan",
|
||||
Name: "鹏博士_四川",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xizang",
|
||||
Name: "鹏博士_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Chongqing",
|
||||
Name: "鹏博士_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Yunnan",
|
||||
Name: "鹏博士_云南",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Guizhou",
|
||||
Name: "鹏博士_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Gansu",
|
||||
Name: "鹏博士_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Xinjiang",
|
||||
Name: "鹏博士_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Shaanxi",
|
||||
Name: "鹏博士_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Qinghai",
|
||||
Name: "鹏博士_青海",
|
||||
},
|
||||
{
|
||||
Code: "Pengboshi_Ningxia",
|
||||
Name: "鹏博士_宁夏",
|
||||
},
|
||||
{
|
||||
Code: "Tietong",
|
||||
Name: "铁通默认",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huabei",
|
||||
Name: "铁通_华北地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Dongbei",
|
||||
Name: "铁通_东北地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huadong",
|
||||
Name: "铁通_华东地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huazhong",
|
||||
Name: "铁通_华中地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Huanan",
|
||||
Name: "铁通_华南地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xinan",
|
||||
Name: "铁通_西南地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xibei",
|
||||
Name: "铁通_西北地区",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Beijing",
|
||||
Name: "铁通_北京",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hebei",
|
||||
Name: "铁通_河北",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Tianjin",
|
||||
Name: "铁通_天津",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shanxi",
|
||||
Name: "铁通_山西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Neimenggu",
|
||||
Name: "铁通_内蒙古",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Heilongjiang",
|
||||
Name: "铁通_黑龙江",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Jilin",
|
||||
Name: "铁通_吉林",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Liaoning",
|
||||
Name: "铁通_辽宁",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Jiangsu",
|
||||
Name: "铁通_江苏",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shanghai",
|
||||
Name: "铁通_上海",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Zhejiang",
|
||||
Name: "铁通_浙江",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Anhui",
|
||||
Name: "铁通_安徽",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Fujian",
|
||||
Name: "铁通_福建",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Jiangxi",
|
||||
Name: "铁通_江西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shandong",
|
||||
Name: "铁通_山东",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hubei",
|
||||
Name: "铁通_湖北",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hunan",
|
||||
Name: "铁通_湖南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Henan",
|
||||
Name: "铁通_河南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Guangdong",
|
||||
Name: "铁通_广东",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Guangxi",
|
||||
Name: "铁通_广西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Hainan",
|
||||
Name: "铁通_海南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Sichuan",
|
||||
Name: "铁通_四川",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xizang",
|
||||
Name: "铁通_西藏",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Chongqing",
|
||||
Name: "铁通_重庆",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Yunnan",
|
||||
Name: "铁通_云南",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Guizhou",
|
||||
Name: "铁通_贵州",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Gansu",
|
||||
Name: "铁通_甘肃",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Xinjiang",
|
||||
Name: "铁通_新疆",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Shaanxi",
|
||||
Name: "铁通_陕西",
|
||||
},
|
||||
{
|
||||
Code: "Tietong_Qinghai",
|
||||
Name: "铁通_青海",
|
||||
},
|
||||
|
||||
{
|
||||
Code: "Tietong_Ningxia",
|
||||
Name: "铁通_宁夏",
|
||||
},
|
||||
}...)
|
||||
|
||||
// 地域线路细分(全球)
|
||||
routes = append(routes, []*dnstypes.Route{
|
||||
{
|
||||
|
||||
@@ -740,3 +740,18 @@ func (this *AdminService) UpdateAdminTheme(ctx context.Context, req *pb.UpdateAd
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateAdminLang 修改管理员使用的语言
|
||||
func (this *AdminService) UpdateAdminLang(ctx context.Context, req *pb.UpdateAdminLangRequest) (*pb.RPCSuccess, error) {
|
||||
adminId, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
|
||||
err = models.SharedAdminDAO.UpdateAdminLang(tx, adminId, req.LangCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (this *HTTPFirewallPolicyService) FindAllEnabledHTTPFirewallPolicies(ctx co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.HTTPFirewallPolicy{}
|
||||
var result = []*pb.HTTPFirewallPolicy{}
|
||||
for _, p := range policies {
|
||||
result = append(result, &pb.HTTPFirewallPolicy{
|
||||
Id: int64(p.Id),
|
||||
@@ -395,7 +395,7 @@ func (this *HTTPFirewallPolicyService) ListEnabledHTTPFirewallPolicies(ctx conte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.HTTPFirewallPolicy{}
|
||||
var result = []*pb.HTTPFirewallPolicy{}
|
||||
for _, p := range policies {
|
||||
result = append(result, &pb.HTTPFirewallPolicy{
|
||||
Id: int64(p.Id),
|
||||
@@ -488,17 +488,21 @@ func (this *HTTPFirewallPolicyService) FindEnabledHTTPFirewallPolicy(ctx context
|
||||
if policy == nil {
|
||||
return &pb.FindEnabledHTTPFirewallPolicyResponse{HttpFirewallPolicy: nil}, nil
|
||||
}
|
||||
return &pb.FindEnabledHTTPFirewallPolicyResponse{HttpFirewallPolicy: &pb.HTTPFirewallPolicy{
|
||||
Id: int64(policy.Id),
|
||||
ServerId: int64(policy.ServerId),
|
||||
Name: policy.Name,
|
||||
Description: policy.Description,
|
||||
IsOn: policy.IsOn,
|
||||
InboundJSON: policy.Inbound,
|
||||
OutboundJSON: policy.Outbound,
|
||||
Mode: policy.Mode,
|
||||
SynFloodJSON: policy.SynFlood,
|
||||
}}, nil
|
||||
return &pb.FindEnabledHTTPFirewallPolicyResponse{
|
||||
HttpFirewallPolicy: &pb.HTTPFirewallPolicy{
|
||||
Id: int64(policy.Id),
|
||||
ServerId: int64(policy.ServerId),
|
||||
Name: policy.Name,
|
||||
Description: policy.Description,
|
||||
IsOn: policy.IsOn,
|
||||
InboundJSON: policy.Inbound,
|
||||
OutboundJSON: policy.Outbound,
|
||||
Mode: policy.Mode,
|
||||
SynFloodJSON: policy.SynFlood,
|
||||
BlockOptionsJSON: policy.BlockOptions,
|
||||
CaptchaOptionsJSON: policy.CaptchaOptions,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ImportHTTPFirewallPolicy 导入策略数据
|
||||
@@ -858,3 +862,29 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
||||
RegionProvince: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithHTTPFirewallPolicyId 获取防火墙对应的网站ID
|
||||
func (this *HTTPFirewallPolicyService) FindServerIdWithHTTPFirewallPolicyId(ctx context.Context, req *pb.FindServerIdWithHTTPFirewallPolicyIdRequest) (*pb.FindServerIdWithHTTPFirewallPolicyIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
serverId, err := models.SharedHTTPFirewallPolicyDAO.FindServerIdWithFirewallPolicyId(tx, req.HttpFirewallPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check user
|
||||
if serverId > 0 && userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithHTTPFirewallPolicyIdResponse{
|
||||
ServerId: serverId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -3,12 +3,16 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/domainutils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HTTPWebService struct {
|
||||
@@ -532,6 +536,49 @@ func (this *HTTPWebService) UpdateHTTPWebCache(ctx context.Context, req *pb.Upda
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
var cacheConfig = &serverconfigs.HTTPCacheConfig{}
|
||||
if len(req.CacheJSON) > 0 {
|
||||
err = json.Unmarshal(req.CacheJSON, cacheConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = cacheConfig.Init()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("validate cache config failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// validate host
|
||||
if cacheConfig.Key != nil && cacheConfig.Key.IsOn {
|
||||
if cacheConfig.Key.Scheme != "http" && cacheConfig.Key.Scheme != "https" {
|
||||
return nil, errors.New("key scheme must be 'http' or 'https'")
|
||||
}
|
||||
|
||||
cacheConfig.Key.Host = strings.ToLower(cacheConfig.Key.Host)
|
||||
if !domainutils.ValidateDomainFormat(cacheConfig.Key.Host) {
|
||||
return nil, errors.New("key host must be a valid domain")
|
||||
}
|
||||
|
||||
serverId, err := models.SharedHTTPWebDAO.FindWebServerId(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if serverId > 0 {
|
||||
serverNamesJSON, _, _, _, _, err := models.SharedServerDAO.FindServerServerNames(tx, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||
err = json.Unmarshal(serverNamesJSON, &serverNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !lists.ContainsString(serverconfigs.PlainServerNames(serverNames), cacheConfig.Key.Host) {
|
||||
return nil, errors.New("key host '" + cacheConfig.Key.Host + "' not exists in server names")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPWebDAO.UpdateWebCache(tx, req.HttpWebId, req.CacheJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -851,28 +898,6 @@ func (this *HTTPWebService) FindHTTPWebRequestLimit(ctx context.Context, req *pb
|
||||
return &pb.FindHTTPWebRequestLimitResponse{RequestLimitJSON: configJSON}, nil
|
||||
}
|
||||
|
||||
// UpdateHTTPWebRequestScripts 修改请求脚本
|
||||
func (this *HTTPWebService) UpdateHTTPWebRequestScripts(ctx context.Context, req *pb.UpdateHTTPWebRequestScriptsRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var config = &serverconfigs.HTTPRequestScriptsConfig{}
|
||||
err = json.Unmarshal(req.RequestScriptsJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedHTTPWebDAO.UpdateWebRequestScripts(tx, req.HttpWebId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindHTTPWebRequestScripts 查找请求脚本
|
||||
func (this *HTTPWebService) FindHTTPWebRequestScripts(ctx context.Context, req *pb.FindHTTPWebRequestScriptsRequest) (*pb.FindHTTPWebRequestScriptsResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
@@ -1029,3 +1054,30 @@ func (this *HTTPWebService) FindHTTPWebUserAgent(ctx context.Context, req *pb.Fi
|
||||
UserAgentJSON: configJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithHTTPWebId 根据WebId查找ServerId
|
||||
func (this *HTTPWebService) FindServerIdWithHTTPWebId(ctx context.Context, req *pb.FindServerIdWithHTTPWebIdRequest) (*pb.FindServerIdWithHTTPWebIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.HttpWebId <= 0 {
|
||||
return nil, errors.New("invalid 'httpWebId'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
serverId, err := models.SharedHTTPWebDAO.FindWebServerId(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if serverId > 0 && userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithHTTPWebIdResponse{ServerId: serverId}, nil
|
||||
}
|
||||
|
||||
@@ -27,3 +27,8 @@ func (this *HTTPWebService) UpdateHTTPWebCC(ctx context.Context, req *pb.UpdateH
|
||||
func (this *HTTPWebService) FindHTTPWebCC(ctx context.Context, req *pb.FindHTTPWebCCRequest) (*pb.FindHTTPWebCCResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateHTTPWebRequestScripts 修改请求脚本
|
||||
func (this *HTTPWebService) UpdateHTTPWebRequestScripts(ctx context.Context, req *pb.UpdateHTTPWebRequestScriptsRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
@@ -768,6 +768,29 @@ func (this *IPItemService) ListAllEnabledIPItems(ctx context.Context, req *pb.Li
|
||||
return &pb.ListAllEnabledIPItemsResponse{Results: results}, nil
|
||||
}
|
||||
|
||||
// ListAllIPItemIds 列出所有名单中的IP ID
|
||||
func (this *IPItemService) ListAllIPItemIds(ctx context.Context, req *pb.ListAllIPItemIdsRequest) (*pb.ListAllIPItemIdsResponse, error) {
|
||||
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if adminId > 0 {
|
||||
userId = req.UserId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var listId int64 = 0
|
||||
if req.GlobalOnly {
|
||||
listId = firewallconfigs.GlobalListId
|
||||
}
|
||||
itemIds, err := models.SharedIPItemDAO.ListAllIPItemIds(tx, userId, req.Keyword, req.Ip, listId, req.Unread, req.EventLevel, req.ListType, req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.ListAllIPItemIdsResponse{IpItemIds: itemIds}, nil
|
||||
}
|
||||
|
||||
// UpdateIPItemsRead 设置所有为已读
|
||||
func (this *IPItemService) UpdateIPItemsRead(ctx context.Context, req *pb.UpdateIPItemsReadRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
@@ -782,3 +805,38 @@ func (this *IPItemService) UpdateIPItemsRead(ctx context.Context, req *pb.Update
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindServerIdWithIPItemId 查找IP对应的名单所属网站ID
|
||||
func (this *IPItemService) FindServerIdWithIPItemId(ctx context.Context, req *pb.FindServerIdWithIPItemIdRequest) (*pb.FindServerIdWithIPItemIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
listId, err := models.SharedIPItemDAO.FindItemListId(tx, req.IpItemId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if listId > 0 {
|
||||
var serverId int64
|
||||
serverId, err = models.SharedIPListDAO.FindServerIdWithListId(tx, listId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if serverId > 0 {
|
||||
// check user
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &pb.FindServerIdWithIPItemIdResponse{ServerId: serverId}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithIPItemIdResponse{ServerId: 0}, nil
|
||||
}
|
||||
|
||||
@@ -224,3 +224,29 @@ func (this *IPListService) FindEnabledIPListContainsIP(ctx context.Context, req
|
||||
}
|
||||
return &pb.FindEnabledIPListContainsIPResponse{IpLists: pbLists}, nil
|
||||
}
|
||||
|
||||
// FindServerIdWithIPListId 查找IP名单对应的网站ID
|
||||
func (this *IPListService) FindServerIdWithIPListId(ctx context.Context, req *pb.FindServerIdWithIPListIdRequest) (*pb.FindServerIdWithIPListIdResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
serverId, err := models.SharedIPListDAO.FindServerIdWithListId(tx, req.IpListId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check user
|
||||
if serverId > 0 && userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.FindServerIdWithIPListIdResponse{
|
||||
ServerId: serverId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -2257,3 +2257,39 @@ func (this *NodeService) UpdateNodeAPIConfig(ctx context.Context, req *pb.Update
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindNodeWebPPolicies 查找节点的WebP策略
|
||||
func (this *NodeService) FindNodeWebPPolicies(ctx context.Context, req *pb.FindNodeWebPPoliciesRequest) (*pb.FindNodeWebPPoliciesResponse, error) {
|
||||
nodeId, err := this.ValidateNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
clusterIds, err := models.SharedNodeDAO.FindEnabledAndOnNodeClusterIds(tx, nodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbPolicies = []*pb.FindNodeWebPPoliciesResponse_WebPPolicy{}
|
||||
for _, clusterId := range clusterIds {
|
||||
policy, err := models.SharedNodeClusterDAO.FindClusterWebPPolicy(tx, clusterId, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if policy == nil {
|
||||
continue
|
||||
}
|
||||
policyJSON, err := json.Marshal(policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbPolicies = append(pbPolicies, &pb.FindNodeWebPPoliciesResponse_WebPPolicy{
|
||||
NodeClusterId: clusterId,
|
||||
WebPPolicyJSON: policyJSON,
|
||||
})
|
||||
}
|
||||
return &pb.FindNodeWebPPoliciesResponse{
|
||||
WebPPolicies: pbPolicies,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1126,14 +1126,14 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
|
||||
|
||||
// webp
|
||||
if models.IsNotNull(cluster.Webp) {
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
var webpPolicy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(cluster.Webp, webpPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.WebpIsOn = webpPolicy.IsOn
|
||||
result.WebPIsOn = webpPolicy.IsOn
|
||||
} else {
|
||||
result.WebpIsOn = nodeconfigs.DefaultWebPImagePolicy.IsOn
|
||||
result.WebPIsOn = nodeconfigs.DefaultWebPImagePolicy.IsOn
|
||||
}
|
||||
|
||||
// UAM
|
||||
@@ -1247,8 +1247,8 @@ func (this *NodeClusterService) UpdateNodeClusterWebPPolicy(ctx context.Context,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
err = json.Unmarshal(req.WebpPolicyJSON, webpPolicy)
|
||||
var webpPolicy = nodeconfigs.NewWebPImagePolicy()
|
||||
err = json.Unmarshal(req.WebPPolicyJSON, webpPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -48,3 +48,8 @@ func (this *PlanService) ListEnabledPlans(ctx context.Context, req *pb.ListEnabl
|
||||
func (this *PlanService) SortPlans(ctx context.Context, req *pb.SortPlansRequest) (*pb.RPCSuccess, error) {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindAllAvailablePlans 列出所有可用的套餐
|
||||
func (this *PlanService) FindAllAvailablePlans(ctx context.Context, req *pb.FindAllAvailablePlansRequest) (*pb.FindAllAvailablePlansResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
@@ -2414,7 +2414,7 @@ func (this *ServerService) UploadServerHTTPRequestStat(ctx context.Context, req
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// CheckServerNameDuplicationInNodeCluster 检查域名是否已经存在
|
||||
// CheckServerNameDuplicationInNodeCluster 检查域名是否在集群中已经存在
|
||||
func (this *ServerService) CheckServerNameDuplicationInNodeCluster(ctx context.Context, req *pb.CheckServerNameDuplicationInNodeClusterRequest) (*pb.CheckServerNameDuplicationInNodeClusterResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
@@ -2441,6 +2441,47 @@ func (this *ServerService) CheckServerNameDuplicationInNodeCluster(ctx context.C
|
||||
return &pb.CheckServerNameDuplicationInNodeClusterResponse{DuplicatedServerNames: duplicatedServerNames}, nil
|
||||
}
|
||||
|
||||
// CheckServerNameInServer 检查域名是否在网站中已经绑定
|
||||
func (this *ServerService) CheckServerNameInServer(ctx context.Context, req *pb.CheckServerNameInServerRequest) (*pb.CheckServerNameInServerResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.ServerId <= 0 {
|
||||
return nil, errors.New("invalid serverId '" + types.String(req.ServerId) + "'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(req.ServerName) == 0 {
|
||||
return &pb.CheckServerNameInServerResponse{
|
||||
Exists: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
serverNamesJSON, _, _, _, _, err := models.SharedServerDAO.FindServerServerNames(tx, req.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||
err = json.Unmarshal(serverNamesJSON, &serverNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CheckServerNameInServerResponse{
|
||||
Exists: lists.ContainsString(serverconfigs.PlainServerNames(serverNames), req.ServerName),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindLatestServers 查找最近访问的服务
|
||||
func (this *ServerService) FindLatestServers(ctx context.Context, req *pb.FindLatestServersRequest) (*pb.FindLatestServersResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
@@ -2849,6 +2890,7 @@ func (this *ServerService) FindServerUserPlan(ctx context.Context, req *pb.FindS
|
||||
User: nil,
|
||||
Plan: &pb.Plan{
|
||||
Id: int64(plan.Id),
|
||||
IsOn: plan.IsOn,
|
||||
Name: plan.Name,
|
||||
PriceType: plan.PriceType,
|
||||
TrafficPriceJSON: plan.TrafficPrice,
|
||||
@@ -2856,6 +2898,8 @@ func (this *ServerService) FindServerUserPlan(ctx context.Context, req *pb.FindS
|
||||
TotalServers: types.Int32(plan.TotalServers),
|
||||
TotalServerNames: types.Int32(plan.TotalServerNames),
|
||||
TotalServerNamesPerServer: types.Int32(plan.TotalServerNamesPerServer),
|
||||
HasFullFeatures: plan.HasFullFeatures,
|
||||
FeaturesJSON: plan.Features,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
|
||||
@@ -80,13 +80,13 @@ func init() {
|
||||
// 套餐统计
|
||||
if stat.UserPlanId > 0 {
|
||||
// 总体统计
|
||||
err = models.SharedUserPlanStatDAO.IncreaseUserPlanStat(tx, stat.UserPlanId, stat.TotalBytes, stat.CountRequests)
|
||||
err = models.SharedUserPlanStatDAO.IncreaseUserPlanStat(tx, stat.UserPlanId, stat.TotalBytes, stat.CountRequests, stat.CountWebsocketConnections)
|
||||
if err != nil {
|
||||
remotelogs.Error("ServerBandwidthStatService", "IncreaseUserPlanStat: "+err.Error())
|
||||
}
|
||||
|
||||
// 分时统计
|
||||
err = models.SharedUserPlanBandwidthStatDAO.UpdateUserPlanBandwidth(tx, stat.UserId, stat.UserPlanId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
|
||||
err = models.SharedUserPlanBandwidthStatDAO.UpdateUserPlanBandwidth(tx, stat.UserId, stat.UserPlanId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests, stat.CountWebsocketConnections)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,22 +146,24 @@ func (this *ServerBandwidthStatService) UploadServerBandwidthStats(ctx context.C
|
||||
oldStat.CountRequests += stat.CountRequests
|
||||
oldStat.CountCachedRequests += stat.CountCachedRequests
|
||||
oldStat.CountAttackRequests += stat.CountAttackRequests
|
||||
oldStat.CountWebsocketConnections += stat.CountWebsocketConnections
|
||||
} else {
|
||||
serverBandwidthStatsMap[key] = &pb.ServerBandwidthStat{
|
||||
Id: 0,
|
||||
NodeRegionId: stat.NodeRegionId,
|
||||
UserId: stat.UserId,
|
||||
ServerId: stat.ServerId,
|
||||
Day: stat.Day,
|
||||
TimeAt: stat.TimeAt,
|
||||
Bytes: stat.Bytes,
|
||||
TotalBytes: stat.TotalBytes,
|
||||
CachedBytes: stat.CachedBytes,
|
||||
AttackBytes: stat.AttackBytes,
|
||||
CountRequests: stat.CountRequests,
|
||||
CountCachedRequests: stat.CountCachedRequests,
|
||||
CountAttackRequests: stat.CountAttackRequests,
|
||||
UserPlanId: stat.UserPlanId,
|
||||
Id: 0,
|
||||
NodeRegionId: stat.NodeRegionId,
|
||||
UserId: stat.UserId,
|
||||
ServerId: stat.ServerId,
|
||||
Day: stat.Day,
|
||||
TimeAt: stat.TimeAt,
|
||||
Bytes: stat.Bytes,
|
||||
TotalBytes: stat.TotalBytes,
|
||||
CachedBytes: stat.CachedBytes,
|
||||
AttackBytes: stat.AttackBytes,
|
||||
CountRequests: stat.CountRequests,
|
||||
CountCachedRequests: stat.CountCachedRequests,
|
||||
CountAttackRequests: stat.CountAttackRequests,
|
||||
CountWebsocketConnections: stat.CountWebsocketConnections,
|
||||
UserPlanId: stat.UserPlanId,
|
||||
}
|
||||
}
|
||||
serverBandwidthStatsLocker.Unlock()
|
||||
|
||||
@@ -618,31 +618,6 @@ func (this *UserService) UpdateAllUsersFeatures(ctx context.Context, req *pb.Upd
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindUserFeatures 获取用户所有的功能列表
|
||||
func (this *UserService) FindUserFeatures(ctx context.Context, req *pb.FindUserFeaturesRequest) (*pb.FindUserFeaturesResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
features, err := models.SharedUserDAO.FindUserFeatures(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.UserFeature{}
|
||||
for _, feature := range features {
|
||||
result = append(result, feature.ToPB())
|
||||
}
|
||||
|
||||
return &pb.FindUserFeaturesResponse{Features: result}, nil
|
||||
}
|
||||
|
||||
// FindAllUserFeatureDefinitions 获取所有的功能定义
|
||||
func (this *UserService) FindAllUserFeatureDefinitions(ctx context.Context, req *pb.FindAllUserFeatureDefinitionsRequest) (*pb.FindAllUserFeatureDefinitionsResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
@@ -650,8 +625,8 @@ func (this *UserService) FindAllUserFeatureDefinitions(ctx context.Context, req
|
||||
return nil, err
|
||||
}
|
||||
|
||||
features := userconfigs.FindAllUserFeatures()
|
||||
result := []*pb.UserFeature{}
|
||||
var features = userconfigs.FindAllUserFeatures()
|
||||
var result = []*pb.UserFeature{}
|
||||
for _, feature := range features {
|
||||
result = append(result, feature.ToPB())
|
||||
}
|
||||
|
||||
@@ -89,3 +89,28 @@ func (this *UserService) RegisterUser(ctx context.Context, req *pb.RegisterUserR
|
||||
RequireEmailVerification: requireEmailVerification,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindUserFeatures 获取用户所有的功能列表
|
||||
func (this *UserService) FindUserFeatures(ctx context.Context, req *pb.FindUserFeaturesRequest) (*pb.FindUserFeaturesResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userId > 0 {
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
features, err := models.SharedUserDAO.FindUserFeatures(tx, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.UserFeature{}
|
||||
for _, feature := range features {
|
||||
result = append(result, feature.ToPB())
|
||||
}
|
||||
|
||||
return &pb.FindUserFeaturesResponse{Features: result}, nil
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
@@ -259,7 +260,16 @@ func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.Exec("INSERT INTO edgeNodeClusters (name, useAllAPINodes, state, uniqueId, secret, dns) VALUES (?, ?, ?, ?, ?, ?)", "默认集群", 1, 1, uniqueId, secret, string(clusterDNSConfigJSON))
|
||||
var defaultDNSName = "g" + rands.HexString(6) + ".cdn"
|
||||
{
|
||||
var b = make([]byte, 3)
|
||||
_, err = rand.Read(b)
|
||||
if err == nil {
|
||||
defaultDNSName = fmt.Sprintf("g%x.cdn", b)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = db.Exec("INSERT INTO edgeNodeClusters (name, useAllAPINodes, state, uniqueId, secret, dns, dnsName) VALUES (?, ?, ?, ?, ?, ?, ?)", "默认集群", 1, 1, uniqueId, secret, string(clusterDNSConfigJSON), defaultDNSName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,12 +11,14 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -101,6 +103,9 @@ var upgradeFuncs = []*upgradeVersion{
|
||||
{
|
||||
"1.2.10", upgradeV1_2_10,
|
||||
},
|
||||
{
|
||||
"1.3.2", upgradeV1_3_2,
|
||||
},
|
||||
}
|
||||
|
||||
// UpgradeSQLData 升级SQL数据
|
||||
@@ -816,3 +821,412 @@ func upgradeV1_2_10(db *dbs.DB) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 1.3.2
|
||||
func upgradeV1_3_2(db *dbs.DB) error {
|
||||
// waf
|
||||
{
|
||||
var disableSet = func(setId int64) error {
|
||||
_, err := db.Exec("UPDATE edgeHTTPFirewallRuleSets SET state=0 WHERE id=?", setId)
|
||||
return err
|
||||
}
|
||||
|
||||
var addRuleToGroup = func(groupId int64, setCode string, setName string, actions []*firewallconfigs.HTTPFirewallActionConfig, ruleParam string, ruleOperator string, value string) error {
|
||||
actionsJSON, err := json.Marshal(actions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// rule
|
||||
ruleResult, err := db.Exec("INSERT INTO edgeHTTPFirewallRules (isOn, param, operator, value, isCaseInsensitive, state) VALUES (1, ?, ?, ?, 0, 1)", ruleParam, ruleOperator, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ruleId, err := ruleResult.LastInsertId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var ruleRefs = []*firewallconfigs.HTTPFirewallRuleRef{
|
||||
{
|
||||
IsOn: true,
|
||||
RuleId: ruleId,
|
||||
},
|
||||
}
|
||||
ruleRefsJSON, err := json.Marshal(ruleRefs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set
|
||||
setResult, err := db.Exec("INSERT INTO edgeHTTPFirewallRuleSets (isOn, code, name, rules, connector, state, actions) VALUES (1, ?, ?, ?, 'or', 1, ?)", setCode, setName, ruleRefsJSON, actionsJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setId, err := setResult.LastInsertId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var setRefs = []*firewallconfigs.HTTPFirewallRuleSetRef{
|
||||
{
|
||||
IsOn: true,
|
||||
SetId: setId,
|
||||
},
|
||||
}
|
||||
setRefsJSON, err := json.Marshal(setRefs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// group
|
||||
_, err = db.Exec("UPDATE edgeHTTPFirewallRuleGroups SET sets=? WHERE id=?", setRefsJSON, groupId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sql injection
|
||||
{
|
||||
ruleGroups, _, err := db.FindOnes("SELECT id, sets FROM edgeHTTPFirewallRuleGroups WHERE code='sqlInjection' AND state=1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, ruleGroup := range ruleGroups {
|
||||
var setsJSON = ruleGroup.GetBytes("sets")
|
||||
if len(setsJSON) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var setRefs = []*firewallconfigs.HTTPFirewallRuleSetRef{}
|
||||
err = json.Unmarshal(setsJSON, &setRefs)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if len(setRefs) != 5 {
|
||||
continue
|
||||
}
|
||||
|
||||
var isChanged = false
|
||||
for setIndex, setRef := range setRefs {
|
||||
set, setErr := db.FindOne("SELECT id, rules, isOn, actions FROM edgeHTTPFirewallRuleSets WHERE id=? AND state=1", setRef.SetId)
|
||||
if setErr != nil {
|
||||
return setErr
|
||||
}
|
||||
if set == nil {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
var rulesJSON = set.GetBytes("rules")
|
||||
if len(rulesJSON) == 0 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
var ruleRefs = []*firewallconfigs.HTTPFirewallRuleRef{}
|
||||
err = json.Unmarshal(rulesJSON, &ruleRefs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ruleRefs) < 1 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
|
||||
var actionsJSON = set.GetBytes("actions")
|
||||
if len(actionsJSON) == 0 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
var actions = []*firewallconfigs.HTTPFirewallActionConfig{}
|
||||
err = json.Unmarshal(actionsJSON, &actions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !(len(actions) == 1 && actions[0].Code == firewallconfigs.HTTPFirewallActionBlock) {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
|
||||
var rules = []maps.Map{}
|
||||
for _, ruleRef := range ruleRefs {
|
||||
rule, ruleErr := db.FindOne("SELECT * FROM edgeHTTPFirewallRules WHERE id=? AND state=1", ruleRef.RuleId)
|
||||
if ruleErr != nil {
|
||||
return ruleErr
|
||||
}
|
||||
if rule == nil {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
if isChanged {
|
||||
break
|
||||
}
|
||||
if len(rules) < 1 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
|
||||
switch setIndex {
|
||||
case 0:
|
||||
var rule = rules[0]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `union[\s/\*]+select`) {
|
||||
isChanged = true
|
||||
}
|
||||
case 1:
|
||||
var rule = rules[0]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `/\*(!|\x00)`) {
|
||||
isChanged = true
|
||||
}
|
||||
case 2:
|
||||
if len(rules) != 4 {
|
||||
isChanged = true
|
||||
} else {
|
||||
{
|
||||
var rule = rules[0]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `\s(and|or|rlike)\s+(if|updatexml)\s*\(`) {
|
||||
isChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var rule = rules[1]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `\s+(and|or|rlike)\s+(select|case)\s+`) {
|
||||
isChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var rule = rules[2]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `\s+(and|or|procedure)\s+[\w\p{L}]+\s*=\s*[\w\p{L}]+(\s|$|--|#)`) {
|
||||
isChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var rule = rules[3]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `\(\s*case\s+when\s+[\w\p{L}]+\s*=\s*[\w\p{L}]+\s+then\s+`) {
|
||||
isChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
var rule = rules[0]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `\b(updatexml|extractvalue|ascii|ord|char|chr|count|concat|rand|floor|substr|length|len|user|database|benchmark|analyse)\s*\(.*\)`) {
|
||||
isChanged = true
|
||||
}
|
||||
case 4:
|
||||
var rule = rules[0]
|
||||
if !(rule.GetString("param") == "${requestAll}" && rule.GetString("operator") == "match" && rule.GetString("value") == `;\s*(declare|use|drop|create|exec|delete|update|insert)\s`) {
|
||||
isChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if isChanged {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, setRef := range setRefs {
|
||||
err = disableSet(setRef.SetId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = addRuleToGroup(ruleGroup.GetInt64("id"), "7010", "SQL注入检测", []*firewallconfigs.HTTPFirewallActionConfig{
|
||||
{
|
||||
Code: firewallconfigs.HTTPFirewallActionPage,
|
||||
Options: maps.Map{"status": 403, "body": ""},
|
||||
},
|
||||
}, "${requestAll}", firewallconfigs.HTTPFirewallRuleOperatorContainsSQLInjection, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// xss
|
||||
{
|
||||
ruleGroups, _, err := db.FindOnes("SELECT id, sets FROM edgeHTTPFirewallRuleGroups WHERE code='xss' AND state=1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, ruleGroup := range ruleGroups {
|
||||
var setsJSON = ruleGroup.GetBytes("sets")
|
||||
if len(setsJSON) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var setRefs = []*firewallconfigs.HTTPFirewallRuleSetRef{}
|
||||
err = json.Unmarshal(setsJSON, &setRefs)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if len(setRefs) != 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
var isChanged = false
|
||||
for setIndex, setRef := range setRefs {
|
||||
set, setErr := db.FindOne("SELECT id, rules, isOn, actions FROM edgeHTTPFirewallRuleSets WHERE id=? AND state=1", setRef.SetId)
|
||||
if setErr != nil {
|
||||
return setErr
|
||||
}
|
||||
if set == nil {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
var rulesJSON = set.GetBytes("rules")
|
||||
if len(rulesJSON) == 0 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
var ruleRefs = []*firewallconfigs.HTTPFirewallRuleRef{}
|
||||
err = json.Unmarshal(rulesJSON, &ruleRefs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ruleRefs) != 1 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
|
||||
var actionsJSON = set.GetBytes("actions")
|
||||
if len(actionsJSON) == 0 {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
var actions = []*firewallconfigs.HTTPFirewallActionConfig{}
|
||||
err = json.Unmarshal(actionsJSON, &actions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !(len(actions) == 1 && actions[0].Code == firewallconfigs.HTTPFirewallActionBlock) {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
|
||||
rule, ruleErr := db.FindOne("SELECT * FROM edgeHTTPFirewallRules WHERE id=? AND state=1", ruleRefs[0].RuleId)
|
||||
if ruleErr != nil {
|
||||
return ruleErr
|
||||
}
|
||||
if rule == nil {
|
||||
isChanged = true
|
||||
break
|
||||
}
|
||||
|
||||
switch setIndex {
|
||||
case 0:
|
||||
if !(rule.GetString("param") == "${requestURI}" && rule.GetString("operator") == "match" && rule.GetString("value") == `(onmouseover|onmousemove|onmousedown|onmouseup|onerror|onload|onclick|ondblclick|onkeydown|onkeyup|onkeypress)\s*=`) {
|
||||
isChanged = true
|
||||
}
|
||||
case 1:
|
||||
if !(rule.GetString("param") == "${requestURI}" && rule.GetString("operator") == "match" && rule.GetString("value") == `(alert|eval|prompt|confirm)\s*\(`) {
|
||||
isChanged = true
|
||||
}
|
||||
case 2:
|
||||
if !(rule.GetString("param") == "${requestURI}" && rule.GetString("operator") == "match" && rule.GetString("value") == `<(script|iframe|link)`) {
|
||||
isChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if isChanged {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, setRef := range setRefs {
|
||||
err = disableSet(setRef.SetId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = addRuleToGroup(ruleGroup.GetInt64("id"), "1010", "XSS攻击检测", []*firewallconfigs.HTTPFirewallActionConfig{
|
||||
{
|
||||
Code: firewallconfigs.HTTPFirewallActionPage,
|
||||
Options: maps.Map{"status": 403, "body": ""},
|
||||
},
|
||||
}, "${requestAll}", firewallconfigs.HTTPFirewallRuleOperatorContainsXSS, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// user register config
|
||||
|
||||
var newAddedFeatureCodes = []string{
|
||||
userconfigs.UserFeatureCodeServerOptimization,
|
||||
userconfigs.UserFeatureCodeServerAuth,
|
||||
userconfigs.UserFeatureCodeServerWebsocket,
|
||||
userconfigs.UserFeatureCodeServerHTTP3,
|
||||
userconfigs.UserFeatureCodeServerCC,
|
||||
userconfigs.UserFeatureCodeServerReferers,
|
||||
userconfigs.UserFeatureCodeServerUserAgent,
|
||||
userconfigs.UserFeatureCodeServerRequestLimit,
|
||||
userconfigs.UserFeatureCodeServerCompression,
|
||||
userconfigs.UserFeatureCodeServerRewriteRules,
|
||||
userconfigs.UserFeatureCodeServerHostRedirects,
|
||||
userconfigs.UserFeatureCodeServerHTTPHeaders,
|
||||
userconfigs.UserFeatureCodeServerPages,
|
||||
}
|
||||
|
||||
{
|
||||
value, err := db.FindCol(0, "SELECT value FROM edgeSysSettings WHERE code=?", systemconfigs.SettingCodeUserRegisterConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value != nil {
|
||||
var valueString = types.String(value)
|
||||
if valueString != "null" && len(valueString) > 0 {
|
||||
var registerConfig = &userconfigs.UserRegisterConfig{}
|
||||
err = json.Unmarshal([]byte(valueString), registerConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(registerConfig.Features) > 0 {
|
||||
var newFeatureCodes = registerConfig.Features
|
||||
var changed = false
|
||||
for _, featureCode := range newAddedFeatureCodes {
|
||||
if !lists.ContainsString(newFeatureCodes, featureCode) {
|
||||
newFeatureCodes = append(newFeatureCodes, featureCode)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
registerConfig.Features = newFeatureCodes
|
||||
registerConfigJSON, err := json.Marshal(registerConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec("UPDATE edgeSysSettings SET value=? WHERE code=?", registerConfigJSON, systemconfigs.SettingCodeUserRegisterConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// user features
|
||||
{
|
||||
var sqlPieces []string
|
||||
for _, featureCode := range newAddedFeatureCodes {
|
||||
if strings.Contains(featureCode, "'") {
|
||||
continue
|
||||
}
|
||||
sqlPieces = append(sqlPieces, "'$', '"+featureCode+"'")
|
||||
}
|
||||
|
||||
_, err := db.Exec("UPDATE edgeUsers SET features=JSON_ARRAY_APPEND(features," + strings.Join(sqlPieces, ",") + ") WHERE features IS NOT NULL AND JSON_LENGTH(features)>0 AND NOT JSON_CONTAINS(features, '" + strconv.Quote(newAddedFeatureCodes[0]) + "')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -289,3 +289,23 @@ func TestUpgradeSQLData_v1_2_10(t *testing.T) {
|
||||
}
|
||||
t.Log("ok")
|
||||
}
|
||||
|
||||
|
||||
func TestUpgradeSQLData_v1_3_2(t *testing.T) {
|
||||
db, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
||||
Driver: "mysql",
|
||||
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&timeout=30s",
|
||||
Prefix: "edge",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
err = upgradeV1_3_2(db)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("ok")
|
||||
}
|
||||
@@ -33,7 +33,7 @@ func TestZero_Map(t *testing.T) {
|
||||
|
||||
var stat2 = &runtime.MemStats{}
|
||||
runtime.ReadMemStats(stat2)
|
||||
t.Log((stat2.HeapInuse-stat1.HeapInuse)/1024/1024, "MB")
|
||||
t.Log((stat2.HeapInuse-stat1.HeapInuse)/1024/1024, "MiB")
|
||||
t.Log(len(m))
|
||||
|
||||
_, ok := m[1024]
|
||||
|
||||
Reference in New Issue
Block a user