From f97ebb604ada6196ffbcbf83870f05ba059cf4d2 Mon Sep 17 00:00:00 2001 From: Aine Date: Mon, 29 Aug 2022 21:41:14 +0300 Subject: [PATCH 01/10] manage users in runtime, closes #16 --- README.md | 3 ++- bot/bot.go | 31 ++++++++++++++------------- bot/command.go | 8 +++++++ bot/command_admin.go | 38 +++++++++++++++++++++++++++++++++ bot/data.go | 50 ++++++++++++++++++++++++++++++++++++++++++-- bot/settings.go | 5 +++++ config/types.go | 2 +- 7 files changed, 119 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b5913e7..631e933 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ env vars * **POSTMOOGLE_DB_DSN** - database connection string * **POSTMOOGLE_DB_DIALECT** - database dialect (postgres, sqlite3) * **POSTMOOGLE_MAXSIZE** - max email size (including attachments) in megabytes -* **POSTMOOGLE_USERS** - a space-separated list of whitelisted users allowed to use the bridge. If not defined, everyone on the homeserver are allowed. Example rule: `@someone:example.com @another:example.com @bot.*:example.com @*:another.com` * **POSTMOOGLE_ADMINS** - a space-separated list of admin users. See `POSTMOOGLE_USERS` for syntax examples +* **POSTMOOGLE_USERS** - deprecated and ignored, use `!pm users` instead You can find default values in [config/defaults.go](config/defaults.go) @@ -83,6 +83,7 @@ If you want to change them - check available options in the help message (`!pm h --- * **!pm mailboxes** - Show the list of all mailboxes +* **!pm users** - Get or set allowed users patterns * **!pm delete** <mailbox> - Delete specific mailbox diff --git a/bot/bot.go b/bot/bot.go index de25ddb..43e9018 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -39,12 +39,25 @@ func New( users []string, admins []string, ) (*Bot, error) { + b := &Bot{ + prefix: prefix, + domain: domain, + rooms: sync.Map{}, + cfg: cache.NewLRU[settings](1000), + log: log, + lp: lp, + mu: map[id.RoomID]*sync.Mutex{}, + } + err := b.migrateBotSettings(users) + if err != nil { + return nil, err + } + _, homeserver, err := lp.GetClient().UserID.Parse() if err != nil { return nil, err } - var allowedUsers []*regexp.Regexp - allowedUsers, uerr := parseMXIDpatterns(users, "@*:"+homeserver) + allowedUsers, uerr := parseMXIDpatterns(b.getBotSettings().Users(), "@*:"+homeserver) if uerr != nil { return nil, uerr } @@ -52,18 +65,8 @@ func New( if aerr != nil { return nil, aerr } - - b := &Bot{ - prefix: prefix, - domain: domain, - allowedUsers: allowedUsers, - allowedAdmins: allowedAdmins, - rooms: sync.Map{}, - cfg: cache.NewLRU[settings](1000), - log: log, - lp: lp, - mu: map[id.RoomID]*sync.Mutex{}, - } + b.allowedUsers = allowedUsers + b.allowedAdmins = allowedAdmins b.commands = b.buildCommandList() return b, nil diff --git a/bot/command.go b/bot/command.go index 966662f..926eadd 100644 --- a/bot/command.go +++ b/bot/command.go @@ -14,6 +14,7 @@ import ( const ( commandHelp = "help" commandStop = "stop" + commandUsers = botOptionUsers commandDelete = "delete" commandMailboxes = "mailboxes" ) @@ -111,6 +112,11 @@ func (b *Bot) buildCommandList() commandList { allowed: b.allowOwner, }, {allowed: b.allowAdmin}, // delimiter + { + key: botOptionUsers, + description: "Get or set allowed users", + allowed: b.allowAdmin, + }, { key: commandMailboxes, description: "Show the list of all mailboxes", @@ -140,6 +146,8 @@ func (b *Bot) handleCommand(ctx context.Context, evt *event.Event, commandSlice b.sendHelp(ctx) case commandStop: b.runStop(ctx) + case commandUsers: + b.runUsers(ctx, commandSlice) case commandDelete: b.runDelete(ctx, commandSlice) case commandMailboxes: diff --git a/bot/command_admin.go b/bot/command_admin.go index b51b1de..ebec11b 100644 --- a/bot/command_admin.go +++ b/bot/command_admin.go @@ -87,3 +87,41 @@ func (b *Bot) runDelete(ctx context.Context, commandSlice []string) { b.SendNotice(ctx, evt.RoomID, "mailbox has been deleted") } + +func (b *Bot) runUsers(ctx context.Context, commandSlice []string) { + evt := eventFromContext(ctx) + cfg := b.getBotSettings() + if len(commandSlice) < 2 { + var msg strings.Builder + users := cfg.Users() + if len(users) > 0 { + msg.WriteString("Currently: `") + msg.WriteString(strings.Join(users, " ")) + msg.WriteString("`\n\n") + } + msg.WriteString("Usage: `") + msg.WriteString(b.prefix) + msg.WriteString(" users PATTERN1 PATTERN2 PATTERN3...`") + msg.WriteString("where patterns like `@someone:example.com ") + msg.WriteString(" @bot.*:example.com @*:another.com @*:*`\n") + + b.SendNotice(ctx, evt.RoomID, msg.String()) + return + } + + patterns := commandSlice[1:] + allowedUsers, err := parseMXIDpatterns(patterns, "") + if err != nil { + b.SendError(ctx, evt.RoomID, fmt.Sprintf("invalid patterns: %v", err)) + return + } + + cfg.Set(botOptionUsers, strings.Join(patterns, " ")) + + err = b.setBotSettings(cfg) + if err != nil { + b.Error(ctx, evt.RoomID, "cannot set bot config: %v", err) + } + b.allowedUsers = allowedUsers + b.SendNotice(ctx, evt.RoomID, "allowed users updated") +} diff --git a/bot/data.go b/bot/data.go index 31b8902..310704d 100644 --- a/bot/data.go +++ b/bot/data.go @@ -4,12 +4,15 @@ import ( "strings" "maunium.net/go/mautrix/id" + + "gitlab.com/etke.cc/postmoogle/utils" ) // account data keys const ( - messagekey = "cc.etke.postmoogle.message" - settingskey = "cc.etke.postmoogle.settings" + messagekey = "cc.etke.postmoogle.message" + settingskey = "cc.etke.postmoogle.settings" + botconfigkey = "cc.etke.postmoogle.config" ) // event keys @@ -27,6 +30,8 @@ const ( optionNoHTML = "nohtml" optionNoThreads = "nothreads" optionNoFiles = "nofiles" + + botOptionUsers = "users" ) var migrations = []string{} @@ -108,3 +113,44 @@ func (b *Bot) setThreadID(roomID id.RoomID, messageID string, eventID id.EventID } } } + +// TODO: remove after migration +func (b *Bot) migrateBotSettings(users []string) error { + config := b.getBotSettings() + cfgUsers := config.Users() + if len(users) > 0 && len(cfgUsers) == 0 { + _, err := parseMXIDpatterns(users, "") + if err != nil { + return err + } + config.Set(botOptionUsers, strings.Join(users, " ")) + return b.setBotSettings(config) + } + + return nil +} + +func (b *Bot) getBotSettings() settings { + cfg := b.cfg.Get(botconfigkey) + if cfg != nil { + return cfg + } + + config := settings{} + err := b.lp.GetClient().GetAccountData(botconfigkey, &config) + if err != nil { + if strings.Contains(err.Error(), "M_NOT_FOUND") { + err = nil + } + b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) + } else { + b.cfg.Set(botconfigkey, config) + } + + return config +} + +func (b *Bot) setBotSettings(cfg settings) error { + b.cfg.Set(botconfigkey, cfg) + return utils.UnwrapError(b.lp.GetClient().SetAccountData(botconfigkey, cfg)) +} diff --git a/bot/settings.go b/bot/settings.go index 74886c3..66bb29a 100644 --- a/bot/settings.go +++ b/bot/settings.go @@ -52,6 +52,11 @@ func (s settings) NoFiles() bool { return utils.Bool(s.Get(optionNoFiles)) } +// Users is bot/admin option +func (s settings) Users() []string { + return strings.Split(s.Get(botOptionUsers), " ") +} + // Set option func (s settings) Set(key, value string) { s[strings.ToLower(strings.TrimSpace(key))] = value diff --git a/config/types.go b/config/types.go index 531ebfb..605d8a5 100644 --- a/config/types.go +++ b/config/types.go @@ -22,7 +22,7 @@ type Config struct { MaxSize int // StatusMsg of the bot StatusMsg string - // Users holds list of allowed users (wildcards supported), e.g.: @*:example.com, @bot.*:example.com, @admin:*. Empty = homeserver only + // Users DEPRECATED holds list of allowed users (wildcards supported), e.g.: @*:example.com, @bot.*:example.com, @admin:*. Empty = homeserver only Users []string // Admins holds list of admin users (wildcards supported), e.g.: @*:example.com, @bot.*:example.com, @admin:*. Empty = no admins Admins []string From 5ed3a53223061c6b6b29c5ba0f8cf7e438b28ac8 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 14:37:19 +0300 Subject: [PATCH 02/10] diff bot and room settings --- bot/access.go | 2 +- bot/bot.go | 6 ++- bot/command.go | 2 +- bot/command_admin.go | 6 +-- bot/command_owner.go | 10 ++-- bot/data.go | 62 +---------------------- bot/email.go | 4 +- bot/settings_bot.go | 73 +++++++++++++++++++++++++++ bot/{settings.go => settings_room.go} | 64 +++++++++++++---------- 9 files changed, 127 insertions(+), 102 deletions(-) create mode 100644 bot/settings_bot.go rename bot/{settings.go => settings_room.go} (59%) diff --git a/bot/access.go b/bot/access.go index 31cd5cc..bcb99fc 100644 --- a/bot/access.go +++ b/bot/access.go @@ -28,7 +28,7 @@ func (b *Bot) allowOwner(actorID id.UserID, targetRoomID id.RoomID) bool { } } - cfg, err := b.getSettings(targetRoomID) + cfg, err := b.getRoomSettings(targetRoomID) if err != nil { b.Error(context.Background(), targetRoomID, "failed to retrieve settings: %v", err) return false diff --git a/bot/bot.go b/bot/bot.go index 43e9018..8fbf124 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -23,7 +23,8 @@ type Bot struct { allowedAdmins []*regexp.Regexp commands commandList rooms sync.Map - cfg cache.Cache[settings] + botcfg cache.Cache[botsettings] + cfg cache.Cache[roomsettings] log *logger.Logger lp *linkpearl.Linkpearl mu map[id.RoomID]*sync.Mutex @@ -43,7 +44,8 @@ func New( prefix: prefix, domain: domain, rooms: sync.Map{}, - cfg: cache.NewLRU[settings](1000), + botcfg: cache.NewLRU[botsettings](1), + cfg: cache.NewLRU[roomsettings](1000), log: log, lp: lp, mu: map[id.RoomID]*sync.Mutex{}, diff --git a/bot/command.go b/bot/command.go index 926eadd..66b57fa 100644 --- a/bot/command.go +++ b/bot/command.go @@ -193,7 +193,7 @@ func (b *Bot) sendIntroduction(ctx context.Context, roomID id.RoomID) { func (b *Bot) sendHelp(ctx context.Context) { evt := eventFromContext(ctx) - cfg, serr := b.getSettings(evt.RoomID) + cfg, serr := b.getRoomSettings(evt.RoomID) if serr != nil { b.log.Error("cannot retrieve settings: %v", serr) } diff --git a/bot/command_admin.go b/bot/command_admin.go index ebec11b..38ad306 100644 --- a/bot/command_admin.go +++ b/bot/command_admin.go @@ -13,7 +13,7 @@ import ( func (b *Bot) sendMailboxes(ctx context.Context) { evt := eventFromContext(ctx) - mailboxes := map[string]settings{} + mailboxes := map[string]roomsettings{} slice := []string{} b.rooms.Range(func(key any, value any) bool { if key == nil { @@ -31,7 +31,7 @@ func (b *Bot) sendMailboxes(ctx context.Context) { if !ok { return true } - config, err := b.getSettings(roomID) + config, err := b.getRoomSettings(roomID) if err != nil { b.log.Error("cannot retrieve settings: %v", err) } @@ -79,7 +79,7 @@ func (b *Bot) runDelete(ctx context.Context, commandSlice []string) { roomID := v.(id.RoomID) b.rooms.Delete(mailbox) - err := b.setSettings(roomID, settings{}) + err := b.setRoomSettings(roomID, roomsettings{}) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return diff --git a/bot/command_owner.go b/bot/command_owner.go index 84f26cd..443dca3 100644 --- a/bot/command_owner.go +++ b/bot/command_owner.go @@ -7,7 +7,7 @@ import ( func (b *Bot) runStop(ctx context.Context) { evt := eventFromContext(ctx) - cfg, err := b.getSettings(evt.RoomID) + cfg, err := b.getRoomSettings(evt.RoomID) if err != nil { b.Error(ctx, evt.RoomID, "failed to retrieve settings: %v", err) return @@ -21,7 +21,7 @@ func (b *Bot) runStop(ctx context.Context) { b.rooms.Delete(mailbox) - err = b.setSettings(evt.RoomID, settings{}) + err = b.setRoomSettings(evt.RoomID, roomsettings{}) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return @@ -40,7 +40,7 @@ func (b *Bot) handleOption(ctx context.Context, cmd []string) { func (b *Bot) getOption(ctx context.Context, name string) { evt := eventFromContext(ctx) - cfg, err := b.getSettings(evt.RoomID) + cfg, err := b.getRoomSettings(evt.RoomID) if err != nil { b.Error(ctx, evt.RoomID, "failed to retrieve settings: %v", err) return @@ -74,7 +74,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { } } - cfg, err := b.getSettings(evt.RoomID) + cfg, err := b.getRoomSettings(evt.RoomID) if err != nil { b.Error(ctx, evt.RoomID, "failed to retrieve settings: %v", err) return @@ -92,7 +92,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { value = fmt.Sprintf("%s@%s", value, b.domain) } - err = b.setSettings(evt.RoomID, cfg) + err = b.setRoomSettings(evt.RoomID, cfg) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return diff --git a/bot/data.go b/bot/data.go index 310704d..327dc79 100644 --- a/bot/data.go +++ b/bot/data.go @@ -4,15 +4,11 @@ import ( "strings" "maunium.net/go/mautrix/id" - - "gitlab.com/etke.cc/postmoogle/utils" ) // account data keys const ( - messagekey = "cc.etke.postmoogle.message" - settingskey = "cc.etke.postmoogle.settings" - botconfigkey = "cc.etke.postmoogle.config" + messagekey = "cc.etke.postmoogle.message" ) // event keys @@ -21,19 +17,6 @@ const ( eventInReplyToKey = "cc.etke.postmoogle.inReplyTo" ) -// option keys -const ( - optionOwner = "owner" - optionMailbox = "mailbox" - optionNoSender = "nosender" - optionNoSubject = "nosubject" - optionNoHTML = "nohtml" - optionNoThreads = "nothreads" - optionNoFiles = "nofiles" - - botOptionUsers = "users" -) - var migrations = []string{} func (b *Bot) migrate() error { @@ -72,7 +55,7 @@ func (b *Bot) syncRooms() error { } for _, roomID := range resp.JoinedRooms { b.migrateSettings(roomID) - cfg, serr := b.getSettings(roomID) + cfg, serr := b.getRoomSettings(roomID) if serr != nil { b.log.Warn("cannot get %s settings: %v", roomID, err) continue @@ -113,44 +96,3 @@ func (b *Bot) setThreadID(roomID id.RoomID, messageID string, eventID id.EventID } } } - -// TODO: remove after migration -func (b *Bot) migrateBotSettings(users []string) error { - config := b.getBotSettings() - cfgUsers := config.Users() - if len(users) > 0 && len(cfgUsers) == 0 { - _, err := parseMXIDpatterns(users, "") - if err != nil { - return err - } - config.Set(botOptionUsers, strings.Join(users, " ")) - return b.setBotSettings(config) - } - - return nil -} - -func (b *Bot) getBotSettings() settings { - cfg := b.cfg.Get(botconfigkey) - if cfg != nil { - return cfg - } - - config := settings{} - err := b.lp.GetClient().GetAccountData(botconfigkey, &config) - if err != nil { - if strings.Contains(err.Error(), "M_NOT_FOUND") { - err = nil - } - b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) - } else { - b.cfg.Set(botconfigkey, config) - } - - return config -} - -func (b *Bot) setBotSettings(cfg settings) error { - b.cfg.Set(botconfigkey, cfg) - return utils.UnwrapError(b.lp.GetClient().SetAccountData(botconfigkey, cfg)) -} diff --git a/bot/email.go b/bot/email.go index cf8b10a..e4cbd4a 100644 --- a/bot/email.go +++ b/bot/email.go @@ -12,7 +12,7 @@ import ( "gitlab.com/etke.cc/postmoogle/utils" ) -func email2content(email *utils.Email, cfg settings, threadID id.EventID) *event.Content { +func email2content(email *utils.Email, cfg roomsettings, threadID id.EventID) *event.Content { var text strings.Builder if !cfg.NoSender() { text.WriteString("From: ") @@ -66,7 +66,7 @@ func (b *Bot) Send(ctx context.Context, email *utils.Email) error { b.lock(roomID) defer b.unlock(roomID) - cfg, err := b.getSettings(roomID) + cfg, err := b.getRoomSettings(roomID) if err != nil { b.Error(ctx, roomID, "cannot get settings: %v", err) } diff --git a/bot/settings_bot.go b/bot/settings_bot.go new file mode 100644 index 0000000..be057b4 --- /dev/null +++ b/bot/settings_bot.go @@ -0,0 +1,73 @@ +package bot + +import ( + "strings" + + "gitlab.com/etke.cc/postmoogle/utils" +) + +// account data key +const botsettingskey = "cc.etke.postmoogle.config" + +// bot options keys +const ( + botOptionUsers = "users" +) + +type botsettings map[string]string + +// Get option +func (s botsettings) Get(key string) string { + return s[strings.ToLower(strings.TrimSpace(key))] +} + +// Set option +func (s botsettings) Set(key, value string) { + s[strings.ToLower(strings.TrimSpace(key))] = value +} + +// Users option +func (s botsettings) Users() []string { + return strings.Split(s.Get(botOptionUsers), " ") +} + +// TODO: remove after migration +func (b *Bot) migrateBotSettings(users []string) error { + config := b.getBotSettings() + cfgUsers := config.Users() + if len(users) > 0 && len(cfgUsers) == 0 { + _, err := parseMXIDpatterns(users, "") + if err != nil { + return err + } + config.Set(botOptionUsers, strings.Join(users, " ")) + return b.setBotSettings(config) + } + + return nil +} + +func (b *Bot) getBotSettings() botsettings { + cfg := b.botcfg.Get(botsettingskey) + if cfg != nil { + return cfg + } + + config := botsettings{} + err := b.lp.GetClient().GetAccountData(botsettingskey, &config) + if err != nil { + if strings.Contains(err.Error(), "M_NOT_FOUND") { + err = nil + } + b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) + } else { + b.botcfg.Set(botsettingskey, config) + } + + return config +} + +func (b *Bot) setBotSettings(cfg botsettings) error { + b.botcfg.Set(botsettingskey, cfg) + return utils.UnwrapError(b.lp.GetClient().SetAccountData(botsettingskey, cfg)) +} diff --git a/bot/settings.go b/bot/settings_room.go similarity index 59% rename from bot/settings.go rename to bot/settings_room.go index 66bb29a..9ab0037 100644 --- a/bot/settings.go +++ b/bot/settings_room.go @@ -9,8 +9,21 @@ import ( "gitlab.com/etke.cc/postmoogle/utils" ) -// settings of a room -type settings map[string]string +// account data key +const roomsettingskey = "cc.etke.postmoogle.settings" + +// option keys +const ( + optionOwner = "owner" + optionMailbox = "mailbox" + optionNoSender = "nosender" + optionNoSubject = "nosubject" + optionNoHTML = "nohtml" + optionNoThreads = "nothreads" + optionNoFiles = "nofiles" +) + +type roomsettings map[string]string // settingsOld of a room type settingsOld struct { @@ -20,52 +33,47 @@ type settingsOld struct { } // Get option -func (s settings) Get(key string) string { +func (s roomsettings) Get(key string) string { return s[strings.ToLower(strings.TrimSpace(key))] } -func (s settings) Mailbox() string { +// Set option +func (s roomsettings) Set(key, value string) { + s[strings.ToLower(strings.TrimSpace(key))] = value +} + +func (s roomsettings) Mailbox() string { return s.Get(optionMailbox) } -func (s settings) Owner() string { +func (s roomsettings) Owner() string { return s.Get(optionOwner) } -func (s settings) NoSender() bool { +func (s roomsettings) NoSender() bool { return utils.Bool(s.Get(optionNoSender)) } -func (s settings) NoSubject() bool { +func (s roomsettings) NoSubject() bool { return utils.Bool(s.Get(optionNoSubject)) } -func (s settings) NoHTML() bool { +func (s roomsettings) NoHTML() bool { return utils.Bool(s.Get(optionNoHTML)) } -func (s settings) NoThreads() bool { +func (s roomsettings) NoThreads() bool { return utils.Bool(s.Get(optionNoThreads)) } -func (s settings) NoFiles() bool { +func (s roomsettings) NoFiles() bool { return utils.Bool(s.Get(optionNoFiles)) } -// Users is bot/admin option -func (s settings) Users() []string { - return strings.Split(s.Get(botOptionUsers), " ") -} - -// Set option -func (s settings) Set(key, value string) { - s[strings.ToLower(strings.TrimSpace(key))] = value -} - // TODO: remove after migration func (b *Bot) migrateSettings(roomID id.RoomID) { var config settingsOld - err := b.lp.GetClient().GetRoomAccountData(roomID, settingskey, &config) + err := b.lp.GetClient().GetRoomAccountData(roomID, roomsettingskey, &config) if err != nil { // any error = no need to migrate return @@ -74,25 +82,25 @@ func (b *Bot) migrateSettings(roomID id.RoomID) { if config.Mailbox == "" { return } - cfg := settings{} + cfg := roomsettings{} cfg.Set(optionMailbox, config.Mailbox) cfg.Set(optionOwner, config.Owner.String()) cfg.Set(optionNoSender, strconv.FormatBool(config.NoSender)) - err = b.setSettings(roomID, cfg) + err = b.setRoomSettings(roomID, cfg) if err != nil { b.log.Error("cannot migrate settings: %v", err) } } -func (b *Bot) getSettings(roomID id.RoomID) (settings, error) { +func (b *Bot) getRoomSettings(roomID id.RoomID) (roomsettings, error) { cfg := b.cfg.Get(roomID.String()) if cfg != nil { return cfg, nil } - config := settings{} - err := b.lp.GetClient().GetRoomAccountData(roomID, settingskey, &config) + config := roomsettings{} + err := b.lp.GetClient().GetRoomAccountData(roomID, roomsettingskey, &config) if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { // Suppress `M_NOT_FOUND (HTTP 404): Room account data not found` errors. @@ -107,7 +115,7 @@ func (b *Bot) getSettings(roomID id.RoomID) (settings, error) { return config, utils.UnwrapError(err) } -func (b *Bot) setSettings(roomID id.RoomID, cfg settings) error { +func (b *Bot) setRoomSettings(roomID id.RoomID, cfg roomsettings) error { b.cfg.Set(roomID.String(), cfg) - return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, settingskey, cfg)) + return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, roomsettingskey, cfg)) } From 627e090afdc0bc8dffc8fa507cde825717961eed Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 14:42:07 +0300 Subject: [PATCH 03/10] rename account data keys, rearrange code --- bot/data.go | 45 -------------------------------------------- bot/email.go | 37 ++++++++++++++++++++++++++++++++++++ bot/settings_bot.go | 12 ++++++------ bot/settings_room.go | 8 ++++---- 4 files changed, 47 insertions(+), 55 deletions(-) diff --git a/bot/data.go b/bot/data.go index 327dc79..160cc72 100644 --- a/bot/data.go +++ b/bot/data.go @@ -1,22 +1,5 @@ package bot -import ( - "strings" - - "maunium.net/go/mautrix/id" -) - -// account data keys -const ( - messagekey = "cc.etke.postmoogle.message" -) - -// event keys -const ( - eventMessageIDkey = "cc.etke.postmoogle.messageID" - eventInReplyToKey = "cc.etke.postmoogle.inReplyTo" -) - var migrations = []string{} func (b *Bot) migrate() error { @@ -68,31 +51,3 @@ func (b *Bot) syncRooms() error { return nil } - -func (b *Bot) getThreadID(roomID id.RoomID, messageID string) id.EventID { - key := messagekey + "." + messageID - data := map[string]id.EventID{} - err := b.lp.GetClient().GetRoomAccountData(roomID, key, &data) - if err != nil { - if !strings.Contains(err.Error(), "M_NOT_FOUND") { - b.log.Error("cannot retrieve account data %s: %v", key, err) - return "" - } - } - - return data["eventID"] -} - -func (b *Bot) setThreadID(roomID id.RoomID, messageID string, eventID id.EventID) { - key := messagekey + "." + messageID - data := map[string]id.EventID{ - "eventID": eventID, - } - - err := b.lp.GetClient().SetRoomAccountData(roomID, key, data) - if err != nil { - if !strings.Contains(err.Error(), "M_NOT_FOUND") { - b.log.Error("cannot save account data %s: %v", key, err) - } - } -} diff --git a/bot/email.go b/bot/email.go index e4cbd4a..a7c6349 100644 --- a/bot/email.go +++ b/bot/email.go @@ -12,6 +12,15 @@ import ( "gitlab.com/etke.cc/postmoogle/utils" ) +// account data key +const acMessagePrefix = "cc.etke.postmoogle.message" + +// event keys +const ( + eventMessageIDkey = "cc.etke.postmoogle.messageID" + eventInReplyToKey = "cc.etke.postmoogle.inReplyTo" +) + func email2content(email *utils.Email, cfg roomsettings, threadID id.EventID) *event.Content { var text strings.Builder if !cfg.NoSender() { @@ -115,3 +124,31 @@ func (b *Bot) sendFiles(ctx context.Context, roomID id.RoomID, files []*utils.Fi } } } + +func (b *Bot) getThreadID(roomID id.RoomID, messageID string) id.EventID { + key := acMessagePrefix + "." + messageID + data := map[string]id.EventID{} + err := b.lp.GetClient().GetRoomAccountData(roomID, key, &data) + if err != nil { + if !strings.Contains(err.Error(), "M_NOT_FOUND") { + b.log.Error("cannot retrieve account data %s: %v", key, err) + return "" + } + } + + return data["eventID"] +} + +func (b *Bot) setThreadID(roomID id.RoomID, messageID string, eventID id.EventID) { + key := acMessagePrefix + "." + messageID + data := map[string]id.EventID{ + "eventID": eventID, + } + + err := b.lp.GetClient().SetRoomAccountData(roomID, key, data) + if err != nil { + if !strings.Contains(err.Error(), "M_NOT_FOUND") { + b.log.Error("cannot save account data %s: %v", key, err) + } + } +} diff --git a/bot/settings_bot.go b/bot/settings_bot.go index be057b4..dc44379 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -7,7 +7,7 @@ import ( ) // account data key -const botsettingskey = "cc.etke.postmoogle.config" +const acBotSettingsKey = "cc.etke.postmoogle.config" // bot options keys const ( @@ -48,26 +48,26 @@ func (b *Bot) migrateBotSettings(users []string) error { } func (b *Bot) getBotSettings() botsettings { - cfg := b.botcfg.Get(botsettingskey) + cfg := b.botcfg.Get(acBotSettingsKey) if cfg != nil { return cfg } config := botsettings{} - err := b.lp.GetClient().GetAccountData(botsettingskey, &config) + err := b.lp.GetClient().GetAccountData(acBotSettingsKey, &config) if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { err = nil } b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) } else { - b.botcfg.Set(botsettingskey, config) + b.botcfg.Set(acBotSettingsKey, config) } return config } func (b *Bot) setBotSettings(cfg botsettings) error { - b.botcfg.Set(botsettingskey, cfg) - return utils.UnwrapError(b.lp.GetClient().SetAccountData(botsettingskey, cfg)) + b.botcfg.Set(acBotSettingsKey, cfg) + return utils.UnwrapError(b.lp.GetClient().SetAccountData(acBotSettingsKey, cfg)) } diff --git a/bot/settings_room.go b/bot/settings_room.go index 9ab0037..f65c021 100644 --- a/bot/settings_room.go +++ b/bot/settings_room.go @@ -10,7 +10,7 @@ import ( ) // account data key -const roomsettingskey = "cc.etke.postmoogle.settings" +const acRoomSettingsKey = "cc.etke.postmoogle.settings" // option keys const ( @@ -73,7 +73,7 @@ func (s roomsettings) NoFiles() bool { // TODO: remove after migration func (b *Bot) migrateSettings(roomID id.RoomID) { var config settingsOld - err := b.lp.GetClient().GetRoomAccountData(roomID, roomsettingskey, &config) + err := b.lp.GetClient().GetRoomAccountData(roomID, acRoomSettingsKey, &config) if err != nil { // any error = no need to migrate return @@ -100,7 +100,7 @@ func (b *Bot) getRoomSettings(roomID id.RoomID) (roomsettings, error) { } config := roomsettings{} - err := b.lp.GetClient().GetRoomAccountData(roomID, roomsettingskey, &config) + err := b.lp.GetClient().GetRoomAccountData(roomID, acRoomSettingsKey, &config) if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { // Suppress `M_NOT_FOUND (HTTP 404): Room account data not found` errors. @@ -117,5 +117,5 @@ func (b *Bot) getRoomSettings(roomID id.RoomID) (roomsettings, error) { func (b *Bot) setRoomSettings(roomID id.RoomID, cfg roomsettings) error { b.cfg.Set(roomID.String(), cfg) - return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, roomsettingskey, cfg)) + return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, acRoomSettingsKey, cfg)) } From 9f66d1fee648be323cb9a20c963f52d294f3bd7f Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 14:45:07 +0300 Subject: [PATCH 04/10] rename options, rename settings types --- bot/bot.go | 8 +++--- bot/command.go | 28 ++++++++++---------- bot/command_admin.go | 4 +-- bot/command_owner.go | 14 +++++----- bot/email.go | 2 +- bot/settings_bot.go | 14 +++++----- bot/settings_room.go | 62 ++++++++++++++++++++++---------------------- 7 files changed, 66 insertions(+), 66 deletions(-) diff --git a/bot/bot.go b/bot/bot.go index 8fbf124..195f273 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -23,8 +23,8 @@ type Bot struct { allowedAdmins []*regexp.Regexp commands commandList rooms sync.Map - botcfg cache.Cache[botsettings] - cfg cache.Cache[roomsettings] + botcfg cache.Cache[botSettings] + cfg cache.Cache[roomSettings] log *logger.Logger lp *linkpearl.Linkpearl mu map[id.RoomID]*sync.Mutex @@ -44,8 +44,8 @@ func New( prefix: prefix, domain: domain, rooms: sync.Map{}, - botcfg: cache.NewLRU[botsettings](1), - cfg: cache.NewLRU[roomsettings](1000), + botcfg: cache.NewLRU[botSettings](1), + cfg: cache.NewLRU[roomSettings](1000), log: log, lp: lp, mu: map[id.RoomID]*sync.Mutex{}, diff --git a/bot/command.go b/bot/command.go index 66b57fa..4db54ce 100644 --- a/bot/command.go +++ b/bot/command.go @@ -54,59 +54,59 @@ func (b *Bot) buildCommandList() commandList { {allowed: b.allowOwner}, // delimiter // options commands { - key: optionMailbox, + key: roomOptionMailbox, description: "Get or set mailbox of the room", sanitizer: utils.Mailbox, allowed: b.allowOwner, }, { - key: optionOwner, + key: roomOptionOwner, description: "Get or set owner of the room", sanitizer: func(s string) string { return s }, allowed: b.allowOwner, }, {allowed: b.allowOwner}, // delimiter { - key: optionNoSender, + key: roomOptionNoSender, description: fmt.Sprintf( "Get or set `%s` of the room (`true` - hide email sender; `false` - show email sender)", - optionNoSender, + roomOptionNoSender, ), sanitizer: utils.SanitizeBoolString, allowed: b.allowOwner, }, { - key: optionNoSubject, + key: roomOptionNoSubject, description: fmt.Sprintf( "Get or set `%s` of the room (`true` - hide email subject; `false` - show email subject)", - optionNoSubject, + roomOptionNoSubject, ), sanitizer: utils.SanitizeBoolString, allowed: b.allowOwner, }, { - key: optionNoHTML, + key: roomOptionNoHTML, description: fmt.Sprintf( "Get or set `%s` of the room (`true` - ignore HTML in email; `false` - parse HTML in emails)", - optionNoHTML, + roomOptionNoHTML, ), sanitizer: utils.SanitizeBoolString, allowed: b.allowOwner, }, { - key: optionNoThreads, + key: roomOptionNoThreads, description: fmt.Sprintf( "Get or set `%s` of the room (`true` - ignore email threads; `false` - convert email threads into matrix threads)", - optionNoThreads, + roomOptionNoThreads, ), sanitizer: utils.SanitizeBoolString, allowed: b.allowOwner, }, { - key: optionNoFiles, + key: roomOptionNoFiles, description: fmt.Sprintf( "Get or set `%s` of the room (`true` - ignore email attachments; `false` - upload email attachments)", - optionNoFiles, + roomOptionNoFiles, ), sanitizer: utils.SanitizeBoolString, allowed: b.allowOwner, @@ -180,7 +180,7 @@ func (b *Bot) sendIntroduction(ctx context.Context, roomID id.RoomID) { msg.WriteString("To get started, assign an email address to this room by sending a `") msg.WriteString(b.prefix) msg.WriteString(" ") - msg.WriteString(optionMailbox) + msg.WriteString(roomOptionMailbox) msg.WriteString("` command.\n") msg.WriteString("You will then be able to send emails to `SOME_INBOX@") @@ -221,7 +221,7 @@ func (b *Bot) sendHelp(ctx context.Context) { case true: msg.WriteString("(currently `") msg.WriteString(value) - if cmd.key == optionMailbox { + if cmd.key == roomOptionMailbox { msg.WriteString("@") msg.WriteString(b.domain) } diff --git a/bot/command_admin.go b/bot/command_admin.go index 38ad306..4b5bc0c 100644 --- a/bot/command_admin.go +++ b/bot/command_admin.go @@ -13,7 +13,7 @@ import ( func (b *Bot) sendMailboxes(ctx context.Context) { evt := eventFromContext(ctx) - mailboxes := map[string]roomsettings{} + mailboxes := map[string]roomSettings{} slice := []string{} b.rooms.Range(func(key any, value any) bool { if key == nil { @@ -79,7 +79,7 @@ func (b *Bot) runDelete(ctx context.Context, commandSlice []string) { roomID := v.(id.RoomID) b.rooms.Delete(mailbox) - err := b.setRoomSettings(roomID, roomsettings{}) + err := b.setRoomSettings(roomID, roomSettings{}) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return diff --git a/bot/command_owner.go b/bot/command_owner.go index 443dca3..becd5fe 100644 --- a/bot/command_owner.go +++ b/bot/command_owner.go @@ -13,7 +13,7 @@ func (b *Bot) runStop(ctx context.Context) { return } - mailbox := cfg.Get(optionMailbox) + mailbox := cfg.Get(roomOptionMailbox) if mailbox == "" { b.SendNotice(ctx, evt.RoomID, "that room is not configured yet") return @@ -21,7 +21,7 @@ func (b *Bot) runStop(ctx context.Context) { b.rooms.Delete(mailbox) - err = b.setRoomSettings(evt.RoomID, roomsettings{}) + err = b.setRoomSettings(evt.RoomID, roomSettings{}) if err != nil { b.Error(ctx, evt.RoomID, "cannot update settings: %v", err) return @@ -52,7 +52,7 @@ func (b *Bot) getOption(ctx context.Context, name string) { return } - if name == optionMailbox { + if name == roomOptionMailbox { value = value + "@" + b.domain } @@ -66,7 +66,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { } evt := eventFromContext(ctx) - if name == optionMailbox { + if name == roomOptionMailbox { existingID, ok := b.GetMapping(value) if ok && existingID != "" && existingID != evt.RoomID { b.SendNotice(ctx, evt.RoomID, fmt.Sprintf("Mailbox `%s@%s` already taken, kupo", value, b.domain)) @@ -83,8 +83,8 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { old := cfg.Get(name) cfg.Set(name, value) - if name == optionMailbox { - cfg.Set(optionOwner, evt.Sender.String()) + if name == roomOptionMailbox { + cfg.Set(roomOptionOwner, evt.Sender.String()) if old != "" { b.rooms.Delete(old) } @@ -98,7 +98,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) { return } - if name == optionMailbox { + if name == roomOptionMailbox { value = value + "@" + b.domain } diff --git a/bot/email.go b/bot/email.go index a7c6349..2981136 100644 --- a/bot/email.go +++ b/bot/email.go @@ -21,7 +21,7 @@ const ( eventInReplyToKey = "cc.etke.postmoogle.inReplyTo" ) -func email2content(email *utils.Email, cfg roomsettings, threadID id.EventID) *event.Content { +func email2content(email *utils.Email, cfg roomSettings, threadID id.EventID) *event.Content { var text strings.Builder if !cfg.NoSender() { text.WriteString("From: ") diff --git a/bot/settings_bot.go b/bot/settings_bot.go index dc44379..6173172 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -14,20 +14,20 @@ const ( botOptionUsers = "users" ) -type botsettings map[string]string +type botSettings map[string]string // Get option -func (s botsettings) Get(key string) string { +func (s botSettings) Get(key string) string { return s[strings.ToLower(strings.TrimSpace(key))] } // Set option -func (s botsettings) Set(key, value string) { +func (s botSettings) Set(key, value string) { s[strings.ToLower(strings.TrimSpace(key))] = value } // Users option -func (s botsettings) Users() []string { +func (s botSettings) Users() []string { return strings.Split(s.Get(botOptionUsers), " ") } @@ -47,13 +47,13 @@ func (b *Bot) migrateBotSettings(users []string) error { return nil } -func (b *Bot) getBotSettings() botsettings { +func (b *Bot) getBotSettings() botSettings { cfg := b.botcfg.Get(acBotSettingsKey) if cfg != nil { return cfg } - config := botsettings{} + config := botSettings{} err := b.lp.GetClient().GetAccountData(acBotSettingsKey, &config) if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { @@ -67,7 +67,7 @@ func (b *Bot) getBotSettings() botsettings { return config } -func (b *Bot) setBotSettings(cfg botsettings) error { +func (b *Bot) setBotSettings(cfg botSettings) error { b.botcfg.Set(acBotSettingsKey, cfg) return utils.UnwrapError(b.lp.GetClient().SetAccountData(acBotSettingsKey, cfg)) } diff --git a/bot/settings_room.go b/bot/settings_room.go index f65c021..ce0bfd6 100644 --- a/bot/settings_room.go +++ b/bot/settings_room.go @@ -14,16 +14,16 @@ const acRoomSettingsKey = "cc.etke.postmoogle.settings" // option keys const ( - optionOwner = "owner" - optionMailbox = "mailbox" - optionNoSender = "nosender" - optionNoSubject = "nosubject" - optionNoHTML = "nohtml" - optionNoThreads = "nothreads" - optionNoFiles = "nofiles" + roomOptionOwner = "owner" + roomOptionMailbox = "mailbox" + roomOptionNoSender = "nosender" + roomOptionNoSubject = "nosubject" + roomOptionNoHTML = "nohtml" + roomOptionNoThreads = "nothreads" + roomOptionNoFiles = "nofiles" ) -type roomsettings map[string]string +type roomSettings map[string]string // settingsOld of a room type settingsOld struct { @@ -33,41 +33,41 @@ type settingsOld struct { } // Get option -func (s roomsettings) Get(key string) string { +func (s roomSettings) Get(key string) string { return s[strings.ToLower(strings.TrimSpace(key))] } // Set option -func (s roomsettings) Set(key, value string) { +func (s roomSettings) Set(key, value string) { s[strings.ToLower(strings.TrimSpace(key))] = value } -func (s roomsettings) Mailbox() string { - return s.Get(optionMailbox) +func (s roomSettings) Mailbox() string { + return s.Get(roomOptionMailbox) } -func (s roomsettings) Owner() string { - return s.Get(optionOwner) +func (s roomSettings) Owner() string { + return s.Get(roomOptionOwner) } -func (s roomsettings) NoSender() bool { - return utils.Bool(s.Get(optionNoSender)) +func (s roomSettings) NoSender() bool { + return utils.Bool(s.Get(roomOptionNoSender)) } -func (s roomsettings) NoSubject() bool { - return utils.Bool(s.Get(optionNoSubject)) +func (s roomSettings) NoSubject() bool { + return utils.Bool(s.Get(roomOptionNoSubject)) } -func (s roomsettings) NoHTML() bool { - return utils.Bool(s.Get(optionNoHTML)) +func (s roomSettings) NoHTML() bool { + return utils.Bool(s.Get(roomOptionNoHTML)) } -func (s roomsettings) NoThreads() bool { - return utils.Bool(s.Get(optionNoThreads)) +func (s roomSettings) NoThreads() bool { + return utils.Bool(s.Get(roomOptionNoThreads)) } -func (s roomsettings) NoFiles() bool { - return utils.Bool(s.Get(optionNoFiles)) +func (s roomSettings) NoFiles() bool { + return utils.Bool(s.Get(roomOptionNoFiles)) } // TODO: remove after migration @@ -82,10 +82,10 @@ func (b *Bot) migrateSettings(roomID id.RoomID) { if config.Mailbox == "" { return } - cfg := roomsettings{} - cfg.Set(optionMailbox, config.Mailbox) - cfg.Set(optionOwner, config.Owner.String()) - cfg.Set(optionNoSender, strconv.FormatBool(config.NoSender)) + cfg := roomSettings{} + cfg.Set(roomOptionMailbox, config.Mailbox) + cfg.Set(roomOptionOwner, config.Owner.String()) + cfg.Set(roomOptionNoSender, strconv.FormatBool(config.NoSender)) err = b.setRoomSettings(roomID, cfg) if err != nil { @@ -93,13 +93,13 @@ func (b *Bot) migrateSettings(roomID id.RoomID) { } } -func (b *Bot) getRoomSettings(roomID id.RoomID) (roomsettings, error) { +func (b *Bot) getRoomSettings(roomID id.RoomID) (roomSettings, error) { cfg := b.cfg.Get(roomID.String()) if cfg != nil { return cfg, nil } - config := roomsettings{} + config := roomSettings{} err := b.lp.GetClient().GetRoomAccountData(roomID, acRoomSettingsKey, &config) if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { @@ -115,7 +115,7 @@ func (b *Bot) getRoomSettings(roomID id.RoomID) (roomsettings, error) { return config, utils.UnwrapError(err) } -func (b *Bot) setRoomSettings(roomID id.RoomID, cfg roomsettings) error { +func (b *Bot) setRoomSettings(roomID id.RoomID, cfg roomSettings) error { b.cfg.Set(roomID.String(), cfg) return utils.UnwrapError(b.lp.GetClient().SetRoomAccountData(roomID, acRoomSettingsKey, cfg)) } From 00b84fba0e682f03520bc2795a6c244f2aedb2e2 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 14:47:16 +0300 Subject: [PATCH 05/10] cache even unexisting bot settings --- bot/settings_bot.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bot/settings_bot.go b/bot/settings_bot.go index 6173172..eb208d3 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -58,9 +58,12 @@ func (b *Bot) getBotSettings() botSettings { if err != nil { if strings.Contains(err.Error(), "M_NOT_FOUND") { err = nil + } else { + b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) } - b.log.Error("cannot get bot settings: %v", utils.UnwrapError(err)) - } else { + } + + if err == nil { b.botcfg.Set(acBotSettingsKey, config) } From ea1ef9da7f5382d1859753236205cf9496fd64f1 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 15:00:34 +0300 Subject: [PATCH 06/10] !pm users changes --- bot/command_admin.go | 4 ++-- bot/settings_bot.go | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bot/command_admin.go b/bot/command_admin.go index 4b5bc0c..114b043 100644 --- a/bot/command_admin.go +++ b/bot/command_admin.go @@ -102,8 +102,8 @@ func (b *Bot) runUsers(ctx context.Context, commandSlice []string) { msg.WriteString("Usage: `") msg.WriteString(b.prefix) msg.WriteString(" users PATTERN1 PATTERN2 PATTERN3...`") - msg.WriteString("where patterns like `@someone:example.com ") - msg.WriteString(" @bot.*:example.com @*:another.com @*:*`\n") + msg.WriteString("where each pattern is like `@someone:example.com`, ") + msg.WriteString("`@bot.*:example.com`, `@*:another.com`, or `@*:*`\n") b.SendNotice(ctx, evt.RoomID, msg.String()) return diff --git a/bot/settings_bot.go b/bot/settings_bot.go index eb208d3..53af08f 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -28,7 +28,11 @@ func (s botSettings) Set(key, value string) { // Users option func (s botSettings) Users() []string { - return strings.Split(s.Get(botOptionUsers), " ") + value := s.Get(botOptionUsers) + if strings.Contains(value, " ") { + return strings.Split(value, " ") + } + return []string{} } // TODO: remove after migration From cec2761911a8f056498a3f1f87368cfb2c5b8665 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 15:43:06 +0300 Subject: [PATCH 07/10] users adjustments --- bot/bot.go | 12 +----------- bot/command_admin.go | 7 ++++++- bot/settings_bot.go | 23 ++++++++++++++++++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/bot/bot.go b/bot/bot.go index 195f273..e8b1d01 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -50,24 +50,14 @@ func New( lp: lp, mu: map[id.RoomID]*sync.Mutex{}, } - err := b.migrateBotSettings(users) + err := b.initBotUsers(users) if err != nil { return nil, err } - - _, homeserver, err := lp.GetClient().UserID.Parse() - if err != nil { - return nil, err - } - allowedUsers, uerr := parseMXIDpatterns(b.getBotSettings().Users(), "@*:"+homeserver) - if uerr != nil { - return nil, uerr - } allowedAdmins, aerr := parseMXIDpatterns(admins, "") if aerr != nil { return nil, aerr } - b.allowedUsers = allowedUsers b.allowedAdmins = allowedAdmins b.commands = b.buildCommandList() diff --git a/bot/command_admin.go b/bot/command_admin.go index 114b043..978d8eb 100644 --- a/bot/command_admin.go +++ b/bot/command_admin.go @@ -109,8 +109,13 @@ func (b *Bot) runUsers(ctx context.Context, commandSlice []string) { return } + _, homeserver, err := b.lp.GetClient().UserID.Parse() + if err != nil { + b.SendError(ctx, evt.RoomID, fmt.Sprintf("invalid userID: %v", err)) + } + patterns := commandSlice[1:] - allowedUsers, err := parseMXIDpatterns(patterns, "") + allowedUsers, err := parseMXIDpatterns(patterns, "@*:"+homeserver) if err != nil { b.SendError(ctx, evt.RoomID, fmt.Sprintf("invalid patterns: %v", err)) return diff --git a/bot/settings_bot.go b/bot/settings_bot.go index 53af08f..858fca1 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -35,16 +35,29 @@ func (s botSettings) Users() []string { return []string{} } -// TODO: remove after migration -func (b *Bot) migrateBotSettings(users []string) error { +func (b *Bot) initBotUsers(users []string) error { + _, homeserver, err := b.lp.GetClient().UserID.Parse() + if err != nil { + return err + } config := b.getBotSettings() - cfgUsers := config.Users() - if len(users) > 0 && len(cfgUsers) == 0 { - _, err := parseMXIDpatterns(users, "") + oldUsers := config.Get(botOptionUsers) + // TODO: remove after migration + if len(users) > 0 && oldUsers == "" { + _, err := parseMXIDpatterns(users, "@*:"+homeserver) if err != nil { return err } config.Set(botOptionUsers, strings.Join(users, " ")) + } + + allowedUsers, uerr := parseMXIDpatterns(config.Users(), "@*:"+homeserver) + if uerr != nil { + return uerr + } + b.allowedUsers = allowedUsers + + if oldUsers != config.Get(botOptionUsers) { return b.setBotSettings(config) } From 0c74ae02fbadf33feb8b0662ab37efa0ed4c2ef0 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 16:13:10 +0300 Subject: [PATCH 08/10] fix one value --- bot/settings_bot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/settings_bot.go b/bot/settings_bot.go index 858fca1..2a7dbbd 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -32,7 +32,7 @@ func (s botSettings) Users() []string { if strings.Contains(value, " ") { return strings.Split(value, " ") } - return []string{} + return []string{value} } func (b *Bot) initBotUsers(users []string) error { From 84b1900dbbce435afc9ec8df74e4aff41f5ef875 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 18:29:16 +0300 Subject: [PATCH 09/10] adjust initBotUsers() --- bot/bot.go | 11 +++++++++-- bot/settings_bot.go | 37 +++++++++++++++---------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/bot/bot.go b/bot/bot.go index e8b1d01..9365e5e 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -37,7 +37,7 @@ func New( log *logger.Logger, prefix string, domain string, - users []string, + envUsers []string, admins []string, ) (*Bot, error) { b := &Bot{ @@ -50,15 +50,22 @@ func New( lp: lp, mu: map[id.RoomID]*sync.Mutex{}, } - err := b.initBotUsers(users) + users, err := b.initBotUsers(envUsers) if err != nil { return nil, err } + allowedUsers, uerr := parseMXIDpatterns(users, "") + if uerr != nil { + return nil, uerr + } + b.allowedUsers = allowedUsers + allowedAdmins, aerr := parseMXIDpatterns(admins, "") if aerr != nil { return nil, aerr } b.allowedAdmins = allowedAdmins + b.commands = b.buildCommandList() return b, nil diff --git a/bot/settings_bot.go b/bot/settings_bot.go index 2a7dbbd..5710081 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -35,33 +35,26 @@ func (s botSettings) Users() []string { return []string{value} } -func (b *Bot) initBotUsers(users []string) error { - _, homeserver, err := b.lp.GetClient().UserID.Parse() - if err != nil { - return err - } +func (b *Bot) initBotUsers(envUsers []string) ([]string, error) { config := b.getBotSettings() - oldUsers := config.Get(botOptionUsers) - // TODO: remove after migration - if len(users) > 0 && oldUsers == "" { - _, err := parseMXIDpatterns(users, "@*:"+homeserver) + cfgUsers := config.Users() + if len(cfgUsers) > 0 { + // already migrated + return cfgUsers, nil + } + if len(envUsers) == 0 { + _, homeserver, err := b.lp.GetClient().UserID.Parse() if err != nil { - return err + return nil, err } - config.Set(botOptionUsers, strings.Join(users, " ")) + config.Set(botOptionUsers, "@*:"+homeserver) + } else { + // Initialize from environment variable + // TODO: remove this migration later and always initialize to `"@*:"+homeserver` + config.Set(botOptionUsers, strings.Join(envUsers, " ")) } - allowedUsers, uerr := parseMXIDpatterns(config.Users(), "@*:"+homeserver) - if uerr != nil { - return uerr - } - b.allowedUsers = allowedUsers - - if oldUsers != config.Get(botOptionUsers) { - return b.setBotSettings(config) - } - - return nil + return config.Users(), b.setBotSettings(config) } func (b *Bot) getBotSettings() botSettings { From 233d212143b27de7d14037027fb54e1e2185dd01 Mon Sep 17 00:00:00 2001 From: Aine Date: Tue, 30 Aug 2022 18:35:10 +0300 Subject: [PATCH 10/10] fix botSettings.Users() --- bot/settings_bot.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bot/settings_bot.go b/bot/settings_bot.go index 5710081..72ee168 100644 --- a/bot/settings_bot.go +++ b/bot/settings_bot.go @@ -29,9 +29,14 @@ func (s botSettings) Set(key, value string) { // Users option func (s botSettings) Users() []string { value := s.Get(botOptionUsers) + if value == "" { + return []string{} + } + if strings.Contains(value, " ") { return strings.Split(value, " ") } + return []string{value} }