diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index 5d3561a1..6bf66aae 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -127,6 +127,10 @@ func (this *RPCClient) HTTPFirewallPolicyRPC() pb.HTTPFirewallPolicyServiceClien return pb.NewHTTPFirewallPolicyServiceClient(this.pickConn()) } +func (this *RPCClient) HTTPFirewallRuleGroupRPC() pb.HTTPFirewallRuleGroupServiceClient { + return pb.NewHTTPFirewallRuleGroupServiceClient(this.pickConn()) +} + func (this *RPCClient) HTTPLocationRPC() pb.HTTPLocationServiceClient { return pb.NewHTTPLocationServiceClient(this.pickConn()) } diff --git a/internal/web/actions/default/servers/components/waf/createGroupPopup.go b/internal/web/actions/default/servers/components/waf/createGroupPopup.go new file mode 100644 index 00000000..9f292205 --- /dev/null +++ b/internal/web/actions/default/servers/components/waf/createGroupPopup.go @@ -0,0 +1,98 @@ +package waf + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/models" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" + "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 := models.SharedHTTPFirewallPolicyDAO.FindEnabledPolicyConfig(this.AdminContext(), 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.AdminContext(), &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.AdminContext(), &pb.UpdateHTTPFirewallPolicyGroupsRequest{ + FirewallPolicyId: params.FirewallPolicyId, + InboundJSON: inboundJSON, + OutboundJSON: outboundJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/components/waf/deleteGroup.go b/internal/web/actions/default/servers/components/waf/deleteGroup.go new file mode 100644 index 00000000..f02bbb0c --- /dev/null +++ b/internal/web/actions/default/servers/components/waf/deleteGroup.go @@ -0,0 +1,52 @@ +package waf + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/models" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +type DeleteGroupAction struct { + actionutils.ParentAction +} + +func (this *DeleteGroupAction) RunPost(params struct { + FirewallPolicyId int64 + GroupId int64 +}) { + firewallPolicy, err := models.SharedHTTPFirewallPolicyDAO.FindEnabledPolicyConfig(this.AdminContext(), 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.AdminContext(), &pb.UpdateHTTPFirewallPolicyGroupsRequest{ + FirewallPolicyId: params.FirewallPolicyId, + InboundJSON: inboundJSON, + OutboundJSON: outboundJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/components/waf/export.go b/internal/web/actions/default/servers/components/waf/export.go index 4850c0fb..443dca9b 100644 --- a/internal/web/actions/default/servers/components/waf/export.go +++ b/internal/web/actions/default/servers/components/waf/export.go @@ -7,7 +7,7 @@ type ExportAction struct { } func (this *ExportAction) Init() { - this.Nav("", "", "") + this.Nav("", "", "export") } func (this *ExportAction) RunGet(params struct{}) { diff --git a/internal/web/actions/default/servers/components/waf/groups.go b/internal/web/actions/default/servers/components/waf/groups.go index d93a82c8..2bbf46ef 100644 --- a/internal/web/actions/default/servers/components/waf/groups.go +++ b/internal/web/actions/default/servers/components/waf/groups.go @@ -1,15 +1,72 @@ package waf -import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/models" + "github.com/iwind/TeaGo/maps" +) type GroupsAction struct { actionutils.ParentAction } func (this *GroupsAction) Init() { - this.Nav("", "", "") + this.Nav("", "", this.ParamString("type")) } -func (this *GroupsAction) RunGet(params struct{}) { +func (this *GroupsAction) RunGet(params struct { + FirewallPolicyId int64 + Type string +}) { + this.Data["type"] = params.Type + + firewallPolicy, err := models.SharedHTTPFirewallPolicyDAO.FindEnabledPolicyConfig(this.AdminContext(), 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() } diff --git a/internal/web/actions/default/servers/components/waf/import.go b/internal/web/actions/default/servers/components/waf/import.go index 16f9cd62..284519e5 100644 --- a/internal/web/actions/default/servers/components/waf/import.go +++ b/internal/web/actions/default/servers/components/waf/import.go @@ -7,7 +7,7 @@ type ImportAction struct { } func (this *ImportAction) Init() { - this.Nav("", "", "") + this.Nav("", "", "import") } func (this *ImportAction) RunGet(params struct{}) { diff --git a/internal/web/actions/default/servers/components/waf/init.go b/internal/web/actions/default/servers/components/waf/init.go index 10cb0772..b404a531 100644 --- a/internal/web/actions/default/servers/components/waf/init.go +++ b/internal/web/actions/default/servers/components/waf/init.go @@ -24,6 +24,11 @@ func init() { GetPost("/test", new(TestAction)). GetPost("/export", new(ExportAction)). GetPost("/import", new(ImportAction)). + Post("/updateGroupOn", new(UpdateGroupOnAction)). + Post("/deleteGroup", new(DeleteGroupAction)). + GetPost("/ipadmin", new(IpadminAction)). + GetPost("/createGroupPopup", new(CreateGroupPopupAction)). + Post("/sortGroups", new(SortGroupsAction)). EndAll() }) } diff --git a/internal/web/actions/default/servers/components/waf/ipadmin.go b/internal/web/actions/default/servers/components/waf/ipadmin.go new file mode 100644 index 00000000..9a79e2b9 --- /dev/null +++ b/internal/web/actions/default/servers/components/waf/ipadmin.go @@ -0,0 +1,15 @@ +package waf + +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + +type IpadminAction struct { + actionutils.ParentAction +} + +func (this *IpadminAction) Init() { + this.Nav("", "", "ipadmin") +} + +func (this *IpadminAction) RunGet(params struct{}) { + this.Show() +} diff --git a/internal/web/actions/default/servers/components/waf/log.go b/internal/web/actions/default/servers/components/waf/log.go index a4203c1d..409c0614 100644 --- a/internal/web/actions/default/servers/components/waf/log.go +++ b/internal/web/actions/default/servers/components/waf/log.go @@ -7,7 +7,7 @@ type LogAction struct { } func (this *LogAction) Init() { - this.Nav("", "", "") + this.Nav("", "", "log") } func (this *LogAction) RunGet(params struct{}) { diff --git a/internal/web/actions/default/servers/components/waf/sortGroups.go b/internal/web/actions/default/servers/components/waf/sortGroups.go new file mode 100644 index 00000000..16f2f40a --- /dev/null +++ b/internal/web/actions/default/servers/components/waf/sortGroups.go @@ -0,0 +1,82 @@ +package waf + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/models" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" +) + +type SortGroupsAction struct { + actionutils.ParentAction +} + +func (this *SortGroupsAction) RunPost(params struct { + FirewallPolicyId int64 + Type string + GroupIds []int64 +}) { + firewallPolicy, err := models.SharedHTTPFirewallPolicyDAO.FindEnabledPolicyConfig(this.AdminContext(), 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.AdminContext(), &pb.UpdateHTTPFirewallPolicyGroupsRequest{ + FirewallPolicyId: params.FirewallPolicyId, + InboundJSON: inboundJSON, + OutboundJSON: outboundJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/components/waf/test.go b/internal/web/actions/default/servers/components/waf/test.go index 9f8634bd..84a330a0 100644 --- a/internal/web/actions/default/servers/components/waf/test.go +++ b/internal/web/actions/default/servers/components/waf/test.go @@ -7,7 +7,7 @@ type TestAction struct { } func (this *TestAction) Init() { - this.Nav("", "", "") + this.Nav("", "", "test") } func (this *TestAction) RunGet(params struct{}) { diff --git a/internal/web/actions/default/servers/components/waf/updateGroupOn.go b/internal/web/actions/default/servers/components/waf/updateGroupOn.go new file mode 100644 index 00000000..f4a13b6c --- /dev/null +++ b/internal/web/actions/default/servers/components/waf/updateGroupOn.go @@ -0,0 +1,26 @@ +package waf + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +type UpdateGroupOnAction struct { + actionutils.ParentAction +} + +func (this *UpdateGroupOnAction) RunPost(params struct { + GroupId int64 + IsOn bool +}) { + _, err := this.RPC().HTTPFirewallRuleGroupRPC().UpdateHTTPFirewallRuleGroupIsOn(this.AdminContext(), &pb.UpdateHTTPFirewallRuleGroupIsOnRequest{ + FirewallRuleGroupId: params.GroupId, + IsOn: params.IsOn, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/web/public/js/utils.js b/web/public/js/utils.js index 98392413..1e53f7f8 100644 --- a/web/public/js/utils.js +++ b/web/public/js/utils.js @@ -158,6 +158,22 @@ window.teaweb = { } }); }, + successToast: function (message, timeout) { + if (timeout == null) { + timeout = 2000 + } + var width = "20em"; + if (message.length > 30) { + width = "30em"; + } + Swal.fire({ + text: message, + icon: "success", + width: width, + timer: timeout, + showConfirmButton: false + }); + }, warn: function (message, callback) { var width = "20em"; if (message.length > 30) { diff --git a/web/views/@default/servers/components/waf/@waf_menu.html b/web/views/@default/servers/components/waf/@waf_menu.html index 1ffb574c..c511c75a 100644 --- a/web/views/@default/servers/components/waf/@waf_menu.html +++ b/web/views/@default/servers/components/waf/@waf_menu.html @@ -2,8 +2,8 @@ 列表 | {{firewallPolicyName}} - 入站规则集({{countInboundGroups}}) - 出站规则集({{countOutboundGroups}}) + 入站规则({{countInboundGroups}}) + 出站规则({{countOutboundGroups}}) IP管理 拦截日志 测试 diff --git a/web/views/@default/servers/components/waf/createGroupPopup.html b/web/views/@default/servers/components/waf/createGroupPopup.html new file mode 100644 index 00000000..31a16c76 --- /dev/null +++ b/web/views/@default/servers/components/waf/createGroupPopup.html @@ -0,0 +1,39 @@ +{$layout "layout_popup"} + +

添加分组

+ +
+ + + + + + + + + + + + + + + + + + + + +
分组名称 * + +

给分组起一个容易识别的名称

+
分组描述 + +
是否启用 +
+ + +
+
+ + +
\ No newline at end of file diff --git a/web/views/@default/servers/components/waf/createGroupPopup.js b/web/views/@default/servers/components/waf/createGroupPopup.js new file mode 100644 index 00000000..c8fe9515 --- /dev/null +++ b/web/views/@default/servers/components/waf/createGroupPopup.js @@ -0,0 +1,3 @@ +Tea.context(function () { + this.success = NotifyPopup +}) \ No newline at end of file diff --git a/web/views/@default/servers/components/waf/export.html b/web/views/@default/servers/components/waf/export.html new file mode 100644 index 00000000..5bb825ea --- /dev/null +++ b/web/views/@default/servers/components/waf/export.html @@ -0,0 +1,8 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "waf_menu"} + +

此功能暂未开放,敬请期待。

+
\ No newline at end of file diff --git a/web/views/@default/servers/components/waf/groups.html b/web/views/@default/servers/components/waf/groups.html new file mode 100644 index 00000000..99758477 --- /dev/null +++ b/web/views/@default/servers/components/waf/groups.html @@ -0,0 +1,45 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "waf_menu"} + + + [添加分组] + + +

暂时还没有规则分组。

+ + + + + + + + + + + + + + + + + + +
规则分组规则集操作
{{group.name}} +

{{group.description}}

+

+ 启用 + 停用 + 预置 + 自定义 +

+
+ {{group.countSets}} + + 详情   + 启用停用   + 删除 +
+
\ No newline at end of file diff --git a/web/views/@default/servers/components/waf/groups.js b/web/views/@default/servers/components/waf/groups.js new file mode 100644 index 00000000..6efd592c --- /dev/null +++ b/web/views/@default/servers/components/waf/groups.js @@ -0,0 +1,68 @@ +Tea.context(function () { + // 排序 + this.$delay(function () { + let that = this + sortTable(function () { + let groupIds = [] + document.querySelectorAll("tbody[data-group-id]") + .forEach(function (v) { + groupIds.push(v.getAttribute("data-group-id")) + }) + + that.$post(".sortGroups") + .params({ + firewallPolicyId: that.firewallPolicyId, + type: that.type, + groupIds: groupIds + }) + .success(function () { + teaweb.successToast("排序保存成功") + }) + }) + }) + + // 启用 + this.enableGroup = function (groupId) { + this.$post(".updateGroupOn") + .params({ + groupId: groupId, + isOn: 1 + }) + .refresh() + + } + + // 停用 + this.disableGroup = function (groupId) { + this.$post(".updateGroupOn") + .params({ + groupId: groupId, + isOn: 0 + }) + .refresh() + } + + // 删除 + this.deleteGroup = function (groupId) { + teaweb.confirm("确定要删除此规则分组吗?", function () { + this.$post(".deleteGroup") + .params({ + firewallPolicyId: this.firewallPolicyId, + groupId: groupId + }) + .refresh() + }) + } + + // 添加分组 + this.createGroup = function (type) { + teaweb.popup("/servers/components/waf/createGroupPopup?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type, { + height: "16em", + callback: function () { + teaweb.success("保存成功", function () { + window.location.reload() + }) + } + }) + } +}) \ No newline at end of file diff --git a/web/views/@default/servers/components/waf/import.html b/web/views/@default/servers/components/waf/import.html new file mode 100644 index 00000000..5bb825ea --- /dev/null +++ b/web/views/@default/servers/components/waf/import.html @@ -0,0 +1,8 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "waf_menu"} + +

此功能暂未开放,敬请期待。

+
\ No newline at end of file diff --git a/web/views/@default/servers/components/waf/ipadmin.html b/web/views/@default/servers/components/waf/ipadmin.html new file mode 100644 index 00000000..5bb825ea --- /dev/null +++ b/web/views/@default/servers/components/waf/ipadmin.html @@ -0,0 +1,8 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "waf_menu"} + +

此功能暂未开放,敬请期待。

+
\ No newline at end of file diff --git a/web/views/@default/servers/components/waf/log.html b/web/views/@default/servers/components/waf/log.html new file mode 100644 index 00000000..5bb825ea --- /dev/null +++ b/web/views/@default/servers/components/waf/log.html @@ -0,0 +1,8 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "waf_menu"} + +

此功能暂未开放,敬请期待。

+
\ No newline at end of file diff --git a/web/views/@default/servers/components/waf/test.html b/web/views/@default/servers/components/waf/test.html new file mode 100644 index 00000000..5bb825ea --- /dev/null +++ b/web/views/@default/servers/components/waf/test.html @@ -0,0 +1,8 @@ +{$layout} +{$template "/left_menu"} + +
+ {$template "waf_menu"} + +

此功能暂未开放,敬请期待。

+
\ No newline at end of file