diff options
| author | MHSanaei <ho3ein.sanaei@gmail.com> | 2023-07-18 02:10:22 +0300 |
|---|---|---|
| committer | MHSanaei <ho3ein.sanaei@gmail.com> | 2023-07-18 02:10:22 +0300 |
| commit | 1f78842b707a1190b6a84aded269d664254a7f1d (patch) | |
| tree | f9226bfda4856a6289a657cff21234738be4f8c3 /web/service | |
| parent | 81a057d63876df5ba69260ac6b97aeeb7964c87d (diff) | |
[feature] using xray API for inbound
Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
Diffstat (limited to 'web/service')
| -rw-r--r-- | web/service/inbound.go | 167 | ||||
| -rw-r--r-- | web/service/server.go | 11 |
2 files changed, 133 insertions, 45 deletions
diff --git a/web/service/inbound.go b/web/service/inbound.go index b278eb57..b77b2209 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" "time" - "x-ui/database" "x-ui/database/model" "x-ui/logger" @@ -75,6 +74,7 @@ func (s *InboundService) getAllEmails() ([]string, error) { FROM inbounds, JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client `).Scan(&emails).Error + if err != nil { return nil, err } @@ -134,26 +134,26 @@ func (s *InboundService) checkEmailExistForInbound(inbound *model.Inbound) (stri return "", nil } -func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, error) { +func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, bool, error) { exist, err := s.checkPortExist(inbound.Port, 0) if err != nil { - return inbound, err + return inbound, false, err } if exist { - return inbound, common.NewError("Port already exists:", inbound.Port) + return inbound, false, common.NewError("Port already exists:", inbound.Port) } existEmail, err := s.checkEmailExistForInbound(inbound) if err != nil { - return inbound, err + return inbound, false, err } if existEmail != "" { - return inbound, common.NewError("Duplicate email:", existEmail) + return inbound, false, common.NewError("Duplicate email:", existEmail) } clients, err := s.GetClients(inbound) if err != nil { - return inbound, err + return inbound, false, err } db := database.GetDB() @@ -172,7 +172,26 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, err s.AddClientStat(tx, inbound.Id, &client) } } - return inbound, err + + needRestart := false + if inbound.Enable { + s.xrayApi.Init(p.GetAPIPort()) + inboundJson, err1 := json.MarshalIndent(inbound.GenXrayInboundConfig(), "", " ") + if err1 != nil { + logger.Debug("Unable to marshal inbound config:", err1) + } + + err1 = s.xrayApi.AddInbound(inboundJson) + if err1 == nil { + logger.Debug("New inbound added by api:", inbound.Tag) + } else { + logger.Debug("Unable to add inbound by api:", err1) + needRestart = true + } + s.xrayApi.Close() + } + + return inbound, needRestart, err } func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error { @@ -207,27 +226,47 @@ func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error { return nil } -func (s *InboundService) DelInbound(id int) error { +func (s *InboundService) DelInbound(id int) (bool, error) { db := database.GetDB() + + var tag string + needRestart := false + result := db.Model(model.Inbound{}).Select("tag").Where("id = ? and enable = ?", id, true).First(&tag) + if result.Error == nil { + s.xrayApi.Init(p.GetAPIPort()) + err1 := s.xrayApi.DelInbound(tag) + if err1 == nil { + logger.Debug("Inbound deleted by api:", tag) + } else { + logger.Debug("Unable to delete inbound by api:", err1) + needRestart = true + } + s.xrayApi.Close() + } else { + logger.Debug("No enabled inbound founded to removing by api", tag) + } + + // Delete client traffics of inbounds err := db.Where("inbound_id = ?", id).Delete(xray.ClientTraffic{}).Error if err != nil { - return err + return false, err } inbound, err := s.GetInbound(id) if err != nil { - return err + return false, err } clients, err := s.GetClients(inbound) if err != nil { - return err + return false, err } for _, client := range clients { err := s.DelClientIPs(db, client.Email) if err != nil { - return err + return false, err } } - return db.Delete(model.Inbound{}, id).Error + + return needRestart, db.Delete(model.Inbound{}, id).Error } func (s *InboundService) GetInbound(id int) (*model.Inbound, error) { @@ -240,23 +279,25 @@ func (s *InboundService) GetInbound(id int) (*model.Inbound, error) { return inbound, nil } -func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, error) { +func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, bool, error) { exist, err := s.checkPortExist(inbound.Port, inbound.Id) if err != nil { - return inbound, err + return inbound, false, err } if exist { - return inbound, common.NewError("Port already exists:", inbound.Port) + return inbound, false, common.NewError("Port already exists:", inbound.Port) } oldInbound, err := s.GetInbound(inbound.Id) if err != nil { - return inbound, err + return inbound, false, err } + tag := oldInbound.Tag + err = s.updateClientTraffics(oldInbound, inbound) if err != nil { - return inbound, err + return inbound, false, err } oldInbound.Up = inbound.Up @@ -273,8 +314,34 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, oldInbound.Sniffing = inbound.Sniffing oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port) + needRestart := false + s.xrayApi.Init(p.GetAPIPort()) + err1 := s.xrayApi.DelInbound(tag) + if err1 != nil { + logger.Debug("Unable to delete old inbound by api:", err1) + needRestart = true + } else { + logger.Debug("Old inbound deleted by api:", tag) + + if inbound.Enable { + inboundJson, err2 := json.MarshalIndent(oldInbound.GenXrayInboundConfig(), "", " ") + if err2 != nil { + logger.Debug("Unable to marshal updated inbound config:", err2) + } + + err2 = s.xrayApi.AddInbound(inboundJson) + if err1 == nil { + logger.Debug("Updated inbound added by api:", oldInbound.Tag) + } else { + logger.Debug("Unable to update inbound by api:", err2) + needRestart = true + } + } + } + s.xrayApi.Close() + db := database.GetDB() - return inbound, db.Save(oldInbound).Error + return inbound, needRestart, db.Save(oldInbound).Error } func (s *InboundService) updateClientTraffics(oldInbound *model.Inbound, newInbound *model.Inbound) error { @@ -393,16 +460,18 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) { for _, client := range clients { if len(client.Email) > 0 { s.AddClientStat(tx, data.Id, &client) - err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{ - "email": client.Email, - "id": client.ID, - "flow": client.Flow, - "password": client.Password, - }) - if err1 == nil { - logger.Debug("Client added by api:", client.Email) - } else { - needRestart = true + if client.Enable { + err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{ + "email": client.Email, + "id": client.ID, + "flow": client.Flow, + "password": client.Password, + }) + if err1 == nil { + logger.Debug("Client added by api:", client.Email) + } else { + needRestart = true + } } } else { needRestart = true @@ -466,7 +535,7 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool, logger.Error("Error in delete client IPs") return false, err } - needRestart := true + needRestart := false s.xrayApi.Init(p.GetAPIPort()) if len(email) > 0 { err = s.xrayApi.RemoveUser(oldInbound.Tag, email) @@ -580,7 +649,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin return false, err } } - needRestart := true + needRestart := false s.xrayApi.Init(p.GetAPIPort()) if len(oldEmail) > 0 { s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail) @@ -729,15 +798,38 @@ func (s *InboundService) adjustTraffics(tx *gorm.DB, dbClientTraffics []*xray.Cl return dbClientTraffics, nil } -func (s *InboundService) DisableInvalidInbounds() (int64, error) { +func (s *InboundService) DisableInvalidInbounds() (bool, int64, error) { db := database.GetDB() now := time.Now().Unix() * 1000 + needRestart := false + + if p != nil { + var tags []string + err := db.Table("inbounds"). + Select("inbounds.tag"). + Where("((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?)) and enable = ?", now, true). + Scan(&tags).Error + if err != nil { + return false, 0, err + } + s.xrayApi.Init(p.GetAPIPort()) + for _, tag := range tags { + err = s.xrayApi.DelInbound(tag) + if err == nil { + logger.Debug("Inbound disabled by api:", tag) + } else { + needRestart = true + } + } + s.xrayApi.Close() + } + result := db.Model(model.Inbound{}). Where("((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?)) and enable = ?", now, true). Update("enable", false) err := result.Error count := result.RowsAffected - return count, err + return needRestart, count, err } func (s *InboundService) DisableInvalidClients() (bool, int64, error) { @@ -763,7 +855,7 @@ func (s *InboundService) DisableInvalidClients() (bool, int64, error) { for _, result := range results { err = s.xrayApi.RemoveUser(result.Tag, result.Email) if err == nil { - logger.Debug("Client deleted by api:", result.Email) + logger.Debug("Client disabled by api:", result.Email) } else { needRestart = true } @@ -816,8 +908,7 @@ func (s *InboundService) UpdateClientStat(email string, client *model.Client) er "enable": true, "email": client.Email, "total": client.TotalGB, - "expiry_time": client.ExpiryTime, - }) + "expiry_time": client.ExpiryTime}) err := result.Error if err != nil { return err @@ -1208,6 +1299,7 @@ func (s *InboundService) ResetAllClientTraffics(id int) error { Updates(map[string]interface{}{"enable": true, "up": 0, "down": 0}) err := result.Error + if err != nil { return err } @@ -1222,6 +1314,7 @@ func (s *InboundService) ResetAllTraffics() error { Updates(map[string]interface{}{"up": 0, "down": 0}) err := result.Error + if err != nil { return err } diff --git a/web/service/server.go b/web/service/server.go index 5216be5a..c5f4e264 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -403,25 +403,20 @@ func (s *ServerService) GetLogs(count string, logLevel string) ([]string, error) } func (s *ServerService) GetConfigJson() (interface{}, error) { - // Open the file for reading - file, err := os.Open(xray.GetConfigPath()) + config, err := s.xrayService.GetXrayConfig() if err != nil { return nil, err } - defer file.Close() - - // Read the file contents - fileContents, err := io.ReadAll(file) + contents, err := json.MarshalIndent(config, "", " ") if err != nil { return nil, err } var jsonData interface{} - err = json.Unmarshal(fileContents, &jsonData) + err = json.Unmarshal(contents, &jsonData) if err != nil { return nil, err } - return jsonData, nil } |
