mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	添加IP到IP名单时,可以选择批量输入
This commit is contained in:
		@@ -45,11 +45,9 @@ func init() {
 | 
			
		||||
			GetPost("/ipadmin", new(ipadmin.IndexAction)).
 | 
			
		||||
			GetPost("/ipadmin/provinces", new(ipadmin.ProvincesAction)).
 | 
			
		||||
			Get("/ipadmin/lists", new(ipadmin.ListsAction)).
 | 
			
		||||
			GetPost("/ipadmin/createIPPopup", new(ipadmin.CreateIPPopupAction)).
 | 
			
		||||
			GetPost("/ipadmin/updateIPPopup", new(ipadmin.UpdateIPPopupAction)).
 | 
			
		||||
			Post("/ipadmin/deleteIP", new(ipadmin.DeleteIPAction)).
 | 
			
		||||
			GetPost("/ipadmin/test", new(ipadmin.TestAction)).
 | 
			
		||||
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
package ipadmin
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/utils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreateIPPopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) Init() {
 | 
			
		||||
	this.Nav("", "", "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) RunGet(params struct {
 | 
			
		||||
	FirewallPolicyId int64
 | 
			
		||||
	Type             string
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["listType"] = params.Type
 | 
			
		||||
 | 
			
		||||
	listId, err := dao.SharedHTTPFirewallPolicyDAO.FindEnabledPolicyIPListIdWithType(this.AdminContext(), params.FirewallPolicyId, params.Type)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["listId"] = listId
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) RunPost(params struct {
 | 
			
		||||
	FirewallPolicyId int64
 | 
			
		||||
	ListId           int64
 | 
			
		||||
	IpFrom           string
 | 
			
		||||
	IpTo             string
 | 
			
		||||
	ExpiredAt        int64
 | 
			
		||||
	Reason           string
 | 
			
		||||
	Type             string
 | 
			
		||||
	EventLevel       string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	// TODO 校验ListId所属用户
 | 
			
		||||
 | 
			
		||||
	switch params.Type {
 | 
			
		||||
	case "ipv4":
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("ipFrom", params.IpFrom).
 | 
			
		||||
			Require("请输入开始IP")
 | 
			
		||||
 | 
			
		||||
		// 校验IP格式(ipFrom/ipTo)
 | 
			
		||||
		var ipFromLong uint64
 | 
			
		||||
		if !utils.IsIPv4(params.IpFrom) {
 | 
			
		||||
			this.Fail("请输入正确的开始IP")
 | 
			
		||||
		}
 | 
			
		||||
		ipFromLong = utils.IP2Long(params.IpFrom)
 | 
			
		||||
 | 
			
		||||
		var ipToLong uint64
 | 
			
		||||
		if len(params.IpTo) > 0 && !utils.IsIPv4(params.IpTo) {
 | 
			
		||||
			ipToLong = utils.IP2Long(params.IpTo)
 | 
			
		||||
			this.Fail("请输入正确的结束IP")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ipFromLong > 0 && ipToLong > 0 && ipFromLong > ipToLong {
 | 
			
		||||
			params.IpTo, params.IpFrom = params.IpFrom, params.IpTo
 | 
			
		||||
		}
 | 
			
		||||
	case "ipv6":
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("ipFrom", params.IpFrom).
 | 
			
		||||
			Require("请输入IP")
 | 
			
		||||
 | 
			
		||||
		// 校验IP格式(ipFrom)
 | 
			
		||||
		if !utils.IsIPv6(params.IpFrom) {
 | 
			
		||||
			this.Fail("请输入正确的IPv6地址")
 | 
			
		||||
		}
 | 
			
		||||
	case "all":
 | 
			
		||||
		params.IpFrom = "0.0.0.0"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
 | 
			
		||||
		IpListId:   params.ListId,
 | 
			
		||||
		IpFrom:     params.IpFrom,
 | 
			
		||||
		IpTo:       params.IpTo,
 | 
			
		||||
		ExpiredAt:  params.ExpiredAt,
 | 
			
		||||
		Reason:     params.Reason,
 | 
			
		||||
		Type:       params.Type,
 | 
			
		||||
		EventLevel: params.EventLevel,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	itemId := createResp.IpItemId
 | 
			
		||||
 | 
			
		||||
	// 日志
 | 
			
		||||
	defer this.CreateLog(oplogs.LevelInfo, "在WAF策略 %d 名单中添加IP %d", params.FirewallPolicyId, itemId)
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -4,8 +4,13 @@ import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"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/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreateIPPopupAction struct {
 | 
			
		||||
@@ -21,13 +26,34 @@ func (this *CreateIPPopupAction) RunGet(params struct {
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["listId"] = params.ListId
 | 
			
		||||
 | 
			
		||||
	listResp, err := this.RPC().IPListRPC().FindEnabledIPList(this.AdminContext(), &pb.FindEnabledIPListRequest{
 | 
			
		||||
		IpListId: params.ListId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var ipList = listResp.IpList
 | 
			
		||||
	if ipList == nil {
 | 
			
		||||
		this.NotFound("ipList", params.ListId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["list"] = maps.Map{
 | 
			
		||||
		"type": ipList.Type,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) RunPost(params struct {
 | 
			
		||||
	ListId     int64
 | 
			
		||||
	IpFrom     string
 | 
			
		||||
	IpTo       string
 | 
			
		||||
	ListId int64
 | 
			
		||||
	Method string
 | 
			
		||||
 | 
			
		||||
	IpFrom string
 | 
			
		||||
	IpTo   string
 | 
			
		||||
 | 
			
		||||
	IpData string
 | 
			
		||||
 | 
			
		||||
	ExpiredAt  int64
 | 
			
		||||
	Reason     string
 | 
			
		||||
	Type       string
 | 
			
		||||
@@ -46,58 +72,207 @@ func (this *CreateIPPopupAction) RunPost(params struct {
 | 
			
		||||
		this.Fail("IP名单不存在")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	type ipData struct {
 | 
			
		||||
		ipFrom string
 | 
			
		||||
		ipTo   string
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var batchIPs = []*ipData{}
 | 
			
		||||
	switch params.Type {
 | 
			
		||||
	case "ipv4":
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("ipFrom", params.IpFrom).
 | 
			
		||||
			Require("请输入开始IP")
 | 
			
		||||
		if params.Method == "single" {
 | 
			
		||||
			// 校验IP格式(ipFrom/ipTo)
 | 
			
		||||
			params.Must.
 | 
			
		||||
				Field("ipFrom", params.IpFrom).
 | 
			
		||||
				Require("请输入开始IP")
 | 
			
		||||
 | 
			
		||||
		// 校验IP格式(ipFrom/ipTo)
 | 
			
		||||
		var ipFromLong uint64
 | 
			
		||||
		if !utils.IsIPv4(params.IpFrom) {
 | 
			
		||||
			this.Fail("请输入正确的开始IP")
 | 
			
		||||
		}
 | 
			
		||||
		ipFromLong = utils.IP2Long(params.IpFrom)
 | 
			
		||||
			var ipFromLong uint64
 | 
			
		||||
			if !utils.IsIPv4(params.IpFrom) {
 | 
			
		||||
				this.Fail("请输入正确的开始IP")
 | 
			
		||||
			}
 | 
			
		||||
			ipFromLong = utils.IP2Long(params.IpFrom)
 | 
			
		||||
 | 
			
		||||
		var ipToLong uint64
 | 
			
		||||
		if len(params.IpTo) > 0 && !utils.IsIPv4(params.IpTo) {
 | 
			
		||||
			ipToLong = utils.IP2Long(params.IpTo)
 | 
			
		||||
			this.Fail("请输入正确的结束IP")
 | 
			
		||||
		}
 | 
			
		||||
			var ipToLong uint64
 | 
			
		||||
			if len(params.IpTo) > 0 && !utils.IsIPv4(params.IpTo) {
 | 
			
		||||
				ipToLong = utils.IP2Long(params.IpTo)
 | 
			
		||||
				this.Fail("请输入正确的结束IP")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		if ipFromLong > 0 && ipToLong > 0 && ipFromLong > ipToLong {
 | 
			
		||||
			params.IpTo, params.IpFrom = params.IpFrom, params.IpTo
 | 
			
		||||
			if ipFromLong > 0 && ipToLong > 0 && ipFromLong > ipToLong {
 | 
			
		||||
				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 utils.IP2Long(ipFrom) > utils.IP2Long(ipTo) {
 | 
			
		||||
						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 utils.IP2Long(ipFrom) > utils.IP2Long(ipTo) {
 | 
			
		||||
						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,
 | 
			
		||||
					})
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	case "ipv6":
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("ipFrom", params.IpFrom).
 | 
			
		||||
			Require("请输入IP")
 | 
			
		||||
		if params.Method == "single" {
 | 
			
		||||
			params.Must.
 | 
			
		||||
				Field("ipFrom", params.IpFrom).
 | 
			
		||||
				Require("请输入IP")
 | 
			
		||||
 | 
			
		||||
		// 校验IP格式(ipFrom)
 | 
			
		||||
		if !utils.IsIPv6(params.IpFrom) {
 | 
			
		||||
			this.Fail("请输入正确的IPv6地址")
 | 
			
		||||
			// 校验IP格式(ipFrom)
 | 
			
		||||
			if !utils.IsIPv6(params.IpFrom) {
 | 
			
		||||
				this.Fail("请输入正确的IPv6地址")
 | 
			
		||||
			}
 | 
			
		||||
		} 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 utils.IP2Long(ipFrom) > utils.IP2Long(ipTo) {
 | 
			
		||||
						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 utils.IP2Long(ipFrom) > utils.IP2Long(ipTo) {
 | 
			
		||||
						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,
 | 
			
		||||
					})
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	case "all":
 | 
			
		||||
		params.IpFrom = "0.0.0.0"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
 | 
			
		||||
		IpListId:   params.ListId,
 | 
			
		||||
		IpFrom:     params.IpFrom,
 | 
			
		||||
		IpTo:       params.IpTo,
 | 
			
		||||
		ExpiredAt:  params.ExpiredAt,
 | 
			
		||||
		Reason:     params.Reason,
 | 
			
		||||
		Type:       params.Type,
 | 
			
		||||
		EventLevel: params.EventLevel,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	itemId := createResp.IpItemId
 | 
			
		||||
	if len(batchIPs) > 0 {
 | 
			
		||||
		for _, ip := range batchIPs {
 | 
			
		||||
			_, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
 | 
			
		||||
				IpListId:   params.ListId,
 | 
			
		||||
				IpFrom:     ip.ipFrom,
 | 
			
		||||
				IpTo:       ip.ipTo,
 | 
			
		||||
				ExpiredAt:  params.ExpiredAt,
 | 
			
		||||
				Reason:     params.Reason,
 | 
			
		||||
				Type:       params.Type,
 | 
			
		||||
				EventLevel: params.EventLevel,
 | 
			
		||||
			})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	// 日志
 | 
			
		||||
	defer this.CreateLog(oplogs.LevelInfo, "在IP名单中添加IP %d", itemId)
 | 
			
		||||
		// 日志
 | 
			
		||||
		defer this.CreateLog(oplogs.LevelInfo, "在IP名单中批量添加IP %d", params.ListId)
 | 
			
		||||
	} else {
 | 
			
		||||
		createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
 | 
			
		||||
			IpListId:   params.ListId,
 | 
			
		||||
			IpFrom:     params.IpFrom,
 | 
			
		||||
			IpTo:       params.IpTo,
 | 
			
		||||
			ExpiredAt:  params.ExpiredAt,
 | 
			
		||||
			Reason:     params.Reason,
 | 
			
		||||
			Type:       params.Type,
 | 
			
		||||
			EventLevel: params.EventLevel,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		itemId := createResp.IpItemId
 | 
			
		||||
 | 
			
		||||
		// 日志
 | 
			
		||||
		defer this.CreateLog(oplogs.LevelInfo, "在IP名单 %d 中添加IP %d", params.ListId, itemId)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ func init() {
 | 
			
		||||
			Get("/ipadmin/denyList", new(ipadmin.DenyListAction)).
 | 
			
		||||
			GetPost("/ipadmin/countries", new(ipadmin.CountriesAction)).
 | 
			
		||||
			GetPost("/ipadmin/provinces", new(ipadmin.ProvincesAction)).
 | 
			
		||||
			GetPost("/ipadmin/createIPPopup", new(ipadmin.CreateIPPopupAction)).
 | 
			
		||||
			GetPost("/ipadmin/updateIPPopup", new(ipadmin.UpdateIPPopupAction)).
 | 
			
		||||
			Post("/ipadmin/deleteIP", new(ipadmin.DeleteIPAction)).
 | 
			
		||||
			GetPost("/ipadmin/test", new(ipadmin.TestAction)).
 | 
			
		||||
 
 | 
			
		||||
@@ -1,95 +0,0 @@
 | 
			
		||||
package ipadmin
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/utils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreateIPPopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) Init() {
 | 
			
		||||
	this.Nav("", "", "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) RunGet(params struct {
 | 
			
		||||
	ListId int64
 | 
			
		||||
	Type   string
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["listType"] = params.Type
 | 
			
		||||
	this.Data["listId"] = params.ListId
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateIPPopupAction) RunPost(params struct {
 | 
			
		||||
	ListId     int64
 | 
			
		||||
	IpFrom     string
 | 
			
		||||
	IpTo       string
 | 
			
		||||
	ExpiredAt  int64
 | 
			
		||||
	Reason     string
 | 
			
		||||
	Type       string
 | 
			
		||||
	EventLevel string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	switch params.Type {
 | 
			
		||||
	case "ipv4":
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("ipFrom", params.IpFrom).
 | 
			
		||||
			Require("请输入开始IP")
 | 
			
		||||
 | 
			
		||||
		// 校验IP格式(ipFrom/ipTo)
 | 
			
		||||
		var ipFromLong uint64
 | 
			
		||||
		if !utils.IsIPv4(params.IpFrom) {
 | 
			
		||||
			this.Fail("请输入正确的开始IP")
 | 
			
		||||
		}
 | 
			
		||||
		ipFromLong = utils.IP2Long(params.IpFrom)
 | 
			
		||||
 | 
			
		||||
		var ipToLong uint64
 | 
			
		||||
		if len(params.IpTo) > 0 && !utils.IsIPv4(params.IpTo) {
 | 
			
		||||
			ipToLong = utils.IP2Long(params.IpTo)
 | 
			
		||||
			this.Fail("请输入正确的结束IP")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ipFromLong > 0 && ipToLong > 0 && ipFromLong > ipToLong {
 | 
			
		||||
			params.IpTo, params.IpFrom = params.IpFrom, params.IpTo
 | 
			
		||||
		}
 | 
			
		||||
	case "ipv6":
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("ipFrom", params.IpFrom).
 | 
			
		||||
			Require("请输入IP")
 | 
			
		||||
 | 
			
		||||
		// 校验IP格式(ipFrom)
 | 
			
		||||
		if !utils.IsIPv6(params.IpFrom) {
 | 
			
		||||
			this.Fail("请输入正确的IPv6地址")
 | 
			
		||||
		}
 | 
			
		||||
	case "all":
 | 
			
		||||
		params.IpFrom = "0.0.0.0"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
 | 
			
		||||
		IpListId:   params.ListId,
 | 
			
		||||
		IpFrom:     params.IpFrom,
 | 
			
		||||
		IpTo:       params.IpTo,
 | 
			
		||||
		ExpiredAt:  params.ExpiredAt,
 | 
			
		||||
		Reason:     params.Reason,
 | 
			
		||||
		Type:       params.Type,
 | 
			
		||||
		EventLevel: params.EventLevel,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	itemId := createResp.IpItemId
 | 
			
		||||
 | 
			
		||||
	// 日志
 | 
			
		||||
	defer this.CreateLog(oplogs.LevelInfo, "在WAF策略 %d 名单中添加IP %d", params.ListId, itemId)
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -53,7 +53,7 @@ Vue.component("ip-list-bind-box", {
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	<a href="" @click.prevent="bind()">绑定+</a>   <span v-if="lists.length > 0"><span class="disabled small">| </span> 已绑定:</span>
 | 
			
		||||
	<a href="" @click.prevent="bind()" style="color: rgba(0,0,0,.6)">绑定+</a>   <span v-if="lists.length > 0"><span class="disabled small">| </span> 已绑定:</span>
 | 
			
		||||
	<div class="ui label basic small" v-for="(list, index) in lists">
 | 
			
		||||
		<a :href="'/servers/iplists/list?listId=' + list.id" title="点击查看详情" style="opacity: 1">{{list.name}}</a>
 | 
			
		||||
		<a href="" title="删除" @click.prevent="remove(index, list.id)"><i class="icon remove small"></i></a>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,6 @@
 | 
			
		||||
	<menu-item :href="'/servers/components/waf/ipadmin/provinces?firewallPolicyId=' + firewallPolicyId" :active="subMenuItem == 'province'">省份封禁</menu-item>
 | 
			
		||||
	<span class="item disabled">|</span>
 | 
			
		||||
	<menu-item :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + firewallPolicyId + '&type=white'" :active="subMenuItem == 'white'">白名单</menu-item>
 | 
			
		||||
	<a href="" class="item" @click.prevent="createIP('white')"><span style="font-size: 0.9em">[添加IP]</span></a>
 | 
			
		||||
	<span class="item disabled">|</span>
 | 
			
		||||
	<menu-item :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + firewallPolicyId + '&type=black'" :active="subMenuItem == 'black'">黑名单</menu-item>
 | 
			
		||||
	<a href="" class="item" @click.prevent="createIP('black')"><span style="font-size: 0.9em">[添加IP]</span></a>
 | 
			
		||||
    <span class="item disabled">|</span>
 | 
			
		||||
    <menu-item :href="'/servers/components/waf/ipadmin/test?firewallPolicyId=' + firewallPolicyId" :active="subMenuItem == 'test'">IP检查</menu-item>
 | 
			
		||||
</second-menu>
 | 
			
		||||
@@ -1,78 +0,0 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3 v-if="listType == 'white'">添加IP到白名单</h3>
 | 
			
		||||
<h3 v-if="listType == 'black'">添加IP到黑名单</h3>
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<input type="hidden" name="firewallPolicyId" :value="firewallPolicyId"/>
 | 
			
		||||
	<input type="hidden" name="listId" :value="listId"/>
 | 
			
		||||
	<csrf-token></csrf-token>
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">类型 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <select class="ui dropdown auto-width" name="type" v-model="type">
 | 
			
		||||
                    <option value="ipv4">IPv4</option>
 | 
			
		||||
                    <option value="ipv6">IPv6</option>
 | 
			
		||||
                    <option value="all">所有IP</option>
 | 
			
		||||
                </select>
 | 
			
		||||
                <p class="comment" v-if="type == 'ipv4'">单个IPv4或一个IPv4范围。</p>
 | 
			
		||||
                <p class="comment" v-if="type == 'ipv6'">单个IPv6。</p>
 | 
			
		||||
                <p class="comment" v-if="type == 'all'">允许或禁用所有的IP。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 | 
			
		||||
        <!-- IPv4 -->
 | 
			
		||||
        <tbody v-if="type == 'ipv4'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>开始IP *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x.x.x.x" ref="focus"/>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>结束IP</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipTo" maxlength="64" placeholder="x.x.x.x"/>
 | 
			
		||||
                    <p class="comment">表示IP段的时候需要填写此项。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <!-- IPv6 -->
 | 
			
		||||
        <tbody v-if="type == 'ipv6'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>IP *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x:x:x:x:x:x:x:x" ref="focus"/>
 | 
			
		||||
                    <p class="comment">IPv6地址,比如 1406:3c00:0:2409:13:58:103:15</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>级别</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <firewall-event-level-options :v-value="eventLevel"></firewall-event-level-options>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>过期时间</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<datetime-input :v-name="'expiredAt'"></datetime-input>
 | 
			
		||||
					<p class="comment">在加入名单某一段时间后会失效,留空表示永久有效。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>备注</td>
 | 
			
		||||
				<td><input type="text" name="reason" maxlength="100"/></td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
    this.type = "ipv4"
 | 
			
		||||
    this.eventLevel = (this.listType == "white") ? "debug" : "critical"
 | 
			
		||||
})
 | 
			
		||||
@@ -51,19 +51,4 @@ Tea.context(function () {
 | 
			
		||||
			return country.isChecked
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 添加IP名单菜单
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
 | 
			
		||||
			height: "23em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + that.firewallPolicyId + "&type=" + type
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -3,9 +3,11 @@
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<second-menu style="margin-top: -1em">
 | 
			
		||||
    <span class="item">ID: {{listId}}   <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
 | 
			
		||||
    <a href="" class="item" @click.prevent="createIP">添加IP</a>
 | 
			
		||||
    <span class="item disabled">|</span>
 | 
			
		||||
    <div class="item"><ip-list-bind-box :v-http-firewall-policy-id="firewallPolicyId" :v-type="type"></ip-list-bind-box></div>
 | 
			
		||||
    <span class="item disabled">|</span>
 | 
			
		||||
    <span class="item">ID: {{listId}}   <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
 | 
			
		||||
</second-menu>
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -27,11 +27,11 @@ Tea.context(function () {
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
 | 
			
		||||
		teaweb.popup("/servers/iplists/createIPPopup?listId=" + this.listId + '&type=' + type, {
 | 
			
		||||
			height: "26em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + that.firewallPolicyId + "&type=" + type
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
 
 | 
			
		||||
@@ -37,19 +37,4 @@ Tea.context(function () {
 | 
			
		||||
			return province.isChecked
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 添加IP名单菜单
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
 | 
			
		||||
			height: "23em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + that.firewallPolicyId + "&type=" + type
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -38,7 +38,7 @@ Tea.context(function () {
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
 | 
			
		||||
		teaweb.popup("/servers/iplists/createIPPopup?listId=" + this.listId + '&type=' + type, {
 | 
			
		||||
			height: "26em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3>添加IP</h3>
 | 
			
		||||
<h3 v-if="list.type == 'white'">添加IP到白名单</h3>
 | 
			
		||||
<h3 v-if="list.type == 'black'">添加IP到黑名单</h3>
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<input type="hidden" name="listId" :value="listId"/>
 | 
			
		||||
@@ -20,34 +21,66 @@
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 | 
			
		||||
        <tr v-if="type != 'all'">
 | 
			
		||||
            <td>添加方式</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <radio name="method" value="single" :v-value="'single'" v-model="method">单个添加</radio>    
 | 
			
		||||
                <radio name="method" value="batch" :v-value="'batch'" v-model="method">批量添加</radio>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 | 
			
		||||
        <!-- 单个添加 -->
 | 
			
		||||
        <!-- IPv4 -->
 | 
			
		||||
        <tbody v-if="type == 'ipv4'">
 | 
			
		||||
        <tbody v-if="method == 'single' && type == 'ipv4'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>开始IP *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x.x.x.x" ref="focus"/>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x.x.x.x" ref="focus" style="width: 10em"/>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>结束IP</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipTo" maxlength="64" placeholder="x.x.x.x"/>
 | 
			
		||||
                    <input type="text" name="ipTo" maxlength="64" placeholder="x.x.x.x" style="width: 10em"/>
 | 
			
		||||
                    <p class="comment">表示IP段的时候需要填写此项。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <!-- IPv6 -->
 | 
			
		||||
        <tbody v-if="type == 'ipv6'">
 | 
			
		||||
        <tbody v-if="method == 'single' && type == 'ipv6'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>IP *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x:x:x:x:x:x:x:x" ref="focus"/>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x:x:x:x:x:x:x:x" ref="focus" style="width: 20em"/>
 | 
			
		||||
                    <p class="comment">IPv6地址,比如 1406:3c00:0:2409:13:58:103:15</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <!-- 批量添加 -->
 | 
			
		||||
        <!-- IPv4 -->
 | 
			
		||||
        <tbody v-if="method == 'batch' && type == 'ipv4'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>IP列表</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <textarea name="ipData" style="width: 20em" :placeholder="'x.x.x.x' + '\n'+ 'x.x.x.x/24' + '\n' + 'x.x.x.x-y.y.y.y'" rows="3"></textarea>
 | 
			
		||||
                    <p class="comment">每行一个IP,支持三种格式:<code-label :class="'grey'">192.168.1.1</code-label>、<code-label :class="'grey'">192.168.1.1/24</code-label>、<code-label :class="'grey'">192.168.1.1-192.168.1.255</code-label>。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <!-- IPv6 -->
 | 
			
		||||
        <tbody v-if="method == 'batch' && type == 'ipv6'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>IP列表</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <textarea name="ipData" style="width: 20em" :placeholder="'x:x:x:x:x:x:x:x'" rows="3"></textarea>
 | 
			
		||||
                    <p class="comment">每行一个IP。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>级别</td>
 | 
			
		||||
            <td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
    this.type = "ipv4"
 | 
			
		||||
    this.eventLevel = (this.listType == "white") ? "debug" : "critical"
 | 
			
		||||
	this.method = "single"
 | 
			
		||||
})
 | 
			
		||||
@@ -10,9 +10,9 @@
 | 
			
		||||
    <second-menu>
 | 
			
		||||
        <menu-item @click.prevent="createIP('white')">添加IP</menu-item>
 | 
			
		||||
        <span class="item">|</span>
 | 
			
		||||
        <span class="item">ID: {{listId}}   <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
 | 
			
		||||
        <span class="item">|</span>
 | 
			
		||||
        <div class="item"><ip-list-bind-box :v-http-firewall-policy-id="firewallPolicyId" :v-type="'white'"></ip-list-bind-box></div>
 | 
			
		||||
        <span class="item">|</span>
 | 
			
		||||
        <span class="item">ID: {{listId}}   <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
 | 
			
		||||
    </second-menu>
 | 
			
		||||
 | 
			
		||||
    <warning-message v-if="!wafIsOn">当前WAF未启用,设置将在<a :href="'/servers/server/settings/waf?serverId=' + serverId">[启用]</a>后生效。</warning-message>
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ Tea.context(function () {
 | 
			
		||||
	 * 添加IP名单菜单
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
 | 
			
		||||
		teaweb.popup("/servers/iplists/createIPPopup?listId=" + this.listId + '&type=' + type, {
 | 
			
		||||
			height: "26em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
 
 | 
			
		||||
@@ -51,19 +51,4 @@ Tea.context(function () {
 | 
			
		||||
			return country.isChecked
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 添加IP名单菜单
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
 | 
			
		||||
			height: "30em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + that.firewallPolicyId + "&type=" + type
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3 v-if="listType == 'white'">添加IP到白名单</h3>
 | 
			
		||||
<h3 v-if="listType == 'black'">添加IP到黑名单</h3>
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<input type="hidden" name="listId" :value="listId"/>
 | 
			
		||||
	<csrf-token></csrf-token>
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">类型 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <select class="ui dropdown auto-width" name="type" v-model="type">
 | 
			
		||||
                    <option value="ipv4">IPv4</option>
 | 
			
		||||
                    <option value="ipv6">IPv6</option>
 | 
			
		||||
                    <option value="all">所有IP</option>
 | 
			
		||||
                </select>
 | 
			
		||||
                <p class="comment" v-if="type == 'ipv4'">单个IPv4或一个IPv4范围。</p>
 | 
			
		||||
                <p class="comment" v-if="type == 'ipv6'">单个IPv6。</p>
 | 
			
		||||
                <p class="comment" v-if="type == 'all'">允许或禁用所有的IP。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 | 
			
		||||
        <!-- IPv4 -->
 | 
			
		||||
        <tbody v-if="type == 'ipv4'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>开始IP *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x.x.x.x" ref="focus"/>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>结束IP</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipTo" maxlength="64" placeholder="x.x.x.x"/>
 | 
			
		||||
                    <p class="comment">表示IP段的时候需要填写此项。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <!-- IPv6 -->
 | 
			
		||||
        <tbody v-if="type == 'ipv6'">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>IP *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="ipFrom" maxlength="64" placeholder="x:x:x:x:x:x:x:x" ref="focus"/>
 | 
			
		||||
                    <p class="comment">IPv6地址,比如 1406:3c00:0:2409:13:58:103:15</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>级别</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <firewall-event-level-options :v-value="eventLevel"></firewall-event-level-options>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>过期时间</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<datetime-input :v-name="'expiredAt'"></datetime-input>
 | 
			
		||||
					<p class="comment">在加入名单某一段时间后会失效,留空表示永久有效。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>备注</td>
 | 
			
		||||
				<td><input type="text" name="reason" maxlength="100"/></td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
    this.type = "ipv4"
 | 
			
		||||
    this.eventLevel = (this.listType == "white") ? "debug" : "critical"
 | 
			
		||||
})
 | 
			
		||||
@@ -10,9 +10,9 @@
 | 
			
		||||
    <second-menu>
 | 
			
		||||
        <menu-item @click.prevent="createIP('black')">添加IP</menu-item>
 | 
			
		||||
        <span class="item">|</span>
 | 
			
		||||
        <span class="item">ID: {{listId}}   <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
 | 
			
		||||
        <span class="item">|</span>
 | 
			
		||||
        <div class="item"><ip-list-bind-box :v-http-firewall-policy-id="firewallPolicyId" :v-type="'black'"></ip-list-bind-box></div>
 | 
			
		||||
        <span class="item">|</span>
 | 
			
		||||
        <span class="item">ID: {{listId}}   <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
 | 
			
		||||
    </second-menu>
 | 
			
		||||
 | 
			
		||||
    <warning-message v-if="!wafIsOn">当前WAF未启用,设置将在<a :href="'/servers/server/settings/waf?serverId=' + serverId">[启用]</a>后生效。</warning-message>
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ Tea.context(function () {
 | 
			
		||||
	 * 添加IP名单菜单
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
 | 
			
		||||
		teaweb.popup("/servers/iplists/createIPPopup?listId=" + this.listId + '&type=' + type, {
 | 
			
		||||
			height: "26em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
 
 | 
			
		||||
@@ -37,19 +37,4 @@ Tea.context(function () {
 | 
			
		||||
			return province.isChecked
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 添加IP名单菜单
 | 
			
		||||
	 */
 | 
			
		||||
	this.createIP = function (type) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
 | 
			
		||||
			height: "30em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + that.firewallPolicyId + "&type=" + type
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
		Reference in New Issue
	
	Block a user