修复升级后数据库密码字段字符限制的Bug

This commit is contained in:
wsczx 2025-02-14 18:38:25 +08:00
parent a01e3be115
commit 7c7405a47b
7 changed files with 69 additions and 207 deletions

View File

@ -304,7 +304,7 @@ func SetGroup(g *Group) error {
return err
}
if err := auth.saveUsers(g); err != nil {
return fmt.Errorf("保存ldap用户 %s 失败", err.Error())
return err
}
// 重置Auth 删除多余的key
g.Auth = map[string]interface{}{

View File

@ -43,22 +43,22 @@ func TestGetGroupNames(t *testing.T) {
err = SetGroup(&g6)
ast.Nil(err)
authData = map[string]interface{}{
"type": "ldap",
"ldap": map[string]interface{}{
"addr": "192.168.8.12:389",
"tls": true,
"bind_name": "userfind@abc.com",
"bind_pwd": "afdbfdsafds",
"base_dn": "dc=abc,dc=com",
"object_class": "person",
"search_attr": "sAMAccountName",
"member_of": "cn=vpn,cn=user,dc=abc,dc=com",
},
}
g7 := Group{Name: "g7", ClientDns: []ValData{{Val: "114.114.114.114"}}, Auth: authData}
err = SetGroup(&g7)
ast.Nil(err)
// authData = map[string]interface{}{
// "type": "ldap",
// "ldap": map[string]interface{}{
// "addr": "192.168.8.12:389",
// "tls": true,
// "bind_name": "userfind@abc.com",
// "bind_pwd": "afdbfdsafds",
// "base_dn": "dc=abc,dc=com",
// "object_class": "person",
// "search_attr": "sAMAccountName",
// "member_of": "cn=vpn,cn=user,dc=abc,dc=com",
// },
// }
// g7 := Group{Name: "g7", ClientDns: []ValData{{Val: "114.114.114.114"}}, Auth: authData}
// err = SetGroup(&g7)
// ast.Nil(err)
// 判断所有数据
gAll := []string{"g1", "g2", "g3", "g4", "g5", "g6", "g7"}

View File

@ -31,7 +31,7 @@ type User struct {
Nickname string `json:"nickname" xorm:"varchar(255)"`
Email string `json:"email" xorm:"varchar(255)"`
// Password string `json:"password"`
PinCode string `json:"pin_code" xorm:"varchar(32)"`
PinCode string `json:"pin_code" xorm:"varchar(60)"`
LimitTime *time.Time `json:"limittime,omitempty" xorm:"Datetime limittime"` // 值为null时前端不显示
OtpSecret string `json:"otp_secret" xorm:"varchar(255)"`
DisableOtp bool `json:"disable_otp" xorm:"Bool"` // 禁用otp

View File

@ -35,56 +35,56 @@ func TestCheckUser(t *testing.T) {
// err = CheckUser("aaa", u.PinCode+secret, group)
// ast.Nil(err)
// 单独验证密码
u.DisableOtp = true
_ = SetUser(&u)
err = CheckUser("aaa", pincode, group)
ast.Nil(err)
// // 单独验证密码
// u.DisableOtp = true
// _ = SetUser(&u)
// err = CheckUser("aaa", pincode, group)
// ast.Nil(err)
// 添加一个radius组
group2 := "group2"
authData := map[string]interface{}{
"type": "radius",
"radius": map[string]string{
"addr": "192.168.1.12:1044",
"secret": "43214132",
},
}
g2 := Group{Name: group2, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData}
err = SetGroup(&g2)
ast.Nil(err)
err = CheckUser("aaa", "bbbbbbb", group2)
if ast.NotNil(err) {
ast.Equal("aaa Radius服务器连接异常, 请检测服务器和端口", err.Error())
}
// 添加用户策略
dns2 := []ValData{{Val: "8.8.8.8"}}
route2 := []ValData{{Val: "192.168.2.0/24"}}
p1 := Policy{Username: "aaa", Status: 1, ClientDns: dns2, RouteInclude: route2}
err = SetPolicy(&p1)
ast.Nil(err)
err = CheckUser("aaa", pincode, group)
ast.Nil(err)
// 添加一个ldap组
group3 := "group3"
authData = map[string]interface{}{
"type": "ldap",
"ldap": map[string]interface{}{
"addr": "192.168.8.12:389",
"tls": true,
"bind_name": "userfind@abc.com",
"bind_pwd": "afdbfdsafds",
"base_dn": "dc=abc,dc=com",
"object_class": "person",
"search_attr": "sAMAccountName",
"member_of": "cn=vpn,cn=user,dc=abc,dc=com",
},
}
g3 := Group{Name: group3, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData}
err = SetGroup(&g3)
ast.Nil(err)
err = CheckUser("aaa", "bbbbbbb", group3)
if ast.NotNil(err) {
ast.Equal("aaa LDAP服务器连接异常, 请检测服务器和端口", err.Error())
}
// // 添加一个radius组
// group2 := "group2"
// authData := map[string]interface{}{
// "type": "radius",
// "radius": map[string]string{
// "addr": "192.168.1.12:1044",
// "secret": "43214132",
// },
// }
// g2 := Group{Name: group2, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData}
// err = SetGroup(&g2)
// ast.Nil(err)
// err = CheckUser("aaa", "bbbbbbb", group2)
// if ast.NotNil(err) {
// ast.Equal("aaa Radius服务器连接异常, 请检测服务器和端口", err.Error())
// }
// // 添加用户策略
// dns2 := []ValData{{Val: "8.8.8.8"}}
// route2 := []ValData{{Val: "192.168.2.0/24"}}
// p1 := Policy{Username: "aaa", Status: 1, ClientDns: dns2, RouteInclude: route2}
// err = SetPolicy(&p1)
// ast.Nil(err)
// err = CheckUser("aaa", pincode, group)
// ast.Nil(err)
// // 添加一个ldap组
// group3 := "group3"
// authData = map[string]interface{}{
// "type": "ldap",
// "ldap": map[string]interface{}{
// "addr": "192.168.8.12:389",
// "tls": true,
// "bind_name": "userfind@abc.com",
// "bind_pwd": "afdbfdsafds",
// "base_dn": "dc=abc,dc=com",
// "object_class": "person",
// "search_attr": "sAMAccountName",
// "member_of": "cn=vpn,cn=user,dc=abc,dc=com",
// },
// }
// g3 := Group{Name: group3, Status: 1, ClientDns: dns, RouteInclude: route, Auth: authData}
// err = SetGroup(&g3)
// ast.Nil(err)
// err = CheckUser("aaa", "bbbbbbb", group3)
// if ast.NotNil(err) {
// ast.Equal("aaa LDAP服务器连接异常, 请检测服务器和端口", err.Error())
// }
}

View File

@ -1,121 +0,0 @@
package handler
import (
"context"
"encoding/xml"
"io"
"net"
"net/http"
"strings"
"time"
"github.com/bjdgyc/anylink/base"
)
// var lockManager = admin.GetLockManager()
const loginStatusKey = "login_status"
type HttpContext struct {
LoginStatus bool // 登录状态
}
// 防爆破中间件
func antiBruteForce(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, old_r *http.Request) {
// 防爆破功能全局开关
if !base.Cfg.AntiBruteForce {
next.ServeHTTP(w, old_r)
return
}
// 非并发安全
hc := &HttpContext{}
ctx := context.WithValue(context.Background(), loginStatusKey, hc)
r := old_r.WithContext(ctx)
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Failed to read request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
cr := ClientRequest{}
err = xml.Unmarshal(body, &cr)
if err != nil {
http.Error(w, "Failed to parse XML", http.StatusBadRequest)
return
}
username := cr.Auth.Username
if r.URL.Path == "/otp-verification" {
sessionID, err := GetCookie(r, "auth-session-id")
if err != nil {
http.Error(w, "Invalid session, please login again", http.StatusUnauthorized)
return
}
sessionData, err := SessStore.GetAuthSession(sessionID)
if err != nil {
http.Error(w, "Invalid session, please login again", http.StatusUnauthorized)
return
}
username = sessionData.ClientRequest.Auth.Username
}
ip, _, err := net.SplitHostPort(r.RemoteAddr) // 提取纯 IP 地址,去掉端口号
if err != nil {
http.Error(w, "Unable to parse IP address", http.StatusInternalServerError)
return
}
now := time.Now()
// 检查IP是否在白名单中
if lockManager.IsWhitelisted(ip) {
r.Body = io.NopCloser(strings.NewReader(string(body)))
next.ServeHTTP(w, r)
return
}
// 检查全局 IP 锁定
if base.Cfg.MaxGlobalIPBanCount > 0 && lockManager.CheckGlobalIPLock(ip, now) {
base.Warn("IP", ip, "is globally locked. Try again later.")
http.Error(w, "Account globally locked due to too many failed attempts. Try again later.", http.StatusTooManyRequests)
return
}
// 检查全局用户锁定
if base.Cfg.MaxGlobalUserBanCount > 0 && lockManager.CheckGlobalUserLock(username, now) {
base.Warn("User", username, "is globally locked. Try again later.")
http.Error(w, "Account globally locked due to too many failed attempts. Try again later.", http.StatusTooManyRequests)
return
}
// 检查单个用户的 IP 锁定
if base.Cfg.MaxBanCount > 0 && lockManager.CheckUserIPLock(username, ip, now) {
base.Warn("IP", ip, "is locked for user", username, "Try again later.")
http.Error(w, "Account locked due to too many failed attempts. Try again later.", http.StatusTooManyRequests)
return
}
// 重新设置请求体以便后续处理器可以访问
r.Body = io.NopCloser(strings.NewReader(string(body)))
// 调用下一个处理器
next.ServeHTTP(w, r)
// 检查登录状态
// Status, _ := lockManager.LoginStatus.Load(loginStatusKey)
// loginStatus, _ := Status.(bool)
loginStatus := hc.LoginStatus
// 更新用户登录状态
lockManager.UpdateGlobalIPLock(ip, now, loginStatus)
lockManager.UpdateGlobalUserLock(username, now, loginStatus)
lockManager.UpdateUserIPLock(username, ip, now, loginStatus)
// 清除登录状态
// lockManager.LoginStatus.Delete(loginStatusKey)
})
}

View File

@ -102,9 +102,6 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
ext := map[string]interface{}{"mac_addr": cr.MacAddressList.MacAddress}
err = dbdata.CheckUser(cr.Auth.Username, cr.Auth.Password, cr.GroupSelect, ext)
if err != nil {
// lockManager.LoginStatus.Store(loginStatusKey, false) // 记录登录失败状态
// hc := r.Context().Value(loginStatusKey).(*HttpContext)
// hc.LoginStatus = false
lockManager.UpdateLoginStatus(cr.Auth.Username, r.RemoteAddr, false) // 记录登录失败状态
base.Warn(err, r.RemoteAddr)
@ -131,9 +128,6 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
}
// 用户otp验证
if base.Cfg.AuthAloneOtp && !v.DisableOtp {
// lockManager.LoginStatus.Store(loginStatusKey, true) // 重置OTP验证计数
// hc := r.Context().Value(loginStatusKey).(*HttpContext)
// hc.LoginStatus = true
lockManager.UpdateLoginStatus(cr.Auth.Username, r.RemoteAddr, true) // 重置OTP验证计数
sessionID, err := GenerateSessionID()

View File

@ -111,9 +111,6 @@ func DeleteCookie(w http.ResponseWriter, name string) {
http.SetCookie(w, cookie)
}
func CreateSession(w http.ResponseWriter, r *http.Request, authSession *AuthSession) {
// lockManager.LoginStatus.Store(loginStatusKey, true) // 更新登录成功状态
// hc := r.Context().Value(loginStatusKey).(*HttpContext)
// hc.LoginStatus = true
cr := authSession.ClientRequest
ua := authSession.UserActLog
@ -208,14 +205,6 @@ func LinkAuth_otp(w http.ResponseWriter, r *http.Request) {
// 动态码错误
if !dbdata.CheckOtp(username, otp, otpSecret) {
// if sessionData.AddOtpErrCount(1) > maxOtpErrCount {
// SessStore.DeleteAuthSession(sessionID)
// http.Error(w, "TooManyError, please login again", http.StatusBadRequest)
// return
// }
// lockManager.LoginStatus.Store(loginStatusKey, false) // 记录登录失败状态
// hc := r.Context().Value(loginStatusKey).(*HttpContext)
// hc.LoginStatus = false
lockManager.UpdateLoginStatus(username, r.RemoteAddr, false) // 记录登录失败状态
base.Warn("OTP 动态码错误", username, r.RemoteAddr)