diff --git a/bot.go b/bot.go index f93dee6..7dfcfc2 100644 --- a/bot.go +++ b/bot.go @@ -1,6 +1,8 @@ package main import ( + "crypto/rand" + "encoding/hex" "encoding/json" "fmt" "regexp" @@ -15,6 +17,14 @@ type Bot struct { Config *TelegramConfig } +type CompanyDeleteEntry struct { + CompanyID uint8 + UserID int + Time time.Time +} + +var companyDeleteMap map[string]*CompanyDeleteEntry + func (b *Bot) Start() { var err error b.bot, err = tb.NewBot(tb.Settings{ @@ -24,6 +34,8 @@ func (b *Bot) Start() { }) failError(err, "Bot.Start() : registering bot") + companyDeleteMap = make(map[string]*CompanyDeleteEntry) + b.BotHandlers() } @@ -118,17 +130,50 @@ func botUnpause(m *tb.Message) { func botDelete(m *tb.Message) { logInfoDebug("[%d] %s(%d) | %s(%d) : delete : %s\n", m.ID, m.Chat.Title, m.Chat.ID, m.Sender.Username, m.Sender.ID, m.Text) - if m.Sender.ID == int(bot.Config.AdminID) { - r := regexp.MustCompile("/delete (?P[0-9]+)") + r := regexp.MustCompile("/delete (?P[0-9]+)") + id := uint8(255) + if r.MatchString(m.Text) { ID64, _ := strconv.ParseInt(r.ReplaceAllString(m.Text, "${CompanyID}"), 10, 64) - if _, ok := srv.Status.Companies[uint8(ID64)]; ok { - srv.DeleteCompany(uint8(ID64)) - bot.SendChat(m.Chat.ID, "Deleting") + if m.Sender.ID == int(bot.Config.AdminID) { + id = uint8(ID64) + } else if cc, ok := cfg.Clients[m.Sender.ID]; ok && cc.CompanyID == uint8(ID64) { + id = cc.CompanyID } else { - bot.SendChat(m.Chat.ID, "Company doesn't exist") + bot.SendChat(m.Chat.ID, "Not authorized to delete") + return } + } else if cc, ok := cfg.Clients[m.Sender.ID]; ok { + id = cc.CompanyID } else { - bot.SendChat(m.Chat.ID, "Not authorized to delete") + bot.SendChat(m.Chat.ID, "User not registered") + return + } + + if id == 255 { + bot.SendChat(m.Chat.ID, "No company registered") + return + } + + if co, ok := srv.Status.Companies[id]; ok { + b := make([]byte, 8) + _, err := rand.Read(b) + logErrorDebug(err, "botDelete : rand.Read") + if err != nil { + bot.SendChat(m.Chat.ID, "internal error") + return + } + + c := hex.EncodeToString(b) + d := &CompanyDeleteEntry{ + CompanyID: id, + UserID: m.Sender.ID, + Time: time.Now(), + } + companyDeleteMap[c] = d + bot.SendChat(m.Chat.ID, fmt.Sprintf("Press /delete_%s to delete '%s'", c, co.Name)) + + } else { + bot.SendChat(m.Chat.ID, "Company doesn't exist") } return } @@ -179,11 +224,79 @@ func botPlayers(m *tb.Message) { } func botGive(m *tb.Message) { - PrintText(m) + if m.Sender.ID != int(cfg.Telegram.AdminID) { + bot.SendChat(m.Chat.ID, "Only the admin can use this command.") + return + } + + r := regexp.MustCompile("^/give @(?P[a-zA-Z0-9]+) (?P[a-z0-9]+)") + + if !r.MatchString(m.Text) { + bot.SendChat(m.Chat.ID, "Wrong format.") + return + } + + uStr := r.ReplaceAllString(m.Text, "${Username}") + var u int + for ccID, cc := range cfg.Clients { + if cc.Username == uStr { + u = ccID + } + } + if u == 0 { + bot.SendChat(m.Chat.ID, "No such user found.") + return + } + + dStr := r.ReplaceAllString(m.Text, "${Duration}") + d, err := time.ParseDuration(dStr) + logErrorDebug(err, "botGive : time.ParseDuration") + if err != nil { + bot.SendChat(m.Chat.ID, "Cannot parse duration.") + } + + cc := cfg.Clients[u] + cc.TimeLeft += d + + bot.SendChat(m.Chat.ID, fmt.Sprintf("@%s now has %s left.", uStr, cc.TimeLeft)) } func botTake(m *tb.Message) { - PrintText(m) + if m.Sender.ID != int(cfg.Telegram.AdminID) { + bot.SendChat(m.Chat.ID, "Only the admin can use this command.") + return + } + + r := regexp.MustCompile("^/give @(?P[a-zA-Z0-9]+) (?P[a-z0-9]+)") + + if !r.MatchString(m.Text) { + bot.SendChat(m.Chat.ID, "Wrong format.") + return + } + + uStr := r.ReplaceAllString(m.Text, "${Username}") + var u int + for ccID, cc := range cfg.Clients { + if cc.Username == uStr { + u = ccID + } + } + if u == 0 { + bot.SendChat(m.Chat.ID, "No such user found.") + return + } + + dStr := r.ReplaceAllString(m.Text, "${Duration}") + d, err := time.ParseDuration(dStr) + logErrorDebug(err, "botGive : time.ParseDuration") + if err != nil { + bot.SendChat(m.Chat.ID, "Cannot parse duration.") + } + + cc := cfg.Clients[u] + cc.TimeLeft -= d + + bot.SendChat(m.Chat.ID, fmt.Sprintf("@%s now has %s left.", uStr, cc.TimeLeft)) } func botPasswd(m *tb.Message) { @@ -362,5 +475,26 @@ func botQuery(q *tb.Query) { } func botText(m *tb.Message) { + r := regexp.MustCompile("^/delete_(??[a-f0-9]{16})$") + if r.MatchString(m.Text) { + ref := r.ReplaceAllString(m.Text, "${Ref}") + d, ok := companyDeleteMap[ref] + if !ok { + bot.SendChat(m.Chat.ID, "No corresponding deletion request.") + return + } + if d.UserID != m.Sender.ID { + bot.SendChat(m.Chat.ID, "Requesting user has to confirm himself.") + return + } + if time.Now().Sub(d.Time) > time.Minute { + bot.SendChat(m.Chat.ID, "Request expired.") + return + } + srv.DeleteCompany(d.CompanyID) + bot.SendChat(m.Chat.ID, "Company deleted.") + delete(companyDeleteMap, ref) + return + } PrintText(m) } diff --git a/version.go b/version.go index 5ac0513..64242e9 100644 --- a/version.go +++ b/version.go @@ -1,6 +1,6 @@ // Code generated by version.sh (@generated) DO NOT EDIT. package main -var githash = "caba808" -var buildstamp = "2021-11-12_01:17:14" -var commits = "188" -var version = "caba808-b188 - 2021-11-12_01:17:14" +var githash = "24bf4dc" +var buildstamp = "2021-11-13_02:40:31" +var commits = "189" +var version = "24bf4dc-b189 - 2021-11-13_02:40:31"