From d891d19fc38366249753fe831bb4130b779e54d5 Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Mon, 13 Nov 2023 10:46:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BE=8B=E5=A4=96URL=E5=92=8C=E9=99=90?= =?UTF-8?q?=E5=88=B6URL=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/db/models/http_page_dao.go | 83 +++++++++++++++++++++- internal/db/models/http_page_model.go | 64 +++++++++++------ internal/rpc/services/service_http_page.go | 62 +++++++++++++++- internal/setup/sql.json | 14 +++- 4 files changed, 193 insertions(+), 30 deletions(-) diff --git a/internal/db/models/http_page_dao.go b/internal/db/models/http_page_dao.go index 93447932..c54402c2 100644 --- a/internal/db/models/http_page_dao.go +++ b/internal/db/models/http_page_dao.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" _ "github.com/go-sql-driver/mysql" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" @@ -76,7 +77,7 @@ func (this *HTTPPageDAO) FindEnabledHTTPPage(tx *dbs.Tx, id int64) (*HTTPPage, e } // CreatePage 创建Page -func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []string, bodyType serverconfigs.HTTPPageBodyType, url string, body string, newStatus int) (pageId int64, err error) { +func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []string, bodyType serverconfigs.HTTPPageBodyType, url string, body string, newStatus int, exceptURLPatterns []*shared.URLPattern, onlyURLPatterns []*shared.URLPattern) (pageId int64, err error) { var op = NewHTTPPageOperator() op.UserId = userId op.IsOn = true @@ -93,6 +94,29 @@ func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []strin op.Url = url op.Body = body op.NewStatus = newStatus + + { + if exceptURLPatterns == nil { + exceptURLPatterns = []*shared.URLPattern{} + } + exceptURLPatternsJSON, err := json.Marshal(exceptURLPatterns) + if err != nil { + return 0, err + } + op.ExceptURLPatterns = exceptURLPatternsJSON + } + + { + if onlyURLPatterns == nil { + onlyURLPatterns = []*shared.URLPattern{} + } + onlyURLPatternsJSON, err := json.Marshal(onlyURLPatterns) + if err != nil { + return 0, err + } + op.OnlyURLPatterns = onlyURLPatternsJSON + } + err = this.Save(tx, op) if err != nil { return 0, err @@ -102,7 +126,7 @@ func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []strin } // UpdatePage 修改Page -func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []string, bodyType serverconfigs.HTTPPageBodyType, url string, body string, newStatus int) error { +func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []string, bodyType serverconfigs.HTTPPageBodyType, url string, body string, newStatus int, exceptURLPatterns []*shared.URLPattern, onlyURLPatterns []*shared.URLPattern) error { if pageId <= 0 { return errors.New("invalid pageId") } @@ -125,6 +149,29 @@ func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []strin op.Url = url op.Body = body op.NewStatus = newStatus + + { + if exceptURLPatterns == nil { + exceptURLPatterns = []*shared.URLPattern{} + } + exceptURLPatternsJSON, err := json.Marshal(exceptURLPatterns) + if err != nil { + return err + } + op.ExceptURLPatterns = exceptURLPatternsJSON + } + + { + if onlyURLPatterns == nil { + onlyURLPatterns = []*shared.URLPattern{} + } + onlyURLPatternsJSON, err := json.Marshal(onlyURLPatterns) + if err != nil { + return err + } + op.OnlyURLPatterns = onlyURLPatternsJSON + } + err = this.Save(tx, op) if err != nil { return err @@ -155,6 +202,14 @@ func (this *HTTPPageDAO) ClonePage(tx *dbs.Tx, fromPageId int64) (newPageId int6 op.Body = page.Body op.BodyType = page.BodyType op.State = page.State + + if len(page.ExceptURLPatterns) > 0 { + op.ExceptURLPatterns = page.ExceptURLPatterns + } + if len(page.OnlyURLPatterns) > 0 { + op.OnlyURLPatterns = page.OnlyURLPatterns + } + return this.SaveInt64(tx, op) } @@ -178,7 +233,7 @@ func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *u return nil, nil } - config := &serverconfigs.HTTPPageConfig{} + var config = &serverconfigs.HTTPPageConfig{} config.Id = int64(page.Id) config.IsOn = page.IsOn config.NewStatus = int(page.NewStatus) @@ -201,6 +256,28 @@ func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *u } } + if len(page.ExceptURLPatterns) > 0 { + var exceptURLPatterns = []*shared.URLPattern{} + err = json.Unmarshal(page.ExceptURLPatterns, &exceptURLPatterns) + if err != nil { + return nil, err + } + if len(exceptURLPatterns) > 0 { + config.ExceptURLPatterns = exceptURLPatterns + } + } + + if len(page.OnlyURLPatterns) > 0 { + var onlyURLPatterns = []*shared.URLPattern{} + err = json.Unmarshal(page.OnlyURLPatterns, &onlyURLPatterns) + if err != nil { + return nil, err + } + if len(onlyURLPatterns) > 0 { + config.OnlyURLPatterns = onlyURLPatterns + } + } + if cacheMap != nil { cacheMap.Put(cacheKey, config) } diff --git a/internal/db/models/http_page_model.go b/internal/db/models/http_page_model.go index 1add71a1..47213892 100644 --- a/internal/db/models/http_page_model.go +++ b/internal/db/models/http_page_model.go @@ -2,33 +2,53 @@ package models import "github.com/iwind/TeaGo/dbs" +const ( + HTTPPageField_Id dbs.FieldName = "id" // ID + HTTPPageField_AdminId dbs.FieldName = "adminId" // 管理员ID + HTTPPageField_UserId dbs.FieldName = "userId" // 用户ID + HTTPPageField_IsOn dbs.FieldName = "isOn" // 是否启用 + HTTPPageField_StatusList dbs.FieldName = "statusList" // 状态列表 + HTTPPageField_Url dbs.FieldName = "url" // 页面URL + HTTPPageField_NewStatus dbs.FieldName = "newStatus" // 新状态码 + HTTPPageField_State dbs.FieldName = "state" // 状态 + HTTPPageField_CreatedAt dbs.FieldName = "createdAt" // 创建时间 + HTTPPageField_Body dbs.FieldName = "body" // 页面内容 + HTTPPageField_BodyType dbs.FieldName = "bodyType" // 内容类型 + HTTPPageField_ExceptURLPatterns dbs.FieldName = "exceptURLPatterns" // 例外URL + HTTPPageField_OnlyURLPatterns dbs.FieldName = "onlyURLPatterns" // 限制URL +) + // HTTPPage 特殊页面 type HTTPPage struct { - Id uint32 `field:"id"` // ID - AdminId uint32 `field:"adminId"` // 管理员ID - UserId uint32 `field:"userId"` // 用户ID - IsOn bool `field:"isOn"` // 是否启用 - StatusList dbs.JSON `field:"statusList"` // 状态列表 - Url string `field:"url"` // 页面URL - NewStatus int32 `field:"newStatus"` // 新状态码 - State uint8 `field:"state"` // 状态 - CreatedAt uint64 `field:"createdAt"` // 创建时间 - Body string `field:"body"` // 页面内容 - BodyType string `field:"bodyType"` // 内容类型 + Id uint32 `field:"id"` // ID + AdminId uint32 `field:"adminId"` // 管理员ID + UserId uint32 `field:"userId"` // 用户ID + IsOn bool `field:"isOn"` // 是否启用 + StatusList dbs.JSON `field:"statusList"` // 状态列表 + Url string `field:"url"` // 页面URL + NewStatus int32 `field:"newStatus"` // 新状态码 + State uint8 `field:"state"` // 状态 + CreatedAt uint64 `field:"createdAt"` // 创建时间 + Body string `field:"body"` // 页面内容 + BodyType string `field:"bodyType"` // 内容类型 + ExceptURLPatterns dbs.JSON `field:"exceptURLPatterns"` // 例外URL + OnlyURLPatterns dbs.JSON `field:"onlyURLPatterns"` // 限制URL } type HTTPPageOperator struct { - Id interface{} // ID - AdminId interface{} // 管理员ID - UserId interface{} // 用户ID - IsOn interface{} // 是否启用 - StatusList interface{} // 状态列表 - Url interface{} // 页面URL - NewStatus interface{} // 新状态码 - State interface{} // 状态 - CreatedAt interface{} // 创建时间 - Body interface{} // 页面内容 - BodyType interface{} // 内容类型 + Id any // ID + AdminId any // 管理员ID + UserId any // 用户ID + IsOn any // 是否启用 + StatusList any // 状态列表 + Url any // 页面URL + NewStatus any // 新状态码 + State any // 状态 + CreatedAt any // 创建时间 + Body any // 页面内容 + BodyType any // 内容类型 + ExceptURLPatterns any // 例外URL + OnlyURLPatterns any // 限制URL } func NewHTTPPageOperator() *HTTPPageOperator { diff --git a/internal/rpc/services/service_http_page.go b/internal/rpc/services/service_http_page.go index 3cbd09f7..d1d1a90d 100644 --- a/internal/rpc/services/service_http_page.go +++ b/internal/rpc/services/service_http_page.go @@ -4,10 +4,12 @@ import ( "context" "encoding/json" "errors" + "fmt" "github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" "github.com/iwind/TeaGo/types" ) @@ -64,7 +66,35 @@ func (this *HTTPPageService) CreateHTTPPage(ctx context.Context, req *pb.CreateH return nil, errors.New("invalid 'bodyType': " + req.BodyType) } - pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus)) + var exceptURLPatterns = []*shared.URLPattern{} + if len(req.ExceptURLPatternsJSON) > 0 { + err = json.Unmarshal(req.ExceptURLPatternsJSON, &exceptURLPatterns) + if err != nil { + return nil, err + } + for _, pattern := range exceptURLPatterns { + err = pattern.Init() + if err != nil { + return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err) + } + } + } + + var onlyURLPatterns = []*shared.URLPattern{} + if len(req.OnlyURLPatternsJSON) > 0 { + err = json.Unmarshal(req.OnlyURLPatternsJSON, &onlyURLPatterns) + if err != nil { + return nil, err + } + for _, pattern := range onlyURLPatterns { + err = pattern.Init() + if err != nil { + return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err) + } + } + } + + pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus), exceptURLPatterns, onlyURLPatterns) if err != nil { return nil, err } @@ -127,7 +157,35 @@ func (this *HTTPPageService) UpdateHTTPPage(ctx context.Context, req *pb.UpdateH return nil, errors.New("invalid 'bodyType': " + req.BodyType) } - err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus)) + var exceptURLPatterns = []*shared.URLPattern{} + if len(req.ExceptURLPatternsJSON) > 0 { + err = json.Unmarshal(req.ExceptURLPatternsJSON, &exceptURLPatterns) + if err != nil { + return nil, err + } + for _, pattern := range exceptURLPatterns { + err = pattern.Init() + if err != nil { + return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err) + } + } + } + + var onlyURLPatterns = []*shared.URLPattern{} + if len(req.OnlyURLPatternsJSON) > 0 { + err = json.Unmarshal(req.OnlyURLPatternsJSON, &onlyURLPatterns) + if err != nil { + return nil, err + } + for _, pattern := range onlyURLPatterns { + err = pattern.Init() + if err != nil { + return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err) + } + } + } + + err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus), exceptURLPatterns, onlyURLPatterns) if err != nil { return nil, err } diff --git a/internal/setup/sql.json b/internal/setup/sql.json index cfff6d71..65de29b8 100644 --- a/internal/setup/sql.json +++ b/internal/setup/sql.json @@ -102170,7 +102170,7 @@ "name": "edgeHTTPAccessLogs", "engine": "InnoDB", "charset": "utf8mb4_general_ci", - "definition": "CREATE TABLE `edgeHTTPAccessLogs` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `serverId` int(11) unsigned DEFAULT '0' COMMENT '服务ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `status` int(3) unsigned DEFAULT '0' COMMENT '状态码',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `content` json DEFAULT NULL COMMENT '日志内容',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `firewallPolicyId` int(11) unsigned DEFAULT '0' COMMENT 'WAF策略ID',\n `firewallRuleGroupId` int(11) unsigned DEFAULT '0' COMMENT 'WAF分组ID',\n `firewallRuleSetId` int(11) unsigned DEFAULT '0' COMMENT 'WAF集ID',\n `firewallRuleId` int(11) unsigned DEFAULT '0' COMMENT 'WAF规则ID',\n `remoteAddr` varchar(64) DEFAULT NULL COMMENT 'IP地址',\n `domain` varchar(128) DEFAULT NULL COMMENT '域名',\n `requestBody` mediumblob COMMENT '请求内容',\n `responseBody` mediumblob COMMENT '响应内容',\n PRIMARY KEY (`id`),\n KEY `serverId` (`serverId`),\n KEY `nodeId` (`nodeId`),\n KEY `serverId_status` (`serverId`,`status`),\n KEY `requestId` (`requestId`),\n KEY `firewallPolicyId` (`firewallPolicyId`),\n KEY `firewallRuleGroupId` (`firewallRuleGroupId`),\n KEY `firewallRuleSetId` (`firewallRuleSetId`),\n KEY `firewallRuleId` (`firewallRuleId`),\n KEY `remoteAddr` (`remoteAddr`),\n KEY `domain` (`domain`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问日志'", + "definition": "CREATE TABLE `edgeHTTPAccessLogs` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `serverId` int(11) unsigned DEFAULT '0' COMMENT '服务ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `status` int(3) unsigned DEFAULT '0' COMMENT '状态码',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `content` json DEFAULT NULL COMMENT '日志内容',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `firewallPolicyId` int(11) unsigned DEFAULT '0' COMMENT 'WAF策略ID',\n `firewallRuleGroupId` int(11) unsigned DEFAULT '0' COMMENT 'WAF分组ID',\n `firewallRuleSetId` int(11) unsigned DEFAULT '0' COMMENT 'WAF集ID',\n `firewallRuleId` int(11) unsigned DEFAULT '0' COMMENT 'WAF规则ID',\n `remoteAddr` varchar(64) DEFAULT NULL COMMENT 'IP地址',\n `domain` varchar(255) DEFAULT NULL COMMENT '域名',\n `requestBody` mediumblob COMMENT '请求内容',\n `responseBody` mediumblob COMMENT '响应内容',\n PRIMARY KEY (`id`),\n KEY `serverId` (`serverId`),\n KEY `nodeId` (`nodeId`),\n KEY `serverId_status` (`serverId`,`status`),\n KEY `requestId` (`requestId`),\n KEY `firewallPolicyId` (`firewallPolicyId`),\n KEY `firewallRuleGroupId` (`firewallRuleGroupId`),\n KEY `firewallRuleSetId` (`firewallRuleSetId`),\n KEY `firewallRuleId` (`firewallRuleId`),\n KEY `remoteAddr` (`remoteAddr`),\n KEY `domain` (`domain`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问日志'", "fields": [ { "name": "id", @@ -102222,7 +102222,7 @@ }, { "name": "domain", - "definition": "varchar(128) COMMENT '域名'" + "definition": "varchar(255) COMMENT '域名'" }, { "name": "requestBody", @@ -103342,7 +103342,7 @@ "name": "edgeHTTPPages", "engine": "InnoDB", "charset": "utf8mb4_general_ci", - "definition": "CREATE TABLE `edgeHTTPPages` (\n `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `adminId` int(11) unsigned DEFAULT '0' COMMENT '管理员ID',\n `userId` int(11) unsigned DEFAULT '0' COMMENT '用户ID',\n `isOn` tinyint(1) unsigned DEFAULT '0' COMMENT '是否启用',\n `statusList` json DEFAULT NULL COMMENT '状态列表',\n `url` varchar(1024) DEFAULT NULL COMMENT '页面URL',\n `newStatus` int(3) DEFAULT NULL COMMENT '新状态码',\n `state` tinyint(1) unsigned DEFAULT '1' COMMENT '状态',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `body` text COMMENT '页面内容',\n `bodyType` varchar(32) DEFAULT 'url' COMMENT '内容类型',\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='特殊页面'", + "definition": "CREATE TABLE `edgeHTTPPages` (\n `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `adminId` int(11) unsigned DEFAULT '0' COMMENT '管理员ID',\n `userId` int(11) unsigned DEFAULT '0' COMMENT '用户ID',\n `isOn` tinyint(1) unsigned DEFAULT '0' COMMENT '是否启用',\n `statusList` json DEFAULT NULL COMMENT '状态列表',\n `url` varchar(1024) DEFAULT NULL COMMENT '页面URL',\n `newStatus` int(3) DEFAULT NULL COMMENT '新状态码',\n `state` tinyint(1) unsigned DEFAULT '1' COMMENT '状态',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `body` text COMMENT '页面内容',\n `bodyType` varchar(32) DEFAULT 'url' COMMENT '内容类型',\n `exceptURLPatterns` json DEFAULT NULL COMMENT '例外URL',\n `onlyURLPatterns` json DEFAULT NULL COMMENT '限制URL',\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='特殊页面'", "fields": [ { "name": "id", @@ -103387,6 +103387,14 @@ { "name": "bodyType", "definition": "varchar(32) DEFAULT 'url' COMMENT '内容类型'" + }, + { + "name": "exceptURLPatterns", + "definition": "json COMMENT '例外URL'" + }, + { + "name": "onlyURLPatterns", + "definition": "json COMMENT '限制URL'" } ], "indexes": [