diff --git a/lib/midware/arrow_ip_addr.go b/lib/midware/arrow_ip_addr.go new file mode 100644 index 00000000..3302070c --- /dev/null +++ b/lib/midware/arrow_ip_addr.go @@ -0,0 +1,124 @@ +package midware + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + "ems.agt/lib/dborm" + "ems.agt/lib/services" +) + +// 登录策略限制登录时间和访问ip范围 +func ArrowIPAddr(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Println(" From Host:", r.RemoteAddr) + ipAddr := strings.Split(r.RemoteAddr, ":")[0] + + // 读取配置信息 登录策略设置 + result, err := dborm.XormGetConfig("Security", "loginSecurity") + if err != nil { + next.ServeHTTP(w, r) + return + } + data := make(map[string]any) + err = json.Unmarshal([]byte(result["value_json"].(string)), &data) + if err != nil { + next.ServeHTTP(w, r) + return + } + startIP := data["start_IP"].(string) + endIP := data["end_IP"].(string) + logintimeRange := data["logintime_range"].(string) + + // 检查ip + okPer3 := parsePer3(ipAddr, startIP, endIP) + if !okPer3 { + services.ResponseErrorWithJson(w, 502, "网关登录策略-IP限制") + return + } + okLast4 := parseLast4(ipAddr, startIP, endIP) + if !okLast4 { + services.ResponseErrorWithJson(w, 502, "网关登录策略-IP限制") + return + } + + // 检查开放时间 + logintimeRangeArr := strings.Split(logintimeRange, " - ") + + // 加载中国时区 + loc, _ := time.LoadLocation("Asia/Shanghai") + // 获取当前时间 + currentTime := time.Now().In(loc) + + // 获取当前日期 + currentDate := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location()) + ymd := currentDate.Format("2006-01-02") + + // 定义开始时间和结束时间 + startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", ymd+" "+logintimeRangeArr[0], loc) + endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", ymd+" "+logintimeRangeArr[1], loc) + + // 判断当前时间是否在范围内 + if currentTime.After(startTime) && currentTime.Before(endTime) { + next.ServeHTTP(w, r) + } else { + services.ResponseErrorWithJson(w, 502, "网关登录策略-不在开放时间范围内") + } + }) +} + +// 判断第四位网段 ?.?.?.x +func parseLast4(ipAddr, startIP, endIP string) bool { + ipLastIdx := strings.LastIndex(ipAddr, ".") + ipLastStr := ipAddr[ipLastIdx+1:] + ipLastInt, err := strconv.Atoi(ipLastStr) + if err != nil { + ipLastInt = 0 + } + + startIPLastIdx := strings.LastIndex(startIP, ".") + startIPLastStr := ipAddr[startIPLastIdx+1:] + startIPLastInt, err := strconv.Atoi(startIPLastStr) + if err != nil { + startIPLastInt = 0 + } + + if ipLastInt >= startIPLastInt { + return true + } + + endIPLastIdx := strings.LastIndex(endIP, ".") + endIPLastStr := ipAddr[endIPLastIdx+1:] + endIPLastInt, err := strconv.Atoi(endIPLastStr) + if err != nil { + endIPLastInt = 0 + } + + if ipLastInt >= endIPLastInt { + return true + } + return false +} + +// 判断前三位网段 x.x.x.? +func parsePer3(ipAddr, startIP, endIP string) bool { + ipPerIdx := strings.LastIndex(ipAddr, ".") + ipPerStr := ipAddr[:ipPerIdx] + + startIPPerIdx := strings.LastIndex(startIP, ".") + startIPPerStr := startIP[:startIPPerIdx] + if ipPerStr == startIPPerStr { + return true + } + + endIPPerIdx := strings.LastIndex(endIP, ".") + endIPPerStr := endIP[:endIPPerIdx] + if ipPerStr == endIPPerStr { + return true + } + return false +} diff --git a/lib/routes/routes.go b/lib/routes/routes.go index fb080b03..c7ad6ec7 100644 --- a/lib/routes/routes.go +++ b/lib/routes/routes.go @@ -265,6 +265,7 @@ func NewRouter() *mux.Router { r.Use(midware.LoggerTrace) r.Use(midware.OptionProcess) + r.Use(midware.ArrowIPAddr) for _, router := range routers { r.Methods(router.Method).