From 713a7328f60eec94c56b7ad6d17a942dffcfd944 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Tue, 21 Oct 2025 13:02:55 +0200 Subject: [PATCH] gofmt --- util/ldap/ldap.go | 238 ++++++++++++++++++++--------------------- web/entity/entity.go | 44 ++++---- web/service/inbound.go | 25 +++-- web/service/setting.go | 80 +++++++------- web/service/user.go | 62 +++++------ 5 files changed, 223 insertions(+), 226 deletions(-) diff --git a/util/ldap/ldap.go b/util/ldap/ldap.go index 1c7a20e7..795d0e23 100644 --- a/util/ldap/ldap.go +++ b/util/ldap/ldap.go @@ -1,144 +1,142 @@ package ldaputil import ( - "crypto/tls" - "fmt" + "crypto/tls" + "fmt" - "github.com/go-ldap/ldap/v3" + "github.com/go-ldap/ldap/v3" ) type Config struct { - Host string - Port int - UseTLS bool - BindDN string - Password string - BaseDN string - UserFilter string - UserAttr string - FlagField string - TruthyVals []string - Invert bool + Host string + Port int + UseTLS bool + BindDN string + Password string + BaseDN string + UserFilter string + UserAttr string + FlagField string + TruthyVals []string + Invert bool } // FetchVlessFlags returns map[email]enabled func FetchVlessFlags(cfg Config) (map[string]bool, error) { - addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) - var conn *ldap.Conn - var err error - if cfg.UseTLS { - conn, err = ldap.DialTLS("tcp", addr, &tls.Config{InsecureSkipVerify: false}) - } else { - conn, err = ldap.Dial("tcp", addr) - } - if err != nil { - return nil, err - } - defer conn.Close() + addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) + var conn *ldap.Conn + var err error + if cfg.UseTLS { + conn, err = ldap.DialTLS("tcp", addr, &tls.Config{InsecureSkipVerify: false}) + } else { + conn, err = ldap.Dial("tcp", addr) + } + if err != nil { + return nil, err + } + defer conn.Close() - if cfg.BindDN != "" { - if err := conn.Bind(cfg.BindDN, cfg.Password); err != nil { - return nil, err - } - } + if cfg.BindDN != "" { + if err := conn.Bind(cfg.BindDN, cfg.Password); err != nil { + return nil, err + } + } - if cfg.UserFilter == "" { - cfg.UserFilter = "(objectClass=person)" - } - if cfg.UserAttr == "" { - cfg.UserAttr = "mail" - } - // if field not set we fallback to legacy vless_enabled - if cfg.FlagField == "" { - cfg.FlagField = "vless_enabled" - } + if cfg.UserFilter == "" { + cfg.UserFilter = "(objectClass=person)" + } + if cfg.UserAttr == "" { + cfg.UserAttr = "mail" + } + // if field not set we fallback to legacy vless_enabled + if cfg.FlagField == "" { + cfg.FlagField = "vless_enabled" + } - req := ldap.NewSearchRequest( - cfg.BaseDN, - ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - cfg.UserFilter, - []string{cfg.UserAttr, cfg.FlagField}, - nil, - ) + req := ldap.NewSearchRequest( + cfg.BaseDN, + ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, + cfg.UserFilter, + []string{cfg.UserAttr, cfg.FlagField}, + nil, + ) - res, err := conn.Search(req) - if err != nil { - return nil, err - } + res, err := conn.Search(req) + if err != nil { + return nil, err + } - result := make(map[string]bool, len(res.Entries)) - for _, e := range res.Entries { - user := e.GetAttributeValue(cfg.UserAttr) - if user == "" { - continue - } - val := e.GetAttributeValue(cfg.FlagField) - enabled := false - for _, t := range cfg.TruthyVals { - if val == t { - enabled = true - break - } - } - if cfg.Invert { - enabled = !enabled - } - result[user] = enabled - } - return result, nil + result := make(map[string]bool, len(res.Entries)) + for _, e := range res.Entries { + user := e.GetAttributeValue(cfg.UserAttr) + if user == "" { + continue + } + val := e.GetAttributeValue(cfg.FlagField) + enabled := false + for _, t := range cfg.TruthyVals { + if val == t { + enabled = true + break + } + } + if cfg.Invert { + enabled = !enabled + } + result[user] = enabled + } + return result, nil } // AuthenticateUser searches user by cfg.UserAttr and attempts to bind with provided password. func AuthenticateUser(cfg Config, username, password string) (bool, error) { - addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) - var conn *ldap.Conn - var err error - if cfg.UseTLS { - conn, err = ldap.DialTLS("tcp", addr, &tls.Config{InsecureSkipVerify: false}) - } else { - conn, err = ldap.Dial("tcp", addr) - } - if err != nil { - return false, err - } - defer conn.Close() + addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) + var conn *ldap.Conn + var err error + if cfg.UseTLS { + conn, err = ldap.DialTLS("tcp", addr, &tls.Config{InsecureSkipVerify: false}) + } else { + conn, err = ldap.Dial("tcp", addr) + } + if err != nil { + return false, err + } + defer conn.Close() - // Optional initial bind for search - if cfg.BindDN != "" { - if err := conn.Bind(cfg.BindDN, cfg.Password); err != nil { - return false, err - } - } + // Optional initial bind for search + if cfg.BindDN != "" { + if err := conn.Bind(cfg.BindDN, cfg.Password); err != nil { + return false, err + } + } - if cfg.UserFilter == "" { - cfg.UserFilter = "(objectClass=person)" - } - if cfg.UserAttr == "" { - cfg.UserAttr = "uid" - } + if cfg.UserFilter == "" { + cfg.UserFilter = "(objectClass=person)" + } + if cfg.UserAttr == "" { + cfg.UserAttr = "uid" + } - // Build filter to find specific user - filter := fmt.Sprintf("(&%s(%s=%s))", cfg.UserFilter, cfg.UserAttr, ldap.EscapeFilter(username)) - req := ldap.NewSearchRequest( - cfg.BaseDN, - ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 1, 0, false, - filter, - []string{"dn"}, - nil, - ) - res, err := conn.Search(req) - if err != nil { - return false, err - } - if len(res.Entries) == 0 { - return false, nil - } - userDN := res.Entries[0].DN - // Try to bind as the user - if err := conn.Bind(userDN, password); err != nil { - return false, nil - } - return true, nil + // Build filter to find specific user + filter := fmt.Sprintf("(&%s(%s=%s))", cfg.UserFilter, cfg.UserAttr, ldap.EscapeFilter(username)) + req := ldap.NewSearchRequest( + cfg.BaseDN, + ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 1, 0, false, + filter, + []string{"dn"}, + nil, + ) + res, err := conn.Search(req) + if err != nil { + return false, err + } + if len(res.Entries) == 0 { + return false, nil + } + userDN := res.Entries[0].DN + // Try to bind as the user + if err := conn.Bind(userDN, password); err != nil { + return false, nil + } + return true, nil } - - diff --git a/web/entity/entity.go b/web/entity/entity.go index de054e2b..42e2df85 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -74,30 +74,30 @@ type AllSetting struct { SubJsonFragment string `json:"subJsonFragment" form:"subJsonFragment"` // JSON subscription fragment configuration SubJsonNoises string `json:"subJsonNoises" form:"subJsonNoises"` // JSON subscription noise configuration SubJsonMux string `json:"subJsonMux" form:"subJsonMux"` // JSON subscription mux configuration - SubJsonRules string `json:"subJsonRules" form:"subJsonRules"` - + SubJsonRules string `json:"subJsonRules" form:"subJsonRules"` + // LDAP settings - LdapEnable bool `json:"ldapEnable" form:"ldapEnable"` - LdapHost string `json:"ldapHost" form:"ldapHost"` - LdapPort int `json:"ldapPort" form:"ldapPort"` - LdapUseTLS bool `json:"ldapUseTLS" form:"ldapUseTLS"` - LdapBindDN string `json:"ldapBindDN" form:"ldapBindDN"` - LdapPassword string `json:"ldapPassword" form:"ldapPassword"` - LdapBaseDN string `json:"ldapBaseDN" form:"ldapBaseDN"` - LdapUserFilter string `json:"ldapUserFilter" form:"ldapUserFilter"` - LdapUserAttr string `json:"ldapUserAttr" form:"ldapUserAttr"` // e.g., mail or uid - LdapVlessField string `json:"ldapVlessField" form:"ldapVlessField"` - LdapSyncCron string `json:"ldapSyncCron" form:"ldapSyncCron"` + LdapEnable bool `json:"ldapEnable" form:"ldapEnable"` + LdapHost string `json:"ldapHost" form:"ldapHost"` + LdapPort int `json:"ldapPort" form:"ldapPort"` + LdapUseTLS bool `json:"ldapUseTLS" form:"ldapUseTLS"` + LdapBindDN string `json:"ldapBindDN" form:"ldapBindDN"` + LdapPassword string `json:"ldapPassword" form:"ldapPassword"` + LdapBaseDN string `json:"ldapBaseDN" form:"ldapBaseDN"` + LdapUserFilter string `json:"ldapUserFilter" form:"ldapUserFilter"` + LdapUserAttr string `json:"ldapUserAttr" form:"ldapUserAttr"` // e.g., mail or uid + LdapVlessField string `json:"ldapVlessField" form:"ldapVlessField"` + LdapSyncCron string `json:"ldapSyncCron" form:"ldapSyncCron"` // Generic flag configuration - LdapFlagField string `json:"ldapFlagField" form:"ldapFlagField"` - LdapTruthyValues string `json:"ldapTruthyValues" form:"ldapTruthyValues"` - LdapInvertFlag bool `json:"ldapInvertFlag" form:"ldapInvertFlag"` - LdapInboundTags string `json:"ldapInboundTags" form:"ldapInboundTags"` - LdapAutoCreate bool `json:"ldapAutoCreate" form:"ldapAutoCreate"` - LdapAutoDelete bool `json:"ldapAutoDelete" form:"ldapAutoDelete"` - LdapDefaultTotalGB int `json:"ldapDefaultTotalGB" form:"ldapDefaultTotalGB"` - LdapDefaultExpiryDays int `json:"ldapDefaultExpiryDays" form:"ldapDefaultExpiryDays"` - LdapDefaultLimitIP int `json:"ldapDefaultLimitIP" form:"ldapDefaultLimitIP"` + LdapFlagField string `json:"ldapFlagField" form:"ldapFlagField"` + LdapTruthyValues string `json:"ldapTruthyValues" form:"ldapTruthyValues"` + LdapInvertFlag bool `json:"ldapInvertFlag" form:"ldapInvertFlag"` + LdapInboundTags string `json:"ldapInboundTags" form:"ldapInboundTags"` + LdapAutoCreate bool `json:"ldapAutoCreate" form:"ldapAutoCreate"` + LdapAutoDelete bool `json:"ldapAutoDelete" form:"ldapAutoDelete"` + LdapDefaultTotalGB int `json:"ldapDefaultTotalGB" form:"ldapDefaultTotalGB"` + LdapDefaultExpiryDays int `json:"ldapDefaultExpiryDays" form:"ldapDefaultExpiryDays"` + LdapDefaultLimitIP int `json:"ldapDefaultLimitIP" form:"ldapDefaultLimitIP"` // JSON subscription routing rules } diff --git a/web/service/inbound.go b/web/service/inbound.go index 93414801..66e87a4f 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1569,21 +1569,20 @@ func (s *InboundService) ToggleClientEnableByEmail(clientEmail string) (bool, bo return !clientOldEnabled, needRestart, nil } - // SetClientEnableByEmail sets client enable state to desired value; returns (changed, needRestart, error) func (s *InboundService) SetClientEnableByEmail(clientEmail string, enable bool) (bool, bool, error) { - current, err := s.checkIsEnabledByEmail(clientEmail) - if err != nil { - return false, false, err - } - if current == enable { - return false, false, nil - } - newEnabled, needRestart, err := s.ToggleClientEnableByEmail(clientEmail) - if err != nil { - return false, needRestart, err - } - return newEnabled == enable, needRestart, nil + current, err := s.checkIsEnabledByEmail(clientEmail) + if err != nil { + return false, false, err + } + if current == enable { + return false, false, nil + } + newEnabled, needRestart, err := s.ToggleClientEnableByEmail(clientEmail) + if err != nil { + return false, needRestart, err + } + return newEnabled == enable, needRestart, nil } func (s *InboundService) ResetClientIpLimitByEmail(clientEmail string, count int) (bool, error) { diff --git a/web/service/setting.go b/web/service/setting.go index fa85d58c..c8ce7896 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -74,26 +74,26 @@ var defaultValueMap = map[string]string{ "externalTrafficInformEnable": "false", "externalTrafficInformURI": "", // LDAP defaults - "ldapEnable": "false", - "ldapHost": "", - "ldapPort": "389", - "ldapUseTLS": "false", - "ldapBindDN": "", - "ldapPassword": "", - "ldapBaseDN": "", - "ldapUserFilter": "(objectClass=person)", - "ldapUserAttr": "mail", - "ldapVlessField": "vless_enabled", - "ldapSyncCron": "@every 1m", - "ldapFlagField": "", - "ldapTruthyValues": "true,1,yes,on", - "ldapInvertFlag": "false", - "ldapInboundTags": "", - "ldapAutoCreate": "false", - "ldapAutoDelete": "false", - "ldapDefaultTotalGB": "0", - "ldapDefaultExpiryDays": "0", - "ldapDefaultLimitIP": "0", + "ldapEnable": "false", + "ldapHost": "", + "ldapPort": "389", + "ldapUseTLS": "false", + "ldapBindDN": "", + "ldapPassword": "", + "ldapBaseDN": "", + "ldapUserFilter": "(objectClass=person)", + "ldapUserAttr": "mail", + "ldapVlessField": "vless_enabled", + "ldapSyncCron": "@every 1m", + "ldapFlagField": "", + "ldapTruthyValues": "true,1,yes,on", + "ldapInvertFlag": "false", + "ldapInboundTags": "", + "ldapAutoCreate": "false", + "ldapAutoDelete": "false", + "ldapDefaultTotalGB": "0", + "ldapDefaultExpiryDays": "0", + "ldapDefaultLimitIP": "0", } // SettingService provides business logic for application settings management. @@ -565,83 +565,83 @@ func (s *SettingService) GetIpLimitEnable() (bool, error) { // LDAP exported getters func (s *SettingService) GetLdapEnable() (bool, error) { - return s.getBool("ldapEnable") + return s.getBool("ldapEnable") } func (s *SettingService) GetLdapHost() (string, error) { - return s.getString("ldapHost") + return s.getString("ldapHost") } func (s *SettingService) GetLdapPort() (int, error) { - return s.getInt("ldapPort") + return s.getInt("ldapPort") } func (s *SettingService) GetLdapUseTLS() (bool, error) { - return s.getBool("ldapUseTLS") + return s.getBool("ldapUseTLS") } func (s *SettingService) GetLdapBindDN() (string, error) { - return s.getString("ldapBindDN") + return s.getString("ldapBindDN") } func (s *SettingService) GetLdapPassword() (string, error) { - return s.getString("ldapPassword") + return s.getString("ldapPassword") } func (s *SettingService) GetLdapBaseDN() (string, error) { - return s.getString("ldapBaseDN") + return s.getString("ldapBaseDN") } func (s *SettingService) GetLdapUserFilter() (string, error) { - return s.getString("ldapUserFilter") + return s.getString("ldapUserFilter") } func (s *SettingService) GetLdapUserAttr() (string, error) { - return s.getString("ldapUserAttr") + return s.getString("ldapUserAttr") } func (s *SettingService) GetLdapVlessField() (string, error) { - return s.getString("ldapVlessField") + return s.getString("ldapVlessField") } func (s *SettingService) GetLdapSyncCron() (string, error) { - return s.getString("ldapSyncCron") + return s.getString("ldapSyncCron") } func (s *SettingService) GetLdapFlagField() (string, error) { - return s.getString("ldapFlagField") + return s.getString("ldapFlagField") } func (s *SettingService) GetLdapTruthyValues() (string, error) { - return s.getString("ldapTruthyValues") + return s.getString("ldapTruthyValues") } func (s *SettingService) GetLdapInvertFlag() (bool, error) { - return s.getBool("ldapInvertFlag") + return s.getBool("ldapInvertFlag") } func (s *SettingService) GetLdapInboundTags() (string, error) { - return s.getString("ldapInboundTags") + return s.getString("ldapInboundTags") } func (s *SettingService) GetLdapAutoCreate() (bool, error) { - return s.getBool("ldapAutoCreate") + return s.getBool("ldapAutoCreate") } func (s *SettingService) GetLdapAutoDelete() (bool, error) { - return s.getBool("ldapAutoDelete") + return s.getBool("ldapAutoDelete") } func (s *SettingService) GetLdapDefaultTotalGB() (int, error) { - return s.getInt("ldapDefaultTotalGB") + return s.getInt("ldapDefaultTotalGB") } func (s *SettingService) GetLdapDefaultExpiryDays() (int, error) { - return s.getInt("ldapDefaultExpiryDays") + return s.getInt("ldapDefaultExpiryDays") } func (s *SettingService) GetLdapDefaultLimitIP() (int, error) { - return s.getInt("ldapDefaultLimitIP") + return s.getInt("ldapDefaultLimitIP") } func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error { diff --git a/web/service/user.go b/web/service/user.go index 87c46bf2..1bde69f6 100644 --- a/web/service/user.go +++ b/web/service/user.go @@ -7,7 +7,7 @@ import ( "github.com/mhsanaei/3x-ui/v2/database/model" "github.com/mhsanaei/3x-ui/v2/logger" "github.com/mhsanaei/3x-ui/v2/util/crypto" - ldaputil "github.com/mhsanaei/3x-ui/v2/util/ldap" + ldaputil "github.com/mhsanaei/3x-ui/v2/util/ldap" "github.com/xlzd/gotp" "gorm.io/gorm" ) @@ -49,38 +49,38 @@ func (s *UserService) CheckUser(username string, password string, twoFactorCode return nil } - // If LDAP enabled and local password check fails, attempt LDAP auth - if !crypto.CheckPasswordHash(user.Password, password) { - ldapEnabled, _ := s.settingService.GetLdapEnable() - if !ldapEnabled { - return nil - } + // If LDAP enabled and local password check fails, attempt LDAP auth + if !crypto.CheckPasswordHash(user.Password, password) { + ldapEnabled, _ := s.settingService.GetLdapEnable() + if !ldapEnabled { + return nil + } - host, _ := s.settingService.GetLdapHost() - port, _ := s.settingService.GetLdapPort() - useTLS, _ := s.settingService.GetLdapUseTLS() - bindDN, _ := s.settingService.GetLdapBindDN() - ldapPass, _ := s.settingService.GetLdapPassword() - baseDN, _ := s.settingService.GetLdapBaseDN() - userFilter, _ := s.settingService.GetLdapUserFilter() - userAttr, _ := s.settingService.GetLdapUserAttr() + host, _ := s.settingService.GetLdapHost() + port, _ := s.settingService.GetLdapPort() + useTLS, _ := s.settingService.GetLdapUseTLS() + bindDN, _ := s.settingService.GetLdapBindDN() + ldapPass, _ := s.settingService.GetLdapPassword() + baseDN, _ := s.settingService.GetLdapBaseDN() + userFilter, _ := s.settingService.GetLdapUserFilter() + userAttr, _ := s.settingService.GetLdapUserAttr() - cfg := ldaputil.Config{ - Host: host, - Port: port, - UseTLS: useTLS, - BindDN: bindDN, - Password: ldapPass, - BaseDN: baseDN, - UserFilter: userFilter, - UserAttr: userAttr, - } - ok, err := ldaputil.AuthenticateUser(cfg, username, password) - if err != nil || !ok { - return nil - } - // On successful LDAP auth, continue 2FA checks below - } + cfg := ldaputil.Config{ + Host: host, + Port: port, + UseTLS: useTLS, + BindDN: bindDN, + Password: ldapPass, + BaseDN: baseDN, + UserFilter: userFilter, + UserAttr: userAttr, + } + ok, err := ldaputil.AuthenticateUser(cfg, username, password) + if err != nil || !ok { + return nil + } + // On successful LDAP auth, continue 2FA checks below + } twoFactorEnable, err := s.settingService.GetTwoFactorEnable() if err != nil {