From 4ed37f997ab4a5043f3f7ad986b3aa5cd4a5fc26 Mon Sep 17 00:00:00 2001 From: 0xCA Date: Fri, 17 Nov 2023 17:50:58 +0500 Subject: [PATCH] SendRequestedConfigsToTelegram func, simplified dependencies, fixes --- main.go | 6 ++--- telegram/bot.go | 66 +++++++++++-------------------------------------- util/util.go | 60 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 56 deletions(-) diff --git a/main.go b/main.go index 6f2133e..d4771c3 100644 --- a/main.go +++ b/main.go @@ -264,10 +264,8 @@ func main() { app.GET(util.BasePath+"/static/*", echo.WrapHandler(http.StripPrefix(util.BasePath+"/static/", assetHandler))) initDeps := telegram.TgBotInitDependencies{ - DB: db, - BuildClientConfig: util.BuildClientConfig, - TgUseridToClientID: util.TgUseridToClientID, - TgUseridToClientIDMutex: &util.TgUseridToClientIDMutex, + DB: db, + SendRequestedConfigsToTelegram: util.SendRequestedConfigsToTelegram, } initTelegram(initDeps) diff --git a/telegram/bot.go b/telegram/bot.go index 459e7b0..9ba0ece 100644 --- a/telegram/bot.go +++ b/telegram/bot.go @@ -2,24 +2,19 @@ package telegram import ( "fmt" - "strconv" "sync" "time" "github.com/NicoNex/echotron/v3" "github.com/labstack/gommon/log" - "github.com/ngoduykhanh/wireguard-ui/model" "github.com/ngoduykhanh/wireguard-ui/store" - "github.com/skip2/go-qrcode" ) -type BuildClientConfig func(client model.Client, server model.Server, setting model.GlobalSetting) string +type SendRequestedConfigsToTelegram func(db store.IStore, userid int64) []string type TgBotInitDependencies struct { - DB store.IStore - BuildClientConfig BuildClientConfig - TgUseridToClientID map[int64]([]string) - TgUseridToClientIDMutex *sync.RWMutex + DB store.IStore + SendRequestedConfigsToTelegram SendRequestedConfigsToTelegram } var ( @@ -32,12 +27,6 @@ var ( TgBotMutex sync.RWMutex floodWait = make(map[int64]int64, 0) - - qrCodeSettings = model.QRCodeSettings{ - Enabled: true, - IncludeDNS: true, - IncludeMTU: true, - } ) func Start(initDeps TgBotInitDependencies) (err error) { @@ -98,44 +87,19 @@ func Start(initDeps TgBotInitDependencies) (err error) { } floodWait[userid] = time.Now().Unix() - initDeps.TgUseridToClientIDMutex.RLock() - if clids, found := initDeps.TgUseridToClientID[userid]; found && len(clids) > 0 { - initDeps.TgUseridToClientIDMutex.RUnlock() - - for _, clid := range clids { - func(clid string) { - clientData, err := initDeps.DB.GetClientByID(clid, qrCodeSettings) - if err != nil { - return - } - - // build config - server, _ := initDeps.DB.GetServer() - globalSettings, _ := initDeps.DB.GetGlobalSettings() - config := initDeps.BuildClientConfig(*clientData.Client, server, globalSettings) - configData := []byte(config) - var qrData []byte - - if clientData.Client.PrivateKey != "" { - qrData, err = qrcode.Encode(config, qrcode.Medium, 512) - if err != nil { - return - } - } - - userid, err := strconv.ParseInt(clientData.Client.TgUserid, 10, 64) - if err != nil { - return - } - - SendConfig(userid, clientData.Client.Name, configData, qrData, true) - }(clid) - time.Sleep(2 * time.Second) + failed := initDeps.SendRequestedConfigsToTelegram(initDeps.DB, userid) + if len(failed) > 0 { + messageText := "Failed to send configs:\n" + for _, f := range failed { + messageText += f + "\n" } - } else { - initDeps.TgUseridToClientIDMutex.RUnlock() + bot.SendMessage( + messageText, + userid, + &echotron.MessageOptions{ + ReplyToMessageID: update.Message.ID, + }) } - } } return err @@ -174,7 +138,7 @@ func SendConfig(userid int64, clientName string, confData, qrData []byte, ignore } func updateFloodWait() { - thresholdTS := time.Now().Unix() - 60000*int64(TelegramFloodWait) + thresholdTS := time.Now().Unix() - 60*int64(TelegramFloodWait) for userid, ts := range floodWait { if ts < thresholdTS { delete(floodWait, userid) diff --git a/util/util.go b/util/util.go index 9f7cb88..337745a 100644 --- a/util/util.go +++ b/util/util.go @@ -20,6 +20,7 @@ import ( "github.com/ngoduykhanh/wireguard-ui/store" "github.com/ngoduykhanh/wireguard-ui/telegram" + "github.com/skip2/go-qrcode" "golang.org/x/mod/sumdb/dirhash" externalip "github.com/glendc/go-external-ip" @@ -28,8 +29,14 @@ import ( "github.com/sdomino/scribble" ) +var qrCodeSettings = model.QRCodeSettings{ + Enabled: true, + IncludeDNS: true, + IncludeMTU: true, +} + // BuildClientConfig to create wireguard client config string -var BuildClientConfig telegram.BuildClientConfig = func(client model.Client, server model.Server, setting model.GlobalSetting) string { +func BuildClientConfig(client model.Client, server model.Server, setting model.GlobalSetting) string { // Interface section clientAddress := fmt.Sprintf("Address = %s\n", strings.Join(client.AllocatedIPs, ",")) clientPrivateKey := fmt.Sprintf("PrivateKey = %s\n", client.PrivateKey) @@ -579,6 +586,57 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client return nil } +// SendRequestedConfigsToTelegram to send client all their configs. Returns failed configs list. +func SendRequestedConfigsToTelegram(db store.IStore, userid int64) []string { + failedList := make([]string, 0) + TgUseridToClientIDMutex.RLock() + if clids, found := TgUseridToClientID[userid]; found && len(clids) > 0 { + TgUseridToClientIDMutex.RUnlock() + + for _, clid := range clids { + clientData, err := db.GetClientByID(clid, qrCodeSettings) + if err != nil { + // return fmt.Errorf("unable to get client") + failedList = append(failedList, clid) + continue + } + + // build config + server, _ := db.GetServer() + globalSettings, _ := db.GetGlobalSettings() + config := BuildClientConfig(*clientData.Client, server, globalSettings) + configData := []byte(config) + var qrData []byte + + if clientData.Client.PrivateKey != "" { + qrData, err = qrcode.Encode(config, qrcode.Medium, 512) + if err != nil { + // return fmt.Errorf("unable to encode qr") + failedList = append(failedList, clientData.Client.Name) + continue + } + } + + userid, err := strconv.ParseInt(clientData.Client.TgUserid, 10, 64) + if err != nil { + // return fmt.Errorf("tg usrid is unreadable") + failedList = append(failedList, clientData.Client.Name) + continue + } + + err = telegram.SendConfig(userid, clientData.Client.Name, configData, qrData, true) + if err != nil { + failedList = append(failedList, clientData.Client.Name) + continue + } + time.Sleep(2 * time.Second) + } + } else { + TgUseridToClientIDMutex.RUnlock() + } + return failedList +} + func LookupEnvOrString(key string, defaultVal string) string { if val, ok := os.LookupEnv(key); ok { return val