diff options
Diffstat (limited to 'web/service')
| -rw-r--r-- | web/service/inbound.go | 17 | ||||
| -rw-r--r-- | web/service/setting.go | 102 | ||||
| -rw-r--r-- | web/service/user.go | 37 |
3 files changed, 152 insertions, 4 deletions
diff --git a/web/service/inbound.go b/web/service/inbound.go index 448e6832..93414801 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1569,6 +1569,23 @@ 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 +} + func (s *InboundService) ResetClientIpLimitByEmail(clientEmail string, count int) (bool, error) { _, inbound, err := s.GetClientInboundByEmail(clientEmail) if err != nil { diff --git a/web/service/setting.go b/web/service/setting.go index fc6513c5..fa85d58c 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -73,6 +73,27 @@ var defaultValueMap = map[string]string{ "warp": "", "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", } // SettingService provides business logic for application settings management. @@ -542,6 +563,87 @@ func (s *SettingService) GetIpLimitEnable() (bool, error) { return (accessLogPath != "none" && accessLogPath != ""), nil } +// LDAP exported getters +func (s *SettingService) GetLdapEnable() (bool, error) { + return s.getBool("ldapEnable") +} + +func (s *SettingService) GetLdapHost() (string, error) { + return s.getString("ldapHost") +} + +func (s *SettingService) GetLdapPort() (int, error) { + return s.getInt("ldapPort") +} + +func (s *SettingService) GetLdapUseTLS() (bool, error) { + return s.getBool("ldapUseTLS") +} + +func (s *SettingService) GetLdapBindDN() (string, error) { + return s.getString("ldapBindDN") +} + +func (s *SettingService) GetLdapPassword() (string, error) { + return s.getString("ldapPassword") +} + +func (s *SettingService) GetLdapBaseDN() (string, error) { + return s.getString("ldapBaseDN") +} + +func (s *SettingService) GetLdapUserFilter() (string, error) { + return s.getString("ldapUserFilter") +} + +func (s *SettingService) GetLdapUserAttr() (string, error) { + return s.getString("ldapUserAttr") +} + +func (s *SettingService) GetLdapVlessField() (string, error) { + return s.getString("ldapVlessField") +} + +func (s *SettingService) GetLdapSyncCron() (string, error) { + return s.getString("ldapSyncCron") +} + +func (s *SettingService) GetLdapFlagField() (string, error) { + return s.getString("ldapFlagField") +} + +func (s *SettingService) GetLdapTruthyValues() (string, error) { + return s.getString("ldapTruthyValues") +} + +func (s *SettingService) GetLdapInvertFlag() (bool, error) { + return s.getBool("ldapInvertFlag") +} + +func (s *SettingService) GetLdapInboundTags() (string, error) { + return s.getString("ldapInboundTags") +} + +func (s *SettingService) GetLdapAutoCreate() (bool, error) { + return s.getBool("ldapAutoCreate") +} + +func (s *SettingService) GetLdapAutoDelete() (bool, error) { + return s.getBool("ldapAutoDelete") +} + +func (s *SettingService) GetLdapDefaultTotalGB() (int, error) { + return s.getInt("ldapDefaultTotalGB") +} + +func (s *SettingService) GetLdapDefaultExpiryDays() (int, error) { + return s.getInt("ldapDefaultExpiryDays") +} + +func (s *SettingService) GetLdapDefaultLimitIP() (int, error) { + return s.getInt("ldapDefaultLimitIP") +} + func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error { if err := allSetting.CheckValid(); err != nil { return err diff --git a/web/service/user.go b/web/service/user.go index f42c3cf8..87c46bf2 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" "github.com/xlzd/gotp" "gorm.io/gorm" ) @@ -49,9 +49,38 @@ func (s *UserService) CheckUser(username string, password string, twoFactorCode return nil } - if !crypto.CheckPasswordHash(user.Password, password) { - 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() + + 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 { |
