diff --git a/internal/utils/ip_utils.go b/internal/utils/ip_utils.go index cfe3d8fb..f2bae13d 100644 --- a/internal/utils/ip_utils.go +++ b/internal/utils/ip_utils.go @@ -3,11 +3,66 @@ package utils import ( "bytes" "errors" + "github.com/TeaOSLab/EdgeCommon/pkg/iputils" "github.com/iwind/TeaGo/types" "net" "strings" ) +// ParseIPValue 解析IP值 +func ParseIPValue(value string) (newValue string, ipFrom string, ipTo string, ok bool) { + if len(value) == 0 { + return + } + + newValue = value + + // ip1-ip2 + if strings.Contains(value, "-") { + var pieces = strings.Split(value, "-") + if len(pieces) != 2 { + return + } + + ipFrom = strings.TrimSpace(pieces[0]) + ipTo = strings.TrimSpace(pieces[1]) + + if !iputils.IsValid(ipFrom) || !iputils.IsValid(ipTo) { + return + } + + if !iputils.IsSameVersion(ipFrom, ipTo) { + return + } + + if iputils.CompareIP(ipFrom, ipTo) > 0 { + ipFrom, ipTo = ipTo, ipFrom + newValue = ipFrom + "-" + ipTo + } + + ok = true + return + } + + // ip/mask + if strings.Contains(value, "/") { + cidr, err := iputils.ParseCIDR(value) + if err != nil { + return + } + return newValue, cidr.From().String(), cidr.To().String(), true + } + + // single value + if iputils.IsValid(value) { + ipFrom = value + ok = true + return + } + + return +} + // ExtractIP 分解IP // 只支持D段掩码的CIDR // 最多只记录255个值 diff --git a/internal/web/actions/default/servers/components/waf/ipadmin/lists.go b/internal/web/actions/default/servers/components/waf/ipadmin/lists.go index bb38fe19..5155ce48 100644 --- a/internal/web/actions/default/servers/components/waf/ipadmin/lists.go +++ b/internal/web/actions/default/servers/components/waf/ipadmin/lists.go @@ -99,6 +99,7 @@ func (this *ListsAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/components/waf/ipadmin/test.go b/internal/web/actions/default/servers/components/waf/ipadmin/test.go index 8b4fef46..69886456 100644 --- a/internal/web/actions/default/servers/components/waf/ipadmin/test.go +++ b/internal/web/actions/default/servers/components/waf/ipadmin/test.go @@ -57,6 +57,7 @@ func (this *TestAction) RunPost(params struct { if resp.IpItem != nil { resultMap["item"] = maps.Map{ "id": resp.IpItem.Id, + "value": resp.IpItem.Value, "ipFrom": resp.IpItem.IpFrom, "ipTo": resp.IpItem.IpTo, "reason": resp.IpItem.Reason, diff --git a/internal/web/actions/default/servers/components/waf/ipadmin/updateIPPopup.go b/internal/web/actions/default/servers/components/waf/ipadmin/updateIPPopup.go index 62dadcca..2c3263a7 100644 --- a/internal/web/actions/default/servers/components/waf/ipadmin/updateIPPopup.go +++ b/internal/web/actions/default/servers/components/waf/ipadmin/updateIPPopup.go @@ -1,8 +1,8 @@ package ipadmin import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/iputils" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" @@ -33,6 +33,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { this.Data["item"] = maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "expiredAt": item.ExpiredAt, @@ -50,8 +51,7 @@ func (this *UpdateIPPopupAction) RunPost(params struct { FirewallPolicyId int64 ItemId int64 - IpFrom string - IpTo string + Value string ExpiredAt int64 Reason string Type string @@ -63,50 +63,25 @@ func (this *UpdateIPPopupAction) RunPost(params struct { // 日志 defer this.CreateLogInfo(codes.WAF_LogUpdateIPFromWAFPolicy, params.FirewallPolicyId, params.ItemId) - // TODO 校验ItemId所属用户 - switch params.Type { - case "ipv4": + case "ip": + // 校验IP格式 params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入开始IP") + Field("value", params.Value). + Require("请输入IP或IP段") - // 校验IP格式(ipFrom/ipTo) - if !iputils.IsIPv4(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的开始IP") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv4(params.IpTo) { - this.FailField("ipTo", "请输入正确的结束IP") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo - } - case "ipv6": - params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入正确的开始IP") - - if !iputils.IsIPv6(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv6(params.IpTo) { - this.FailField("ipTo", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo + _, _, _, ok := utils.ParseIPValue(params.Value) + if !ok { + this.FailField("value", "请输入正确的IP格式") + return } case "all": - params.IpFrom = "0.0.0.0" + params.Value = "0.0.0.0" } _, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{ IpItemId: params.ItemId, - IpFrom: params.IpFrom, - IpTo: params.IpTo, + Value: params.Value, ExpiredAt: params.ExpiredAt, Reason: params.Reason, Type: params.Type, diff --git a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/allowList.go b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/allowList.go index 54831900..b2e9d1ee 100644 --- a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/allowList.go +++ b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/allowList.go @@ -109,6 +109,7 @@ func (this *AllowListAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/denyList.go b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/denyList.go index 1304d22b..0d6f1c66 100644 --- a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/denyList.go +++ b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/denyList.go @@ -109,6 +109,7 @@ func (this *DenyListAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/test.go b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/test.go index e816fb4a..1b8514a8 100644 --- a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/test.go +++ b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/test.go @@ -70,6 +70,7 @@ func (this *TestAction) RunPost(params struct { if resp.IpItem != nil { resultMap["item"] = maps.Map{ "id": resp.IpItem.Id, + "value": resp.IpItem.Value, "ipFrom": resp.IpItem.IpFrom, "ipTo": resp.IpItem.IpTo, "reason": resp.IpItem.Reason, diff --git a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/updateIPPopup.go b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/updateIPPopup.go index 11a89f4c..4ca2babe 100644 --- a/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/updateIPPopup.go +++ b/internal/web/actions/default/servers/groups/group/settings/waf/ipadmin/updateIPPopup.go @@ -1,8 +1,8 @@ package ipadmin import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/iputils" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" @@ -33,6 +33,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { this.Data["item"] = maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "expiredAt": item.ExpiredAt, @@ -49,8 +50,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { func (this *UpdateIPPopupAction) RunPost(params struct { ItemId int64 - IpFrom string - IpTo string + Value string ExpiredAt int64 Reason string Type string @@ -62,50 +62,25 @@ func (this *UpdateIPPopupAction) RunPost(params struct { // 日志 defer this.CreateLogInfo(codes.IPItem_LogUpdateIPItem, params.ItemId) - // TODO 校验ItemId所属用户 - switch params.Type { - case "ipv4": + case "ip": + // 校验IP格式 params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入开始IP") + Field("value", params.Value). + Require("请输入IP或IP段") - // 校验IP格式(ipFrom/ipTo) - if !iputils.IsIPv4(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的开始IP") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv4(params.IpTo) { - this.FailField("ipTo", "请输入正确的结束IP") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo - } - case "ipv6": - params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入正确的开始IP") - - if !iputils.IsIPv6(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv6(params.IpTo) { - this.FailField("ipTo", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo + _, _, _, ok := utils.ParseIPValue(params.Value) + if !ok { + this.FailField("value", "请输入正确的IP格式") + return } case "all": - params.IpFrom = "0.0.0.0" + params.Value = "0.0.0.0" } _, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{ IpItemId: params.ItemId, - IpFrom: params.IpFrom, - IpTo: params.IpTo, + Value: params.Value, ExpiredAt: params.ExpiredAt, Reason: params.Reason, Type: params.Type, diff --git a/internal/web/actions/default/servers/iplists/createIPPopup.go b/internal/web/actions/default/servers/iplists/createIPPopup.go index 47b6fbaa..c38695b7 100644 --- a/internal/web/actions/default/servers/iplists/createIPPopup.go +++ b/internal/web/actions/default/servers/iplists/createIPPopup.go @@ -1,16 +1,14 @@ package iplists import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/configutils" - "github.com/TeaOSLab/EdgeCommon/pkg/iputils" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" "github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/types" - "net" "strings" ) @@ -50,9 +48,7 @@ func (this *CreateIPPopupAction) RunPost(params struct { ListId int64 Method string - IpFrom string - IpTo string - + Value string IpData string ExpiredAt int64 @@ -76,29 +72,24 @@ func (this *CreateIPPopupAction) RunPost(params struct { } type ipData struct { + value string ipFrom string ipTo string } var batchIPs = []*ipData{} switch params.Type { - case "ipv4": + case "ip": if params.Method == "single" { - // 校验IP格式(ipFrom/ipTo) + // 校验IP格式 params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入开始IP") + Field("value", params.Value). + Require("请输入IP或IP段") - if !iputils.IsIPv4(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的开始IP") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv4(params.IpTo) { - this.FailField("ipTo", "请输入正确的结束IP") - } - - if len(params.IpTo) != 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo + _, _, _, ok := utils.ParseIPValue(params.Value) + if !ok { + this.FailField("value", "请输入正确的IP格式") + return } } else if params.Method == "batch" { if len(params.IpData) == 0 { @@ -107,144 +98,30 @@ func (this *CreateIPPopupAction) RunPost(params struct { var lines = strings.Split(params.IpData, "\n") for index, line := range lines { line = strings.TrimSpace(line) - if strings.Contains(line, "/") { // CIDR - if strings.Contains(line, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - ipFrom, ipTo, err := configutils.ParseCIDR(line) - if err != nil { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - ipTo: ipTo, - }) - } else if strings.Contains(line, "-") { // IP Range - var pieces = strings.Split(line, "-") - var ipFrom = strings.TrimSpace(pieces[0]) - var ipTo = strings.TrimSpace(pieces[1]) - - if net.ParseIP(ipFrom) == nil || net.ParseIP(ipTo) == nil || strings.Contains(ipFrom, ":") || strings.Contains(ipTo, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - if len(ipTo) > 0 && iputils.CompareIP(ipFrom, ipTo) > 0 { - ipFrom, ipTo = ipTo, ipFrom - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - ipTo: ipTo, - }) - } else if strings.Contains(line, ",") { // IP Range - var pieces = strings.Split(line, ",") - var ipFrom = strings.TrimSpace(pieces[0]) - var ipTo = strings.TrimSpace(pieces[1]) - - if net.ParseIP(ipFrom) == nil || net.ParseIP(ipTo) == nil || strings.Contains(ipFrom, ":") || strings.Contains(ipTo, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - if len(ipTo) > 0 && iputils.CompareIP(ipFrom, ipTo) > 0 { - ipFrom, ipTo = ipTo, ipFrom - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - ipTo: ipTo, - }) - } else if len(line) > 0 { - var ipFrom = line - if net.ParseIP(ipFrom) == nil || strings.Contains(ipFrom, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - }) + if len(line) == 0 { + continue } - } - } - case "ipv6": - if params.Method == "single" { - params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入正确的开始IP") - - if !iputils.IsIPv6(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv6(params.IpTo) { - this.FailField("ipTo", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo - } - } else if params.Method == "batch" { - if len(params.IpData) == 0 { - this.FailField("ipData", "请输入IP") - } - var lines = strings.Split(params.IpData, "\n") - for index, line := range lines { - line = strings.TrimSpace(line) - if strings.Contains(line, "/") { // CIDR - if !strings.Contains(line, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - ipFrom, ipTo, err := configutils.ParseCIDR(line) - if err != nil { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - ipTo: ipTo, - }) - } else if strings.Contains(line, "-") { // IP Range - var pieces = strings.Split(line, "-") - var ipFrom = strings.TrimSpace(pieces[0]) - var ipTo = strings.TrimSpace(pieces[1]) - - if net.ParseIP(ipFrom) == nil || net.ParseIP(ipTo) == nil || !strings.Contains(ipFrom, ":") || !strings.Contains(ipTo, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - if len(ipTo) > 0 && iputils.CompareIP(ipFrom, ipTo) > 0 { - ipFrom, ipTo = ipTo, ipFrom - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - ipTo: ipTo, - }) - } else if strings.Contains(line, ",") { // IP Range - var pieces = strings.Split(line, ",") - var ipFrom = strings.TrimSpace(pieces[0]) - var ipTo = strings.TrimSpace(pieces[1]) - - if net.ParseIP(ipFrom) == nil || net.ParseIP(ipTo) == nil || !strings.Contains(ipFrom, ":") || !strings.Contains(ipTo, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - if len(ipTo) > 0 && iputils.CompareIP(ipFrom, ipTo) > 0 { - ipFrom, ipTo = ipTo, ipFrom - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - ipTo: ipTo, - }) - } else if len(line) > 0 { - var ipFrom = line - if net.ParseIP(ipFrom) == nil || !strings.Contains(ipFrom, ":") { - this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) - } - batchIPs = append(batchIPs, &ipData{ - ipFrom: ipFrom, - }) + _, ipFrom, ipTo, ok := utils.ParseIPValue(line) + if !ok { + this.FailField("ipData", "第"+types.String(index+1)+"行IP格式错误:"+line) + return } + batchIPs = append(batchIPs, &ipData{ + value: line, + ipFrom: ipFrom, + ipTo: ipTo, + }) } } case "all": - params.IpFrom = "0.0.0.0" + params.Value = "0.0.0.0" } if len(batchIPs) > 0 { for _, ip := range batchIPs { _, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{ IpListId: params.ListId, + Value: ip.value, IpFrom: ip.ipFrom, IpTo: ip.ipTo, ExpiredAt: params.ExpiredAt, @@ -263,8 +140,7 @@ func (this *CreateIPPopupAction) RunPost(params struct { } else { createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{ IpListId: params.ListId, - IpFrom: params.IpFrom, - IpTo: params.IpTo, + Value: params.Value, ExpiredAt: params.ExpiredAt, Reason: params.Reason, Type: params.Type, diff --git a/internal/web/actions/default/servers/iplists/exportData.go b/internal/web/actions/default/servers/iplists/exportData.go index 6118d393..8a4d3715 100644 --- a/internal/web/actions/default/servers/iplists/exportData.go +++ b/internal/web/actions/default/servers/iplists/exportData.go @@ -30,7 +30,6 @@ func (this *ExportDataAction) RunGet(params struct { }) { defer this.CreateLogInfo(codes.IPList_LogExportIPList, params.ListId) - var err error var ext string var jsonMaps = []maps.Map{} var xlsxFile *xlsx.File @@ -44,20 +43,16 @@ func (this *ExportDataAction) RunGet(params struct { case "xlsx": ext = ".xlsx" xlsxFile = xlsx.NewFile() - if err != nil { - this.ErrorPage(err) - return - } + var err error xlsxSheet, err = xlsxFile.AddSheet("IP名单") if err != nil { this.ErrorPage(err) return } - row := xlsxSheet.AddRow() + var row = xlsxSheet.AddRow() row.SetHeight(26) - row.AddCell().SetValue("开始IP") - row.AddCell().SetValue("结束IP") + row.AddCell().SetValue("IP/IP段") row.AddCell().SetValue("过期时间戳") row.AddCell().SetValue("类型") row.AddCell().SetValue("级别") @@ -93,27 +88,25 @@ func (this *ExportDataAction) RunGet(params struct { for _, item := range itemsResp.IpItems { switch params.Format { case "xlsx": - row := xlsxSheet.AddRow() + var row = xlsxSheet.AddRow() row.SetHeight(26) - row.AddCell().SetValue(item.IpFrom) - row.AddCell().SetValue(item.IpTo) + row.AddCell().SetValue(item.Value) row.AddCell().SetValue(types.String(item.ExpiredAt)) row.AddCell().SetValue(item.Type) row.AddCell().SetValue(item.EventLevel) row.AddCell().SetValue(item.Reason) case "csv": - err = csvWriter.Write([]string{item.IpFrom, item.IpTo, types.String(item.ExpiredAt), item.Type, item.EventLevel, item.Reason}) + err = csvWriter.Write([]string{item.Value, types.String(item.ExpiredAt), item.Type, item.EventLevel, item.Reason}) if err != nil { this.ErrorPage(err) return } case "txt": - data = append(data, item.IpFrom+","+item.IpTo+","+types.String(item.ExpiredAt)+","+item.Type+","+item.EventLevel+","+item.Reason...) + data = append(data, item.Value+","+types.String(item.ExpiredAt)+","+item.Type+","+item.EventLevel+","+item.Reason...) data = append(data, '\n') case "json": jsonMaps = append(jsonMaps, maps.Map{ - "ipFrom": item.IpFrom, - "ipTo": item.IpTo, + "value": item.Value, "expiredAt": item.ExpiredAt, "type": item.Type, "eventLevel": item.EventLevel, @@ -127,7 +120,7 @@ func (this *ExportDataAction) RunGet(params struct { switch params.Format { case "xlsx": var buf = &bytes.Buffer{} - err = xlsxFile.Write(buf) + err := xlsxFile.Write(buf) if err != nil { this.ErrorPage(err) return @@ -137,6 +130,7 @@ func (this *ExportDataAction) RunGet(params struct { csvWriter.Flush() data = csvBuffer.Bytes() case "json": + var err error data, err = json.Marshal(jsonMaps) if err != nil { this.ErrorPage(err) diff --git a/internal/web/actions/default/servers/iplists/import.go b/internal/web/actions/default/servers/iplists/import.go index 3c77b4c9..f1459027 100644 --- a/internal/web/actions/default/servers/iplists/import.go +++ b/internal/web/actions/default/servers/iplists/import.go @@ -6,8 +6,8 @@ import ( "bytes" "encoding/csv" "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/configutils" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" @@ -15,7 +15,6 @@ import ( "github.com/iwind/TeaGo/types" "github.com/tealeg/xlsx/v3" "io" - "net" "regexp" "strings" ) @@ -79,9 +78,10 @@ func (this *ImportAction) RunPost(params struct { var items = []*pb.IPItem{} switch ext { case ".xlsx": - file, err := xlsx.OpenBinary(data) - if err != nil { - this.Fail("Excel读取错误:" + err.Error()) + file, openErr := xlsx.OpenBinary(data) + if openErr != nil { + this.Fail("Excel读取错误:" + openErr.Error()) + return } if len(file.Sheets) > 0 { var sheet = file.Sheets[0] @@ -136,7 +136,7 @@ func (this *ImportAction) RunPost(params struct { if len(line) == 0 { continue } - item := this.createItemFromValues(strings.SplitN(string(line), ",", 6), &countIgnore) + item := this.createItemFromValues(strings.SplitN(string(line), ",", 5), &countIgnore) if item != nil { items = append(items, item) } @@ -150,6 +150,7 @@ func (this *ImportAction) RunPost(params struct { for _, item := range items { _, err = this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{ IpListId: params.ListId, + Value: item.Value, IpFrom: item.IpFrom, IpTo: item.IpTo, ExpiredAt: item.ExpiredAt, @@ -170,60 +171,45 @@ func (this *ImportAction) RunPost(params struct { } func (this *ImportAction) createItemFromValues(values []string, countIgnore *int) *pb.IPItem { - // ipFrom, ipTo, expiredAt, type, eventType, reason + // value, expiredAt, type, eventType, reason var item = &pb.IPItem{} switch len(values) { case 1: - item.IpFrom = values[0] + item.Value = values[0] case 2: - item.IpFrom = values[0] - item.IpTo = values[1] + item.Value = values[0] + item.ExpiredAt = types.Int64(values[1]) case 3: - item.IpFrom = values[0] - item.IpTo = values[1] - item.ExpiredAt = types.Int64(values[2]) + item.Value = values[0] + item.ExpiredAt = types.Int64(values[1]) + item.Type = values[2] case 4: - item.IpFrom = values[0] - item.IpTo = values[1] - item.ExpiredAt = types.Int64(values[2]) - item.Type = values[3] + item.Value = values[0] + item.ExpiredAt = types.Int64(values[1]) + item.Type = values[2] + item.EventLevel = values[3] case 5: - item.IpFrom = values[0] - item.IpTo = values[1] - item.ExpiredAt = types.Int64(values[2]) - item.Type = values[3] - item.EventLevel = values[4] - case 6: - item.IpFrom = values[0] - item.IpTo = values[1] - item.ExpiredAt = types.Int64(values[2]) - item.Type = values[3] - item.EventLevel = values[4] - item.Reason = values[5] - } - - // CIDR - if strings.Contains(item.IpFrom, "/") { - ipFrom, ipTo, err := configutils.ParseCIDR(item.IpFrom) - if err == nil { - item.IpFrom = ipFrom - item.IpTo = ipTo - } + item.Value = values[0] + item.ExpiredAt = types.Int64(values[1]) + item.Type = values[2] + item.EventLevel = values[3] + item.Reason = values[4] } if len(item.EventLevel) == 0 { item.EventLevel = "critical" } - if net.ParseIP(item.IpFrom) == nil { - *countIgnore++ - return nil - } - if len(item.IpTo) > 0 && net.ParseIP(item.IpTo) == nil { + newValue, ipFrom, ipTo, ok := utils.ParseIPValue(item.Value) + if !ok { *countIgnore++ return nil } + item.Value = newValue + item.IpFrom = ipFrom + item.IpTo = ipTo + return item } diff --git a/internal/web/actions/default/servers/iplists/index.go b/internal/web/actions/default/servers/iplists/index.go index ae351465..c6f38987 100644 --- a/internal/web/actions/default/servers/iplists/index.go +++ b/internal/web/actions/default/servers/iplists/index.go @@ -172,6 +172,7 @@ func (this *IndexAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/iplists/items.go b/internal/web/actions/default/servers/iplists/items.go index 8c5bb94d..7e5d903f 100644 --- a/internal/web/actions/default/servers/iplists/items.go +++ b/internal/web/actions/default/servers/iplists/items.go @@ -118,6 +118,7 @@ func (this *ItemsAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/iplists/test.go b/internal/web/actions/default/servers/iplists/test.go index 2c0b0136..7b06a96e 100644 --- a/internal/web/actions/default/servers/iplists/test.go +++ b/internal/web/actions/default/servers/iplists/test.go @@ -58,6 +58,7 @@ func (this *TestAction) RunPost(params struct { if resp.IpItem != nil { resultMap["item"] = maps.Map{ "id": resp.IpItem.Id, + "value": resp.IpItem.Value, "ipFrom": resp.IpItem.IpFrom, "ipTo": resp.IpItem.IpTo, "reason": resp.IpItem.Reason, diff --git a/internal/web/actions/default/servers/iplists/updateIPPopup.go b/internal/web/actions/default/servers/iplists/updateIPPopup.go index 50a4147f..083038aa 100644 --- a/internal/web/actions/default/servers/iplists/updateIPPopup.go +++ b/internal/web/actions/default/servers/iplists/updateIPPopup.go @@ -1,8 +1,8 @@ package iplists import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/iputils" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" @@ -33,6 +33,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { this.Data["item"] = maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "expiredAt": item.ExpiredAt, @@ -49,8 +50,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { func (this *UpdateIPPopupAction) RunPost(params struct { ItemId int64 - IpFrom string - IpTo string + Value string ExpiredAt int64 Reason string Type string @@ -62,50 +62,25 @@ func (this *UpdateIPPopupAction) RunPost(params struct { // 日志 defer this.CreateLogInfo(codes.IPItem_LogUpdateIPItem, params.ItemId) - // TODO 校验ItemId所属用户 - switch params.Type { - case "ipv4": + case "ip": + // 校验IP格式 params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入开始IP") + Field("value", params.Value). + Require("请输入IP或IP段") - // 校验IP格式(ipFrom/ipTo) - if !iputils.IsIPv4(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的开始IP") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv4(params.IpTo) { - this.FailField("ipTo", "请输入正确的结束IP") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo - } - case "ipv6": - params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入正确的开始IP") - - if !iputils.IsIPv6(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv6(params.IpTo) { - this.FailField("ipTo", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo + _, _, _, ok := utils.ParseIPValue(params.Value) + if !ok { + this.FailField("value", "请输入正确的IP格式") + return } case "all": - params.IpFrom = "0.0.0.0" + params.Value = "0.0.0.0" } _, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{ IpItemId: params.ItemId, - IpFrom: params.IpFrom, - IpTo: params.IpTo, + Value: params.Value, ExpiredAt: params.ExpiredAt, Reason: params.Reason, Type: params.Type, diff --git a/internal/web/actions/default/servers/server/settings/waf/ipadmin/allowList.go b/internal/web/actions/default/servers/server/settings/waf/ipadmin/allowList.go index 54831900..b2e9d1ee 100644 --- a/internal/web/actions/default/servers/server/settings/waf/ipadmin/allowList.go +++ b/internal/web/actions/default/servers/server/settings/waf/ipadmin/allowList.go @@ -109,6 +109,7 @@ func (this *AllowListAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/server/settings/waf/ipadmin/denyList.go b/internal/web/actions/default/servers/server/settings/waf/ipadmin/denyList.go index 5e7808e5..f5ee29e2 100644 --- a/internal/web/actions/default/servers/server/settings/waf/ipadmin/denyList.go +++ b/internal/web/actions/default/servers/server/settings/waf/ipadmin/denyList.go @@ -109,6 +109,7 @@ func (this *DenyListAction) RunGet(params struct { itemMaps = append(itemMaps, maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt), diff --git a/internal/web/actions/default/servers/server/settings/waf/ipadmin/test.go b/internal/web/actions/default/servers/server/settings/waf/ipadmin/test.go index e816fb4a..1b8514a8 100644 --- a/internal/web/actions/default/servers/server/settings/waf/ipadmin/test.go +++ b/internal/web/actions/default/servers/server/settings/waf/ipadmin/test.go @@ -70,6 +70,7 @@ func (this *TestAction) RunPost(params struct { if resp.IpItem != nil { resultMap["item"] = maps.Map{ "id": resp.IpItem.Id, + "value": resp.IpItem.Value, "ipFrom": resp.IpItem.IpFrom, "ipTo": resp.IpItem.IpTo, "reason": resp.IpItem.Reason, diff --git a/internal/web/actions/default/servers/server/settings/waf/ipadmin/updateIPPopup.go b/internal/web/actions/default/servers/server/settings/waf/ipadmin/updateIPPopup.go index 11a89f4c..4ca2babe 100644 --- a/internal/web/actions/default/servers/server/settings/waf/ipadmin/updateIPPopup.go +++ b/internal/web/actions/default/servers/server/settings/waf/ipadmin/updateIPPopup.go @@ -1,8 +1,8 @@ package ipadmin import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/iputils" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" @@ -33,6 +33,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { this.Data["item"] = maps.Map{ "id": item.Id, + "value": item.Value, "ipFrom": item.IpFrom, "ipTo": item.IpTo, "expiredAt": item.ExpiredAt, @@ -49,8 +50,7 @@ func (this *UpdateIPPopupAction) RunGet(params struct { func (this *UpdateIPPopupAction) RunPost(params struct { ItemId int64 - IpFrom string - IpTo string + Value string ExpiredAt int64 Reason string Type string @@ -62,50 +62,25 @@ func (this *UpdateIPPopupAction) RunPost(params struct { // 日志 defer this.CreateLogInfo(codes.IPItem_LogUpdateIPItem, params.ItemId) - // TODO 校验ItemId所属用户 - switch params.Type { - case "ipv4": + case "ip": + // 校验IP格式 params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入开始IP") + Field("value", params.Value). + Require("请输入IP或IP段") - // 校验IP格式(ipFrom/ipTo) - if !iputils.IsIPv4(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的开始IP") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv4(params.IpTo) { - this.FailField("ipTo", "请输入正确的结束IP") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo - } - case "ipv6": - params.Must. - Field("ipFrom", params.IpFrom). - Require("请输入正确的开始IP") - - if !iputils.IsIPv6(params.IpFrom) { - this.FailField("ipFrom", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && !iputils.IsIPv6(params.IpTo) { - this.FailField("ipTo", "请输入正确的IPv6地址") - } - - if len(params.IpTo) > 0 && iputils.CompareIP(params.IpFrom, params.IpTo) > 0 { - params.IpTo, params.IpFrom = params.IpFrom, params.IpTo + _, _, _, ok := utils.ParseIPValue(params.Value) + if !ok { + this.FailField("value", "请输入正确的IP格式") + return } case "all": - params.IpFrom = "0.0.0.0" + params.Value = "0.0.0.0" } _, err := this.RPC().IPItemRPC().UpdateIPItem(this.AdminContext(), &pb.UpdateIPItemRequest{ IpItemId: params.ItemId, - IpFrom: params.IpFrom, - IpTo: params.IpTo, + Value: params.Value, ExpiredAt: params.ExpiredAt, Reason: params.Reason, Type: params.Type, diff --git a/web/public/js/components/common/datetime-input.js b/web/public/js/components/common/datetime-input.js index 2d3a8adf..032d9c4f 100644 --- a/web/public/js/components/common/datetime-input.js +++ b/web/public/js/components/common/datetime-input.js @@ -140,6 +140,15 @@ Vue.component("datetime-input", { resultTimestamp: function () { return this.timestamp }, + nextYear: function () { + let date = new Date() + date.setFullYear(date.getFullYear()+1) + this.day = date.getFullYear() + "-" + this.leadingZero(date.getMonth() + 1, 2) + "-" + this.leadingZero(date.getDate(), 2) + this.hour = this.leadingZero(date.getHours(), 2) + this.minute = this.leadingZero(date.getMinutes(), 2) + this.second = this.leadingZero(date.getSeconds(), 2) + this.change() + }, nextDays: function (days) { let date = new Date() date.setTime(date.getTime() + days * 86400 * 1000) @@ -171,6 +180,6 @@ Vue.component("datetime-input", {
常用时间: 1小时 | 1天 | 3天 | 1周 | 30天
+常用时间: 1小时 | 1天 | 3天 | 1周 | 30天 | 1年
` }) \ No newline at end of file diff --git a/web/public/js/components/iplist/ip-item-text.js b/web/public/js/components/iplist/ip-item-text.js index 3396cb67..70ba1f63 100644 --- a/web/public/js/components/iplist/ip-item-text.js +++ b/web/public/js/components/iplist/ip-item-text.js @@ -2,13 +2,13 @@ Vue.component("ip-item-text", { props: ["v-item"], template: ` * - - {{vItem.ipFrom}} - - {{vItem.ipTo}} - - {{vItem.ipFrom}} - - {{vItem.ipTo}} - + + {{vItem.value}} + + {{vItem.ipFrom}} + - {{vItem.ipTo}} + + 级别:{{vItem.eventLevelName}} ` }) \ No newline at end of file diff --git a/web/public/js/components/iplist/ip-list-table.js b/web/public/js/components/iplist/ip-list-table.js index a1f361ee..dab64808 100644 --- a/web/public/js/components/iplist/ip-list-table.js +++ b/web/public/js/components/iplist/ip-list-table.js @@ -155,8 +155,12 @@ Vue.component("ip-list-table", {只有表示IP段的时候才需要填写此项。
-IPv6地址,比如 1406:3c00:0:2409:13:58:103:15
-只有表示IP段的时候才需要填写此项。
+只有表示IP段的时候才需要填写此项。
-IPv6地址,比如 1406:3c00:0:2409:13:58:103:15
-只有表示IP段的时候才需要填写此项。
+单个IPv4或一个IPv4范围。
-单个IPv6或一个IPv6范围。
+单个IP或一个IP范围。
允许或禁用所有的IP。
只有表示IP段的时候才需要填写此项。
-IPv6地址,比如 1406:3c00:0:2409:13:58:103:15
-只有表示IP段的时候才需要填写此项。
+ +支持IPv4和IPv6;支持三种格式:单个IP(比如192.168.1.100)、IP范围(比如192.168.1.1-192.168.1.255)、CIDR(比如192.168.1.1/24)。
每行一个IP,支持三种格式:
每行一个IP。
+ +每行一个IP,支持三种格式: