This commit is contained in:
unknown
2026-02-04 20:27:13 +08:00
commit 3b042d1dad
9410 changed files with 1488147 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type CountAction struct {
actionutils.ParentAction
}
func (this *CountAction) RunPost(params struct{}) {
countResp, err := this.RPC().HTTPFirewallPolicyRPC().CountAllEnabledHTTPFirewallPolicies(this.UserContext(), &pb.CountAllEnabledHTTPFirewallPoliciesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["count"] = countResp.Count
this.Success()
}

View File

@@ -0,0 +1,102 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
)
type CreateGroupPopupAction struct {
actionutils.ParentAction
}
func (this *CreateGroupPopupAction) Init() {
this.Nav("", "", "")
}
func (this *CreateGroupPopupAction) RunGet(params struct {
Type string
}) {
this.Data["type"] = params.Type
this.Show()
}
func (this *CreateGroupPopupAction) RunPost(params struct {
FirewallPolicyId int64
Type string
Name string
Description string
IsOn bool
Must *actions.Must
}) {
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
}
params.Must.
Field("name", params.Name).
Require("请输入分组名称")
createResp, err := this.RPC().HTTPFirewallRuleGroupRPC().CreateHTTPFirewallRuleGroup(this.UserContext(), &pb.CreateHTTPFirewallRuleGroupRequest{
IsOn: params.IsOn,
Name: params.Name,
Description: params.Description,
})
if err != nil {
this.ErrorPage(err)
return
}
groupId := createResp.FirewallRuleGroupId
switch params.Type {
case "inbound":
firewallPolicy.Inbound.GroupRefs = append(firewallPolicy.Inbound.GroupRefs, &firewallconfigs.HTTPFirewallRuleGroupRef{
IsOn: true,
GroupId: groupId,
})
default:
firewallPolicy.Outbound.GroupRefs = append(firewallPolicy.Outbound.GroupRefs, &firewallconfigs.HTTPFirewallRuleGroupRef{
IsOn: true,
GroupId: groupId,
})
}
inboundJSON, err := firewallPolicy.InboundJSON()
if err != nil {
this.ErrorPage(err)
return
}
outboundJSON, err := firewallPolicy.OutboundJSON()
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallPolicyRPC().UpdateHTTPFirewallPolicyGroups(this.UserContext(), &pb.UpdateHTTPFirewallPolicyGroupsRequest{
HttpFirewallPolicyId: params.FirewallPolicyId,
InboundJSON: inboundJSON,
OutboundJSON: outboundJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
// 日志
defer this.CreateLogInfo(codes.WAFRuleGroup_LogCreateRuleGroup, groupId, params.Name)
this.Success()
}

View File

@@ -0,0 +1,70 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
)
type CreatePopupAction struct {
actionutils.ParentAction
}
func (this *CreatePopupAction) Init() {
this.Nav("", "", "")
}
func (this *CreatePopupAction) RunGet(params struct{}) {
// 预置分组
groups := []maps.Map{}
templatePolicy := firewallconfigs.HTTPFirewallTemplate()
for _, group := range templatePolicy.AllRuleGroups() {
groups = append(groups, maps.Map{
"code": group.Code,
"name": group.Name,
"isOn": group.IsOn,
})
}
this.Data["groups"] = groups
this.Show()
}
func (this *CreatePopupAction) RunPost(params struct {
Name string
GroupCodes []string
Description string
IsOn bool
Must *actions.Must
}) {
params.Must.
Field("name", params.Name).
Require("请输入策略名称")
createResp, err := this.RPC().HTTPFirewallPolicyRPC().CreateHTTPFirewallPolicy(this.UserContext(), &pb.CreateHTTPFirewallPolicyRequest{
IsOn: params.IsOn,
Name: params.Name,
Description: params.Description,
HttpFirewallGroupCodes: params.GroupCodes,
})
if err != nil {
this.ErrorPage(err)
return
}
// 返回数据
this.Data["firewallPolicy"] = maps.Map{
"id": createResp.HttpFirewallPolicyId,
"name": params.Name,
"description": params.Description,
}
// 日志
defer this.CreateLogInfo(codes.WAFPolicy_LogCreateWAFPolicy, createResp.HttpFirewallPolicyId)
this.Success()
}

View File

@@ -0,0 +1,124 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
)
type CreateRulePopupAction struct {
actionutils.ParentAction
}
func (this *CreateRulePopupAction) Init() {
this.Nav("", "", "")
}
func (this *CreateRulePopupAction) RunGet(params struct {
Type string
}) {
// check points
var checkpointList = []maps.Map{}
for _, checkpoint := range firewallconfigs.AllCheckpoints {
if (params.Type == "inbound" && checkpoint.IsRequest) || (params.Type == "outbound" && !checkpoint.IsRequest) {
checkpointList = append(checkpointList, maps.Map{
"name": checkpoint.Name,
"prefix": checkpoint.Prefix,
"description": checkpoint.Description,
"hasParams": checkpoint.HasParams,
"params": checkpoint.Params,
"options": checkpoint.Options,
"isComposed": checkpoint.IsComposed,
"dataType": checkpoint.DataType,
})
}
}
// operators
var operatorMaps = []maps.Map{}
for _, operator := range firewallconfigs.AllRuleOperators {
operatorMaps = append(operatorMaps, maps.Map{
"name": operator.Name,
"code": operator.Code,
"description": operator.Description,
"case": operator.CaseInsensitive,
"dataType": operator.DataType,
})
}
this.Data["operators"] = operatorMaps
this.Data["checkpoints"] = checkpointList
this.Show()
}
func (this *CreateRulePopupAction) RunPost(params struct {
RuleId int64
Prefix string
Operator string
Param string
ParamFiltersJSON []byte
OptionsJSON []byte
Value string
Case bool
Must *actions.Must
}) {
params.Must.
Field("prefix", params.Prefix).
Require("请选择参数")
if len(params.Value) > 4096 {
this.FailField("value", "对比值内容长度不能超过4096个字符")
return
}
var rule = &firewallconfigs.HTTPFirewallRule{
Id: params.RuleId,
IsOn: true,
}
if len(params.Param) > 0 {
rule.Param = "${" + params.Prefix + "." + params.Param + "}"
} else {
rule.Param = "${" + params.Prefix + "}"
}
var paramFilters = []*firewallconfigs.ParamFilter{}
if len(params.ParamFiltersJSON) > 0 {
err := json.Unmarshal(params.ParamFiltersJSON, &paramFilters)
if err != nil {
this.ErrorPage(err)
return
}
}
rule.ParamFilters = paramFilters
rule.Operator = params.Operator
rule.Value = params.Value
rule.IsCaseInsensitive = params.Case
if len(params.OptionsJSON) > 0 {
options := []maps.Map{}
err := json.Unmarshal(params.OptionsJSON, &options)
if err != nil {
this.ErrorPage(err)
return
}
rule.CheckpointOptions = map[string]interface{}{}
for _, option := range options {
rule.CheckpointOptions[option.GetString("code")] = option.Get("value")
}
}
// 校验
err := rule.Init()
if err != nil {
this.Fail("校验规则 '" + rule.Param + " " + rule.Operator + " " + rule.Value + "' 失败,原因:" + err.Error())
}
this.Data["rule"] = rule
this.Success()
}

View File

@@ -0,0 +1,173 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
"strconv"
)
type CreateSetPopupAction struct {
actionutils.ParentAction
}
func (this *CreateSetPopupAction) Init() {
this.Nav("", "", "")
}
func (this *CreateSetPopupAction) RunGet(params struct {
FirewallPolicyId int64
GroupId int64
Type string
}) {
this.Data["groupId"] = params.GroupId
this.Data["type"] = params.Type
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
this.Data["firewallPolicy"] = firewallPolicy
// 一些配置
this.Data["connectors"] = []maps.Map{
{
"name": "和(AND)",
"value": firewallconfigs.HTTPFirewallRuleConnectorAnd,
"description": "所有规则都满足才视为匹配",
},
{
"name": "或(OR)",
"value": firewallconfigs.HTTPFirewallRuleConnectorOr,
"description": "任一规则满足了就视为匹配",
},
}
var actionMaps = []maps.Map{}
for _, action := range firewallconfigs.AllActions {
// 用户端暂时屏蔽notify等动作
if action.Code == firewallconfigs.HTTPFirewallActionNotify || action.Code == firewallconfigs.HTTPFirewallActionRecordIP {
continue
}
actionMaps = append(actionMaps, maps.Map{
"name": action.Name,
"description": action.Description,
"code": action.Code,
})
}
this.Data["actions"] = actionMaps
this.Show()
}
func (this *CreateSetPopupAction) RunPost(params struct {
GroupId int64
Name string
RulesJSON []byte
Connector string
ActionsJSON []byte
IgnoreLocal bool
IgnoreSearchEngine bool
Must *actions.Must
}) {
groupConfig, err := dao.SharedHTTPFirewallRuleGroupDAO.FindRuleGroupConfig(this.UserContext(), params.GroupId)
if err != nil {
this.ErrorPage(err)
return
}
if groupConfig == nil {
this.Fail("找不到分组Id" + strconv.FormatInt(params.GroupId, 10))
return
}
params.Must.
Field("name", params.Name).
Require("请输入规则集名称")
if len(params.RulesJSON) == 0 {
this.Fail("请添加至少一个规则")
}
var rules = []*firewallconfigs.HTTPFirewallRule{}
err = json.Unmarshal(params.RulesJSON, &rules)
if err != nil {
this.ErrorPage(err)
return
}
if len(rules) == 0 {
this.Fail("请添加至少一个规则")
return
}
var actionConfigs = []*firewallconfigs.HTTPFirewallActionConfig{}
if len(params.ActionsJSON) > 0 {
err = json.Unmarshal(params.ActionsJSON, &actionConfigs)
if err != nil {
this.ErrorPage(err)
return
}
}
if len(actionConfigs) == 0 {
this.Fail("请添加至少一个动作")
return
}
var setConfig = &firewallconfigs.HTTPFirewallRuleSet{
Id: 0,
IsOn: true,
Name: params.Name,
Code: "",
Description: "",
Connector: params.Connector,
RuleRefs: nil,
Rules: rules,
Actions: actionConfigs,
IgnoreLocal: params.IgnoreLocal,
IgnoreSearchEngine: params.IgnoreSearchEngine,
}
setConfigJSON, err := json.Marshal(setConfig)
if err != nil {
this.ErrorPage(err)
return
}
createUpdateResp, err := this.RPC().HTTPFirewallRuleSetRPC().CreateOrUpdateHTTPFirewallRuleSetFromConfig(this.UserContext(), &pb.CreateOrUpdateHTTPFirewallRuleSetFromConfigRequest{FirewallRuleSetConfigJSON: setConfigJSON})
if err != nil {
this.ErrorPage(err)
return
}
groupConfig.SetRefs = append(groupConfig.SetRefs, &firewallconfigs.HTTPFirewallRuleSetRef{
IsOn: true,
SetId: createUpdateResp.FirewallRuleSetId,
})
setRefsJSON, err := json.Marshal(groupConfig.SetRefs)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallRuleGroupRPC().UpdateHTTPFirewallRuleGroupSets(this.UserContext(), &pb.UpdateHTTPFirewallRuleGroupSetsRequest{
FirewallRuleGroupId: params.GroupId,
FirewallRuleSetsJSON: setRefsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["setId"] = createUpdateResp.FirewallRuleSetId
this.Success()
}

View File

@@ -0,0 +1,35 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type DeleteAction struct {
actionutils.ParentAction
}
func (this *DeleteAction) RunPost(params struct {
FirewallPolicyId int64
}) {
// 日志
defer this.CreateLogInfo(codes.WAFPolicy_LogDeleteWAFPolicy, params.FirewallPolicyId)
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClustersWithHTTPFirewallPolicyId(this.UserContext(), &pb.CountAllEnabledNodeClustersWithHTTPFirewallPolicyIdRequest{HttpFirewallPolicyId: params.FirewallPolicyId})
if err != nil {
this.ErrorPage(err)
return
}
if countResp.Count > 0 {
this.Fail("此WAF策略正在被有些集群引用请修改后再删除。")
}
_, err = this.RPC().HTTPFirewallPolicyRPC().DeleteHTTPFirewallPolicy(this.UserContext(), &pb.DeleteHTTPFirewallPolicyRequest{HttpFirewallPolicyId: params.FirewallPolicyId})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,56 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type DeleteGroupAction struct {
actionutils.ParentAction
}
func (this *DeleteGroupAction) RunPost(params struct {
FirewallPolicyId int64
GroupId int64
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleGroup_LogDeleteRuleGroup, params.FirewallPolicyId, params.GroupId)
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
firewallPolicy.RemoveRuleGroup(params.GroupId)
inboundJSON, err := firewallPolicy.InboundJSON()
if err != nil {
this.ErrorPage(err)
return
}
outboundJSON, err := firewallPolicy.OutboundJSON()
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallPolicyRPC().UpdateHTTPFirewallPolicyGroups(this.UserContext(), &pb.UpdateHTTPFirewallPolicyGroupsRequest{
HttpFirewallPolicyId: params.FirewallPolicyId,
InboundJSON: inboundJSON,
OutboundJSON: outboundJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,54 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type DeleteSetAction struct {
actionutils.ParentAction
}
func (this *DeleteSetAction) RunPost(params struct {
GroupId int64
SetId int64
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleSet_LogDeleteRuleSet, params.GroupId, params.SetId)
groupConfig, err := dao.SharedHTTPFirewallRuleGroupDAO.FindRuleGroupConfig(this.UserContext(), params.GroupId)
if err != nil {
this.ErrorPage(err)
return
}
if groupConfig == nil {
this.NotFound("firewallRuleGroup", params.GroupId)
return
}
newRefs := []*firewallconfigs.HTTPFirewallRuleSetRef{}
for _, ref := range groupConfig.SetRefs {
if ref.SetId != params.SetId {
newRefs = append(newRefs, ref)
}
}
newRefsJSON, err := json.Marshal(newRefs)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallRuleGroupRPC().UpdateHTTPFirewallRuleGroupSets(this.UserContext(), &pb.UpdateHTTPFirewallRuleGroupSetsRequest{
FirewallRuleGroupId: params.GroupId,
FirewallRuleSetsJSON: newRefsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,121 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/ttlcache"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/rands"
"time"
)
type ExportAction struct {
actionutils.ParentAction
}
func (this *ExportAction) Init() {
this.Nav("", "", "export")
}
func (this *ExportAction) RunGet(params struct {
FirewallPolicyId int64
}) {
policy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if policy == nil {
this.NotFound("firewallPolicy", policy.Id)
return
}
inboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
outboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
if policy.Inbound != nil {
for _, g := range policy.Inbound.Groups {
if g.IsOn {
inboundGroups = append(inboundGroups, g)
}
}
}
if policy.Outbound != nil {
for _, g := range policy.Outbound.Groups {
if g.IsOn {
outboundGroups = append(outboundGroups, g)
}
}
}
this.Data["inboundGroups"] = inboundGroups
this.Data["outboundGroups"] = outboundGroups
this.Show()
}
func (this *ExportAction) RunPost(params struct {
FirewallPolicyId int64
InboundGroupIds []int64
OutboundGroupIds []int64
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo(codes.WAFPolicy_LogExportWAFPolicy, params.FirewallPolicyId)
policy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if policy == nil {
this.NotFound("firewallPolicy", policy.Id)
return
}
// inbound
newInboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
for _, inboundGroupId := range params.InboundGroupIds {
group := policy.FindRuleGroup(inboundGroupId)
if group != nil {
newInboundGroups = append(newInboundGroups, group)
}
}
if policy.Inbound == nil {
policy.Inbound = &firewallconfigs.HTTPFirewallInboundConfig{
IsOn: true,
}
}
policy.Inbound.Groups = newInboundGroups
policy.Inbound.GroupRefs = nil
// outbound
newOutboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
for _, outboundGroupId := range params.OutboundGroupIds {
group := policy.FindRuleGroup(outboundGroupId)
if group != nil {
newOutboundGroups = append(newOutboundGroups, group)
}
}
if policy.Outbound == nil {
policy.Outbound = &firewallconfigs.HTTPFirewallOutboundConfig{
IsOn: true,
}
}
policy.Outbound.Groups = newOutboundGroups
policy.Outbound.GroupRefs = nil
configJSON, err := json.Marshal(policy)
if err != nil {
this.ErrorPage(err)
return
}
key := "waf." + rands.HexString(32)
ttlcache.DefaultCache.Write(key, configJSON, time.Now().Unix()+600)
this.Data["key"] = key
this.Success()
}

View File

@@ -0,0 +1,37 @@
package waf
import (
"github.com/TeaOSLab/EdgeUser/internal/ttlcache"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"strconv"
)
type ExportDownloadAction struct {
actionutils.ParentAction
}
func (this *ExportDownloadAction) Init() {
this.Nav("", "", "")
}
func (this *ExportDownloadAction) RunGet(params struct {
Key string
}) {
item := ttlcache.DefaultCache.Read(params.Key)
if item == nil || item.Value == nil {
this.WriteString("找不到要导出的内容")
return
}
ttlcache.DefaultCache.Delete(params.Key)
data, ok := item.Value.([]byte)
if ok {
this.AddHeader("Content-Disposition", "attachment; filename=\"WAF.json\";")
this.AddHeader("Content-Length", strconv.Itoa(len(data)))
_, _ = this.Write(data)
} else {
this.WriteString("找不到要导出的内容")
return
}
}

View File

@@ -0,0 +1,76 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"strings"
)
type GroupAction struct {
actionutils.ParentAction
}
func (this *GroupAction) Init() {
this.Nav("", "", this.ParamString("type"))
}
func (this *GroupAction) RunGet(params struct {
FirewallPolicyId int64
GroupId int64
Type string
}) {
this.Data["type"] = params.Type
// policy
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
// group config
groupConfig, err := dao.SharedHTTPFirewallRuleGroupDAO.FindRuleGroupConfig(this.UserContext(), params.GroupId)
if err != nil {
this.ErrorPage(err)
return
}
if groupConfig == nil {
this.NotFound("firewallRuleGroup", params.GroupId)
return
}
this.Data["group"] = groupConfig
// rule sets
this.Data["sets"] = lists.Map(groupConfig.Sets, func(k int, v interface{}) interface{} {
var set = v.(*firewallconfigs.HTTPFirewallRuleSet)
return maps.Map{
"id": set.Id,
"name": set.Name,
"rules": lists.Map(set.Rules, func(k int, v interface{}) interface{} {
var rule = v.(*firewallconfigs.HTTPFirewallRule)
return maps.Map{
"param": rule.Param,
"paramFilters": rule.ParamFilters,
"operator": rule.Operator,
"value": rule.Value,
"isCaseInsensitive": rule.IsCaseInsensitive,
"isComposed": firewallconfigs.CheckCheckpointIsComposed(rule.Prefix()),
"checkpointOptions": rule.CheckpointOptions,
}
}),
"isOn": set.IsOn,
"actions": set.Actions,
"connector": strings.ToUpper(set.Connector),
}
})
this.Show()
}

View File

@@ -0,0 +1,72 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type GroupsAction struct {
actionutils.ParentAction
}
func (this *GroupsAction) Init() {
this.Nav("", "", this.ParamString("type"))
}
func (this *GroupsAction) RunGet(params struct {
FirewallPolicyId int64
Type string
}) {
this.Data["type"] = params.Type
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
groupMaps := []maps.Map{}
// inbound
if params.Type == "inbound" {
if firewallPolicy.Inbound != nil {
for _, g := range firewallPolicy.Inbound.Groups {
groupMaps = append(groupMaps, maps.Map{
"id": g.Id,
"name": g.Name,
"code": g.Code,
"isOn": g.IsOn,
"description": g.Description,
"countSets": len(g.Sets),
"canDelete": len(g.Code) == 0,
})
}
}
}
// outbound
if params.Type == "outbound" {
if firewallPolicy.Outbound != nil {
for _, g := range firewallPolicy.Outbound.Groups {
groupMaps = append(groupMaps, maps.Map{
"id": g.Id,
"name": g.Name,
"code": g.Code,
"isOn": g.IsOn,
"description": g.Description,
"countSets": len(g.Sets),
"canDelete": len(g.Code) == 0,
})
}
}
}
this.Data["groups"] = groupMaps
this.Show()
}

View File

@@ -0,0 +1,71 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"net/http"
)
type Helper struct {
}
func NewHelper() *Helper {
return &Helper{}
}
func (this *Helper) BeforeAction(actionPtr actions.ActionWrapper) (goNext bool) {
action := actionPtr.Object()
if action.Request.Method != http.MethodGet {
return true
}
action.Data["mainTab"] = "component"
action.Data["secondMenuItem"] = "waf"
// 显示当前的防火墙名称
firewallPolicyId := action.ParamInt64("firewallPolicyId")
if firewallPolicyId > 0 {
action.Data["firewallPolicyId"] = firewallPolicyId
action.Data["countInboundGroups"] = 0
action.Data["countOutboundGroups"] = 0
parentAction := actionutils.FindParentAction(actionPtr)
if parentAction != nil {
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicy(parentAction.UserContext(), firewallPolicyId)
if err != nil {
parentAction.ErrorPage(err)
return
}
if firewallPolicy == nil {
action.WriteString("can not find firewall policy")
return
}
action.Data["firewallPolicyName"] = firewallPolicy.Name
// inbound
if len(firewallPolicy.InboundJSON) > 0 {
inboundConfig := &firewallconfigs.HTTPFirewallInboundConfig{}
err = json.Unmarshal(firewallPolicy.InboundJSON, inboundConfig)
if err != nil {
parentAction.ErrorPage(err)
return
}
action.Data["countInboundGroups"] = len(inboundConfig.GroupRefs)
}
// outbound
if len(firewallPolicy.OutboundJSON) > 0 {
outboundConfig := &firewallconfigs.HTTPFirewallOutboundConfig{}
err = json.Unmarshal(firewallPolicy.OutboundJSON, outboundConfig)
if err != nil {
parentAction.ErrorPage(err)
return
}
action.Data["countOutboundGroups"] = len(outboundConfig.GroupRefs)
}
}
}
return true
}

View File

@@ -0,0 +1,60 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
)
type ImportAction struct {
actionutils.ParentAction
}
func (this *ImportAction) Init() {
this.Nav("", "", "import")
}
func (this *ImportAction) RunGet(params struct{}) {
this.Show()
}
func (this *ImportAction) RunPost(params struct {
FirewallPolicyId int64
File *actions.File
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo(codes.WAFPolicy_LogImportWAFPolicy, params.FirewallPolicyId)
if params.File == nil {
this.Fail("请上传要导入的文件")
}
if params.File.Ext != ".json" {
this.Fail("规则文件的扩展名只能是.json")
}
data, err := params.File.Read()
if err != nil {
this.Fail("读取文件时发生错误:" + err.Error())
}
config := &firewallconfigs.HTTPFirewallPolicy{}
err = json.Unmarshal(data, config)
if err != nil {
this.Fail("解析文件时发生错误:" + err.Error())
}
_, err = this.RPC().HTTPFirewallPolicyRPC().ImportHTTPFirewallPolicy(this.UserContext(), &pb.ImportHTTPFirewallPolicyRequest{
HttpFirewallPolicyId: params.FirewallPolicyId,
HttpFirewallPolicyJSON: data,
})
if err != nil {
this.Fail("导入失败:" + err.Error())
}
this.Success()
}

View File

@@ -0,0 +1,81 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.FirstMenu("index")
}
func (this *IndexAction) RunGet(params struct{}) {
countResp, err := this.RPC().HTTPFirewallPolicyRPC().CountAllEnabledHTTPFirewallPolicies(this.UserContext(), &pb.CountAllEnabledHTTPFirewallPoliciesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count)
listResp, err := this.RPC().HTTPFirewallPolicyRPC().ListEnabledHTTPFirewallPolicies(this.UserContext(), &pb.ListEnabledHTTPFirewallPoliciesRequest{
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
policyMaps := []maps.Map{}
for _, policy := range listResp.HttpFirewallPolicies {
countInbound := 0
countOutbound := 0
if len(policy.InboundJSON) > 0 {
inboundConfig := &firewallconfigs.HTTPFirewallInboundConfig{}
err = json.Unmarshal(policy.InboundJSON, inboundConfig)
if err != nil {
this.ErrorPage(err)
return
}
countInbound = len(inboundConfig.GroupRefs)
}
if len(policy.OutboundJSON) > 0 {
outboundConfig := &firewallconfigs.HTTPFirewallInboundConfig{}
err = json.Unmarshal(policy.OutboundJSON, outboundConfig)
if err != nil {
this.ErrorPage(err)
return
}
countOutbound = len(outboundConfig.GroupRefs)
}
countClustersResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClustersWithHTTPFirewallPolicyId(this.UserContext(), &pb.CountAllEnabledNodeClustersWithHTTPFirewallPolicyIdRequest{HttpFirewallPolicyId: policy.Id})
if err != nil {
this.ErrorPage(err)
return
}
countClusters := countClustersResp.Count
policyMaps = append(policyMaps, maps.Map{
"id": policy.Id,
"isOn": policy.IsOn,
"name": policy.Name,
"countInbound": countInbound,
"countOutbound": countOutbound,
"countClusters": countClusters,
})
}
this.Data["policies"] = policyMaps
this.Data["page"] = page.AsHTML()
this.Show()
}

View File

@@ -0,0 +1,44 @@
package waf
import (
"github.com/TeaOSLab/EdgeUser/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth("")).
Helper(NewHelper()).
Data("teaMenu", "servers").
Data("teaSubMenu", "waf").
Prefix("/servers/components/waf").
Get("", new(IndexAction)).
GetPost("/createPopup", new(CreatePopupAction)).
Post("/delete", new(DeleteAction)).
Get("/policy", new(PolicyAction)).
Get("/groups", new(GroupsAction)).
Get("/group", new(GroupAction)).
Get("/log", new(LogAction)).
GetPost("/update", new(UpdateAction)).
GetPost("/test", new(TestAction)).
GetPost("/export", new(ExportAction)).
Get("/exportDownload", new(ExportDownloadAction)).
GetPost("/import", new(ImportAction)).
Post("/updateGroupOn", new(UpdateGroupOnAction)).
Post("/deleteGroup", new(DeleteGroupAction)).
GetPost("/createGroupPopup", new(CreateGroupPopupAction)).
Post("/sortGroups", new(SortGroupsAction)).
GetPost("/updateGroupPopup", new(UpdateGroupPopupAction)).
GetPost("/createSetPopup", new(CreateSetPopupAction)).
GetPost("/createRulePopup", new(CreateRulePopupAction)).
Post("/sortSets", new(SortSetsAction)).
Post("/updateSetOn", new(UpdateSetOnAction)).
Post("/deleteSet", new(DeleteSetAction)).
GetPost("/updateSetPopup", new(UpdateSetPopupAction)).
Post("/count", new(CountAction)).
Get("/selectPopup", new(SelectPopupAction)).
Post("/testRegexp", new(TestRegexpAction)).
EndAll()
})
}

View File

@@ -0,0 +1,113 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
"regexp"
"strings"
)
type LogAction struct {
actionutils.ParentAction
}
func (this *LogAction) Init() {
this.Nav("", "", "log")
}
func (this *LogAction) RunGet(params struct {
Day string
RequestId string
FirewallPolicyId int64
GroupId int64
Partition int32 `default:"-1"`
}) {
if len(params.Day) == 0 {
params.Day = timeutil.Format("Y-m-d")
}
this.Data["path"] = this.Request.URL.Path
this.Data["day"] = params.Day
this.Data["groupId"] = params.GroupId
this.Data["accessLogs"] = []interface{}{}
day := params.Day
if len(day) > 0 && regexp.MustCompile(`\d{4}-\d{2}-\d{2}`).MatchString(day) {
day = strings.ReplaceAll(day, "-", "")
size := int64(10)
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.UserContext(), &pb.ListHTTPAccessLogsRequest{
Partition: params.Partition,
RequestId: params.RequestId,
FirewallPolicyId: params.FirewallPolicyId,
FirewallRuleGroupId: params.GroupId,
Day: day,
Size: size,
})
if err != nil {
this.ErrorPage(err)
return
}
if len(resp.HttpAccessLogs) == 0 {
this.Data["accessLogs"] = []interface{}{}
} else {
this.Data["accessLogs"] = resp.HttpAccessLogs
}
this.Data["hasMore"] = resp.HasMore
this.Data["nextRequestId"] = resp.RequestId
// 上一个requestId
this.Data["hasPrev"] = false
this.Data["lastRequestId"] = ""
if len(params.RequestId) > 0 {
this.Data["hasPrev"] = true
prevResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.UserContext(), &pb.ListHTTPAccessLogsRequest{
Partition: params.Partition,
RequestId: params.RequestId,
FirewallPolicyId: params.FirewallPolicyId,
FirewallRuleGroupId: params.GroupId,
Day: day,
Size: size,
Reverse: true,
})
if err != nil {
this.ErrorPage(err)
return
}
if int64(len(prevResp.HttpAccessLogs)) == size {
this.Data["lastRequestId"] = prevResp.RequestId
}
}
}
// 所有分组
policyResp, err := this.RPC().HTTPFirewallPolicyRPC().FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), &pb.FindEnabledHTTPFirewallPolicyConfigRequest{
HttpFirewallPolicyId: params.FirewallPolicyId,
})
if err != nil {
this.ErrorPage(err)
return
}
policyConfig := &firewallconfigs.HTTPFirewallPolicy{}
err = json.Unmarshal(policyResp.HttpFirewallPolicyJSON, policyConfig)
if err != nil {
this.ErrorPage(err)
return
}
groupMaps := []maps.Map{}
for _, group := range policyConfig.AllRuleGroups() {
groupMaps = append(groupMaps, maps.Map{
"id": group.Id,
"name": group.Name,
})
}
this.Data["groups"] = groupMaps
this.Show()
}

View File

@@ -0,0 +1,74 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type PolicyAction struct {
actionutils.ParentAction
}
func (this *PolicyAction) Init() {
this.Nav("", "", "index")
}
func (this *PolicyAction) RunGet(params struct {
FirewallPolicyId int64
}) {
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
internalGroups := []maps.Map{}
if firewallPolicy.Inbound != nil {
for _, group := range firewallPolicy.Inbound.Groups {
internalGroups = append(internalGroups, maps.Map{
"name": group.Name,
"isOn": group.IsOn,
})
}
}
if firewallPolicy.Outbound != nil {
for _, group := range firewallPolicy.Outbound.Groups {
internalGroups = append(internalGroups, maps.Map{
"name": group.Name,
"isOn": group.IsOn,
})
}
}
this.Data["firewallPolicy"] = maps.Map{
"id": firewallPolicy.Id,
"name": firewallPolicy.Name,
"isOn": firewallPolicy.IsOn,
"description": firewallPolicy.Description,
"groups": internalGroups,
"blockOptions": firewallPolicy.BlockOptions,
}
// 正在使用此策略的集群
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPFirewallPolicyId(this.UserContext(), &pb.FindAllEnabledNodeClustersWithHTTPFirewallPolicyIdRequest{HttpFirewallPolicyId: params.FirewallPolicyId})
if err != nil {
this.ErrorPage(err)
return
}
clusterMaps := []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}

View File

@@ -0,0 +1,73 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type SelectPopupAction struct {
actionutils.ParentAction
}
func (this *SelectPopupAction) Init() {
this.FirstMenu("index")
}
func (this *SelectPopupAction) RunGet(params struct{}) {
countResp, err := this.RPC().HTTPFirewallPolicyRPC().CountAllEnabledHTTPFirewallPolicies(this.UserContext(), &pb.CountAllEnabledHTTPFirewallPoliciesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count)
listResp, err := this.RPC().HTTPFirewallPolicyRPC().ListEnabledHTTPFirewallPolicies(this.UserContext(), &pb.ListEnabledHTTPFirewallPoliciesRequest{
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
policyMaps := []maps.Map{}
for _, policy := range listResp.HttpFirewallPolicies {
countInbound := 0
countOutbound := 0
if len(policy.InboundJSON) > 0 {
inboundConfig := &firewallconfigs.HTTPFirewallInboundConfig{}
err = json.Unmarshal(policy.InboundJSON, inboundConfig)
if err != nil {
this.ErrorPage(err)
return
}
countInbound = len(inboundConfig.GroupRefs)
}
if len(policy.OutboundJSON) > 0 {
outboundConfig := &firewallconfigs.HTTPFirewallInboundConfig{}
err = json.Unmarshal(policy.OutboundJSON, outboundConfig)
if err != nil {
this.ErrorPage(err)
return
}
countOutbound = len(outboundConfig.GroupRefs)
}
policyMaps = append(policyMaps, maps.Map{
"id": policy.Id,
"isOn": policy.IsOn,
"name": policy.Name,
"countInbound": countInbound,
"countOutbound": countOutbound,
})
}
this.Data["policies"] = policyMaps
this.Data["page"] = page.AsHTML()
this.Show()
}

View File

@@ -0,0 +1,86 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type SortGroupsAction struct {
actionutils.ParentAction
}
func (this *SortGroupsAction) RunPost(params struct {
FirewallPolicyId int64
Type string
GroupIds []int64
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleGroup_LogSortRuleGroups, params.FirewallPolicyId)
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
switch params.Type {
case "inbound":
refMapping := map[int64]*firewallconfigs.HTTPFirewallRuleGroupRef{}
for _, ref := range firewallPolicy.Inbound.GroupRefs {
refMapping[ref.GroupId] = ref
}
newRefs := []*firewallconfigs.HTTPFirewallRuleGroupRef{}
for _, groupId := range params.GroupIds {
ref, ok := refMapping[groupId]
if ok {
newRefs = append(newRefs, ref)
}
}
firewallPolicy.Inbound.GroupRefs = newRefs
case "outbound":
refMapping := map[int64]*firewallconfigs.HTTPFirewallRuleGroupRef{}
for _, ref := range firewallPolicy.Outbound.GroupRefs {
refMapping[ref.GroupId] = ref
}
newRefs := []*firewallconfigs.HTTPFirewallRuleGroupRef{}
for _, groupId := range params.GroupIds {
ref, ok := refMapping[groupId]
if ok {
newRefs = append(newRefs, ref)
}
}
firewallPolicy.Outbound.GroupRefs = newRefs
}
inboundJSON, err := firewallPolicy.InboundJSON()
if err != nil {
this.ErrorPage(err)
return
}
outboundJSON, err := firewallPolicy.OutboundJSON()
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallPolicyRPC().UpdateHTTPFirewallPolicyGroups(this.UserContext(), &pb.UpdateHTTPFirewallPolicyGroupsRequest{
HttpFirewallPolicyId: params.FirewallPolicyId,
InboundJSON: inboundJSON,
OutboundJSON: outboundJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,61 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type SortSetsAction struct {
actionutils.ParentAction
}
func (this *SortSetsAction) RunPost(params struct {
GroupId int64
SetIds []int64
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleSet_LogSortRuleSets, params.GroupId)
groupConfig, err := dao.SharedHTTPFirewallRuleGroupDAO.FindRuleGroupConfig(this.UserContext(), params.GroupId)
if err != nil {
this.ErrorPage(err)
return
}
if groupConfig == nil {
this.NotFound("firewallRuleGroup", params.GroupId)
return
}
setMap := map[int64]*firewallconfigs.HTTPFirewallRuleSetRef{}
for _, setRef := range groupConfig.SetRefs {
setMap[setRef.SetId] = setRef
}
newRefs := []*firewallconfigs.HTTPFirewallRuleSetRef{}
for _, setId := range params.SetIds {
ref, ok := setMap[setId]
if ok {
newRefs = append(newRefs, ref)
}
}
newRefsJSON, err := json.Marshal(newRefs)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallRuleGroupRPC().UpdateHTTPFirewallRuleGroupSets(this.UserContext(), &pb.UpdateHTTPFirewallRuleGroupSetsRequest{
FirewallRuleGroupId: params.GroupId,
FirewallRuleSetsJSON: newRefsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,15 @@
package waf
import "github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
type TestAction struct {
actionutils.ParentAction
}
func (this *TestAction) Init() {
this.Nav("", "", "test")
}
func (this *TestAction) RunGet(params struct{}) {
this.Show()
}

View File

@@ -0,0 +1,48 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package waf
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
"regexp"
"strings"
)
type TestRegexpAction struct {
actionutils.ParentAction
}
func (this *TestRegexpAction) RunPost(params struct {
Regexp string
IsCaseInsensitive bool
Body string
}) {
var exp = params.Regexp
if params.IsCaseInsensitive && !strings.HasPrefix(params.Regexp, "(?i)") {
exp = "(?i)" + exp
}
reg, err := regexp.Compile(exp)
if err != nil {
this.Data["result"] = maps.Map{
"isOk": false,
"message": "解析正则出错:" + err.Error(),
}
this.Success()
}
if reg.MatchString(params.Body) {
this.Data["result"] = maps.Map{
"isOk": true,
"message": "匹配成功",
}
this.Success()
}
this.Data["result"] = maps.Map{
"isOk": false,
"message": "匹配失败",
}
this.Success()
}

View File

@@ -0,0 +1,104 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
"net/http"
)
type UpdateAction struct {
actionutils.ParentAction
}
func (this *UpdateAction) Init() {
this.Nav("", "", "update")
}
func (this *UpdateAction) RunGet(params struct {
FirewallPolicyId int64
}) {
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
if firewallPolicy.BlockOptions == nil {
firewallPolicy.BlockOptions = &firewallconfigs.HTTPFirewallBlockAction{
StatusCode: http.StatusForbidden,
Body: "Blocked By WAF",
URL: "",
}
}
this.Data["firewallPolicy"] = maps.Map{
"id": firewallPolicy.Id,
"name": firewallPolicy.Name,
"description": firewallPolicy.Description,
"isOn": firewallPolicy.IsOn,
"blockOptions": firewallPolicy.BlockOptions,
}
// 预置分组
groups := []maps.Map{}
templatePolicy := firewallconfigs.HTTPFirewallTemplate()
for _, group := range templatePolicy.AllRuleGroups() {
if len(group.Code) > 0 {
usedGroup := firewallPolicy.FindRuleGroupWithCode(group.Code)
if usedGroup != nil {
group.IsOn = usedGroup.IsOn
}
}
groups = append(groups, maps.Map{
"code": group.Code,
"name": group.Name,
"isOn": group.IsOn,
})
}
this.Data["groups"] = groups
this.Show()
}
func (this *UpdateAction) RunPost(params struct {
FirewallPolicyId int64
Name string
GroupCodes []string
BlockOptionsJSON []byte
Description string
IsOn bool
Must *actions.Must
}) {
// 日志
defer this.CreateLogInfo(codes.WAFPolicy_LogUpdateWAFPolicy, params.FirewallPolicyId)
params.Must.
Field("name", params.Name).
Require("请输入策略名称")
_, err := this.RPC().HTTPFirewallPolicyRPC().UpdateHTTPFirewallPolicy(this.UserContext(), &pb.UpdateHTTPFirewallPolicyRequest{
HttpFirewallPolicyId: params.FirewallPolicyId,
IsOn: params.IsOn,
Name: params.Name,
Description: params.Description,
FirewallGroupCodes: params.GroupCodes,
BlockOptionsJSON: params.BlockOptionsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,30 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type UpdateGroupOnAction struct {
actionutils.ParentAction
}
func (this *UpdateGroupOnAction) RunPost(params struct {
GroupId int64
IsOn bool
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleGroup_LogUpdateRuleGroupIsOn, params.GroupId)
_, err := this.RPC().HTTPFirewallRuleGroupRPC().UpdateHTTPFirewallRuleGroupIsOn(this.UserContext(), &pb.UpdateHTTPFirewallRuleGroupIsOnRequest{
FirewallRuleGroupId: params.GroupId,
IsOn: params.IsOn,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,70 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
)
type UpdateGroupPopupAction struct {
actionutils.ParentAction
}
func (this *UpdateGroupPopupAction) Init() {
this.Nav("", "", "")
}
func (this *UpdateGroupPopupAction) RunGet(params struct {
GroupId int64
}) {
groupConfig, err := dao.SharedHTTPFirewallRuleGroupDAO.FindRuleGroupConfig(this.UserContext(), params.GroupId)
if err != nil {
this.ErrorPage(err)
return
}
if groupConfig == nil {
this.NotFound("ruleGroup", params.GroupId)
return
}
this.Data["group"] = maps.Map{
"id": groupConfig.Id,
"name": groupConfig.Name,
"description": groupConfig.Description,
"isOn": groupConfig.IsOn,
}
this.Show()
}
func (this *UpdateGroupPopupAction) RunPost(params struct {
GroupId int64
Name string
Description string
IsOn bool
Must *actions.Must
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleGroup_LogUpdateRuleGroup, params.GroupId)
params.Must.
Field("name", params.Name).
Require("请输入分组名称")
_, err := this.RPC().HTTPFirewallRuleGroupRPC().UpdateHTTPFirewallRuleGroup(this.UserContext(), &pb.UpdateHTTPFirewallRuleGroupRequest{
FirewallRuleGroupId: params.GroupId,
IsOn: params.IsOn,
Name: params.Name,
Description: params.Description,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,30 @@
package waf
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
type UpdateSetOnAction struct {
actionutils.ParentAction
}
func (this *UpdateSetOnAction) RunPost(params struct {
SetId int64
IsOn bool
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleSet_LogUpdateRuleSetIsOn, params.SetId)
_, err := this.RPC().HTTPFirewallRuleSetRPC().UpdateHTTPFirewallRuleSetIsOn(this.UserContext(), &pb.UpdateHTTPFirewallRuleSetIsOnRequest{
FirewallRuleSetId: params.SetId,
IsOn: params.IsOn,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,171 @@
package waf
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
)
type UpdateSetPopupAction struct {
actionutils.ParentAction
}
func (this *UpdateSetPopupAction) Init() {
this.Nav("", "", "")
}
func (this *UpdateSetPopupAction) RunGet(params struct {
FirewallPolicyId int64
GroupId int64
Type string
SetId int64
}) {
// 日志
defer this.CreateLogInfo(codes.WAFRuleSet_LogUpdateRuleSet, params.SetId)
this.Data["groupId"] = params.GroupId
this.Data["type"] = params.Type
firewallPolicy, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledHTTPFirewallPolicyConfig(this.UserContext(), params.FirewallPolicyId)
if err != nil {
this.ErrorPage(err)
return
}
if firewallPolicy == nil {
this.NotFound("firewallPolicy", params.FirewallPolicyId)
return
}
this.Data["firewallPolicy"] = firewallPolicy
// 一些配置
this.Data["connectors"] = []maps.Map{
{
"name": "和(AND)",
"value": firewallconfigs.HTTPFirewallRuleConnectorAnd,
"description": "所有规则都满足才视为匹配",
},
{
"name": "或(OR)",
"value": firewallconfigs.HTTPFirewallRuleConnectorOr,
"description": "任一规则满足了就视为匹配",
},
}
actionMaps := []maps.Map{}
for _, action := range firewallconfigs.AllActions {
// 用户端暂时屏蔽notify等动作
if action.Code == firewallconfigs.HTTPFirewallActionNotify || action.Code == firewallconfigs.HTTPFirewallActionRecordIP {
continue
}
actionMaps = append(actionMaps, maps.Map{
"name": action.Name,
"description": action.Description,
"code": action.Code,
})
}
this.Data["actions"] = actionMaps
// 规则集信息
setConfig, err := dao.SharedHTTPFirewallRuleSetDAO.FindRuleSetConfig(this.UserContext(), params.SetId)
if err != nil {
this.ErrorPage(err)
return
}
if setConfig == nil {
this.NotFound("firewallRuleSet", params.SetId)
return
}
this.Data["setConfig"] = setConfig
// action configs
actionConfigs, err := dao.SharedHTTPFirewallPolicyDAO.FindHTTPFirewallActionConfigs(this.UserContext(), setConfig.Actions)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["actionConfigs"] = actionConfigs
this.Show()
}
func (this *UpdateSetPopupAction) RunPost(params struct {
GroupId int64
SetId int64
Name string
RulesJSON []byte
Connector string
ActionsJSON []byte
IgnoreLocal bool
IgnoreSearchEngine bool
Must *actions.Must
}) {
// 规则集信息
setConfig, err := dao.SharedHTTPFirewallRuleSetDAO.FindRuleSetConfig(this.UserContext(), params.SetId)
if err != nil {
this.ErrorPage(err)
return
}
if setConfig == nil {
this.NotFound("firewallRuleSet", params.SetId)
return
}
params.Must.
Field("name", params.Name).
Require("请输入规则集名称")
if len(params.RulesJSON) == 0 {
this.Fail("请添加至少一个规则")
return
}
var rules = []*firewallconfigs.HTTPFirewallRule{}
err = json.Unmarshal(params.RulesJSON, &rules)
if err != nil {
this.ErrorPage(err)
return
}
if len(rules) == 0 {
this.Fail("请添加至少一个规则")
return
}
var actionConfigs = []*firewallconfigs.HTTPFirewallActionConfig{}
if len(params.ActionsJSON) > 0 {
err = json.Unmarshal(params.ActionsJSON, &actionConfigs)
if err != nil {
this.ErrorPage(err)
return
}
}
if len(actionConfigs) == 0 {
this.Fail("请添加至少一个动作")
}
setConfig.Name = params.Name
setConfig.Connector = params.Connector
setConfig.Rules = rules
setConfig.Actions = actionConfigs
setConfig.IgnoreLocal = params.IgnoreLocal
setConfig.IgnoreSearchEngine = params.IgnoreSearchEngine
setConfigJSON, err := json.Marshal(setConfig)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPFirewallRuleSetRPC().CreateOrUpdateHTTPFirewallRuleSetFromConfig(this.UserContext(), &pb.CreateOrUpdateHTTPFirewallRuleSetFromConfigRequest{FirewallRuleSetConfigJSON: setConfigJSON})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}