refactor to mautrix 0.17.x; update deps

This commit is contained in:
Aine
2024-02-11 20:47:04 +02:00
parent 0a9701f4c9
commit dd0ad4c245
237 changed files with 9091 additions and 3317 deletions

View File

@@ -22,19 +22,19 @@ func parseMXIDpatterns(patterns []string, defaultPattern string) ([]*regexp.Rege
return mxidwc.ParsePatterns(patterns)
}
func (b *Bot) allowUsers(actorID id.UserID, targetRoomID id.RoomID) bool {
func (b *Bot) allowUsers(ctx context.Context, actorID id.UserID, targetRoomID id.RoomID) bool {
// first, check if it's an allowed user
if mxidwc.Match(actorID.String(), b.allowedUsers) {
return true
}
// second, check if it's an admin (admin may not fit the allowed users pattern)
if b.allowAdmin(actorID, targetRoomID) {
if b.allowAdmin(ctx, actorID, targetRoomID) {
return true
}
// then, check if it's the owner (same as above)
cfg, err := b.cfg.GetRoom(targetRoomID)
cfg, err := b.cfg.GetRoom(ctx, targetRoomID)
if err == nil && cfg.Owner() == actorID.String() {
return true
}
@@ -42,15 +42,15 @@ func (b *Bot) allowUsers(actorID id.UserID, targetRoomID id.RoomID) bool {
return false
}
func (b *Bot) allowAnyone(_ id.UserID, _ id.RoomID) bool {
func (b *Bot) allowAnyone(_ context.Context, _ id.UserID, _ id.RoomID) bool {
return true
}
func (b *Bot) allowOwner(actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(actorID, targetRoomID) {
func (b *Bot) allowOwner(ctx context.Context, actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(ctx, actorID, targetRoomID) {
return false
}
cfg, err := b.cfg.GetRoom(targetRoomID)
cfg, err := b.cfg.GetRoom(ctx, targetRoomID)
if err != nil {
b.Error(context.Background(), "failed to retrieve settings: %v", err)
return false
@@ -61,19 +61,19 @@ func (b *Bot) allowOwner(actorID id.UserID, targetRoomID id.RoomID) bool {
return true
}
return owner == actorID.String() || b.allowAdmin(actorID, targetRoomID)
return owner == actorID.String() || b.allowAdmin(ctx, actorID, targetRoomID)
}
func (b *Bot) allowAdmin(actorID id.UserID, _ id.RoomID) bool {
func (b *Bot) allowAdmin(_ context.Context, actorID id.UserID, _ id.RoomID) bool {
return mxidwc.Match(actorID.String(), b.allowedAdmins)
}
func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(actorID, targetRoomID) {
func (b *Bot) allowSend(ctx context.Context, actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(ctx, actorID, targetRoomID) {
return false
}
cfg, err := b.cfg.GetRoom(targetRoomID)
cfg, err := b.cfg.GetRoom(ctx, targetRoomID)
if err != nil {
b.Error(context.Background(), "failed to retrieve settings: %v", err)
return false
@@ -82,14 +82,14 @@ func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
return !cfg.NoSend()
}
func (b *Bot) allowReply(actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(actorID, targetRoomID) {
func (b *Bot) allowReply(ctx context.Context, actorID id.UserID, targetRoomID id.RoomID) bool {
if !b.allowUsers(ctx, actorID, targetRoomID) {
return false
}
cfg, err := b.cfg.GetRoom(targetRoomID)
cfg, err := b.cfg.GetRoom(ctx, targetRoomID)
if err != nil {
b.Error(context.Background(), "failed to retrieve settings: %v", err)
b.Error(ctx, "failed to retrieve settings: %v", err)
return false
}
@@ -106,30 +106,30 @@ func (b *Bot) isReserved(mailbox string) bool {
}
// IsGreylisted checks if host is in greylist
func (b *Bot) IsGreylisted(addr net.Addr) bool {
if b.cfg.GetBot().Greylist() == 0 {
func (b *Bot) IsGreylisted(ctx context.Context, addr net.Addr) bool {
if b.cfg.GetBot(ctx).Greylist() == 0 {
return false
}
greylist := b.cfg.GetGreylist()
greylist := b.cfg.GetGreylist(ctx)
greylistedAt, ok := greylist.Get(addr)
if !ok {
b.log.Debug().Str("addr", addr.String()).Msg("greylisting")
greylist.Add(addr)
err := b.cfg.SetGreylist(greylist)
err := b.cfg.SetGreylist(ctx, greylist)
if err != nil {
b.log.Error().Err(err).Str("addr", addr.String()).Msg("cannot update greylist")
}
return true
}
duration := time.Duration(b.cfg.GetBot().Greylist()) * time.Minute
duration := time.Duration(b.cfg.GetBot(ctx).Greylist()) * time.Minute
return greylistedAt.Add(duration).After(time.Now().UTC())
}
// IsBanned checks if address is banned
func (b *Bot) IsBanned(addr net.Addr) bool {
return b.cfg.GetBanlist().Has(addr)
func (b *Bot) IsBanned(ctx context.Context, addr net.Addr) bool {
return b.cfg.GetBanlist(ctx).Has(addr)
}
// IsTrusted checks if address is a trusted (proxy)
@@ -146,12 +146,12 @@ func (b *Bot) IsTrusted(addr net.Addr) bool {
}
// Ban an address automatically
func (b *Bot) BanAuto(addr net.Addr) {
if !b.cfg.GetBot().BanlistEnabled() {
func (b *Bot) BanAuto(ctx context.Context, addr net.Addr) {
if !b.cfg.GetBot(ctx).BanlistEnabled() {
return
}
if !b.cfg.GetBot().BanlistAuto() {
if !b.cfg.GetBot(ctx).BanlistAuto() {
return
}
@@ -159,21 +159,21 @@ func (b *Bot) BanAuto(addr net.Addr) {
return
}
b.log.Debug().Str("addr", addr.String()).Msg("attempting to automatically ban")
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
banlist.Add(addr)
err := b.cfg.SetBanlist(banlist)
err := b.cfg.SetBanlist(ctx, banlist)
if err != nil {
b.log.Error().Err(err).Str("addr", addr.String()).Msg("cannot update banlist")
}
}
// Ban an address for incorrect auth automatically
func (b *Bot) BanAuth(addr net.Addr) {
if !b.cfg.GetBot().BanlistEnabled() {
func (b *Bot) BanAuth(ctx context.Context, addr net.Addr) {
if !b.cfg.GetBot(ctx).BanlistEnabled() {
return
}
if !b.cfg.GetBot().BanlistAuth() {
if !b.cfg.GetBot(ctx).BanlistAuth() {
return
}
@@ -181,33 +181,33 @@ func (b *Bot) BanAuth(addr net.Addr) {
return
}
b.log.Debug().Str("addr", addr.String()).Msg("attempting to automatically ban")
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
banlist.Add(addr)
err := b.cfg.SetBanlist(banlist)
err := b.cfg.SetBanlist(ctx, banlist)
if err != nil {
b.log.Error().Err(err).Str("addr", addr.String()).Msg("cannot update banlist")
}
}
// Ban an address manually
func (b *Bot) BanManually(addr net.Addr) {
if !b.cfg.GetBot().BanlistEnabled() {
func (b *Bot) BanManually(ctx context.Context, addr net.Addr) {
if !b.cfg.GetBot(ctx).BanlistEnabled() {
return
}
if b.IsTrusted(addr) {
return
}
b.log.Debug().Str("addr", addr.String()).Msg("attempting to manually ban")
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
banlist.Add(addr)
err := b.cfg.SetBanlist(banlist)
err := b.cfg.SetBanlist(ctx, banlist)
if err != nil {
b.log.Error().Err(err).Str("addr", addr.String()).Msg("cannot update banlist")
}
}
// AllowAuth check if SMTP login (email) and password are valid
func (b *Bot) AllowAuth(email, password string) (id.RoomID, bool) {
func (b *Bot) AllowAuth(ctx context.Context, email, password string) (id.RoomID, bool) {
var suffix bool
for _, domain := range b.domains {
if strings.HasSuffix(email, "@"+domain) {
@@ -223,7 +223,7 @@ func (b *Bot) AllowAuth(email, password string) (id.RoomID, bool) {
if !ok {
return "", false
}
cfg, err := b.cfg.GetRoom(roomID)
cfg, err := b.cfg.GetRoom(ctx, roomID)
if err != nil {
b.log.Error().Err(err).Msg("failed to retrieve settings")
return "", false

View File

@@ -1,13 +1,14 @@
package bot
import (
"context"
"fmt"
"maunium.net/go/mautrix/format"
"maunium.net/go/mautrix/id"
)
type activationFlow func(id.UserID, id.RoomID, string) bool
type activationFlow func(context.Context, id.UserID, id.RoomID, string) bool
func (b *Bot) getActivationFlow() activationFlow {
switch b.mbxc.Activation {
@@ -21,19 +22,19 @@ func (b *Bot) getActivationFlow() activationFlow {
}
// ActivateMailbox using the configured flow
func (b *Bot) ActivateMailbox(ownerID id.UserID, roomID id.RoomID, mailbox string) bool {
func (b *Bot) ActivateMailbox(ctx context.Context, ownerID id.UserID, roomID id.RoomID, mailbox string) bool {
flow := b.getActivationFlow()
return flow(ownerID, roomID, mailbox)
return flow(ctx, ownerID, roomID, mailbox)
}
func (b *Bot) activateNone(ownerID id.UserID, roomID id.RoomID, mailbox string) bool {
func (b *Bot) activateNone(_ context.Context, ownerID id.UserID, roomID id.RoomID, mailbox string) bool {
b.log.Debug().Str("mailbox", mailbox).Str("roomID", roomID.String()).Str("ownerID", ownerID.String()).Msg("activating mailbox through the flow 'none'")
b.rooms.Store(mailbox, roomID)
return true
}
func (b *Bot) activateNotify(ownerID id.UserID, roomID id.RoomID, mailbox string) bool {
func (b *Bot) activateNotify(ctx context.Context, ownerID id.UserID, roomID id.RoomID, mailbox string) bool {
b.log.Debug().Str("mailbox", mailbox).Str("roomID", roomID.String()).Str("ownerID", ownerID.String()).Msg("activating mailbox through the flow 'notify'")
b.rooms.Store(mailbox, roomID)
if len(b.adminRooms) == 0 {
@@ -43,7 +44,7 @@ func (b *Bot) activateNotify(ownerID id.UserID, roomID id.RoomID, mailbox string
msg := fmt.Sprintf("Mailbox %q has been registered by %q for the room %q", mailbox, ownerID, roomID)
for _, adminRoom := range b.adminRooms {
content := format.RenderMarkdown(msg, true, true)
_, err := b.lp.Send(adminRoom, &content)
_, err := b.lp.Send(ctx, adminRoom, &content)
if err != nil {
b.log.Info().Str("adminRoom", adminRoom.String()).Msg("cannot send mailbox activation notification to the admin room")
continue

View File

@@ -36,6 +36,7 @@ type Bot struct {
rooms sync.Map
proxies []string
sendmail func(string, string, string) error
psd *utils.PSD
cfg *config.Manager
log *zerolog.Logger
lp *linkpearl.Linkpearl
@@ -50,6 +51,7 @@ func New(
lp *linkpearl.Linkpearl,
log *zerolog.Logger,
cfg *config.Manager,
psd *utils.PSD,
proxies []string,
prefix string,
domains []string,
@@ -63,13 +65,14 @@ func New(
adminRooms: []id.RoomID{},
proxies: proxies,
mbxc: mbxc,
psd: psd,
cfg: cfg,
log: log,
lp: lp,
mu: utils.NewMutex(),
q: q,
}
users, err := b.initBotUsers()
users, err := b.initBotUsers(context.Background())
if err != nil {
return nil, err
}
@@ -105,7 +108,7 @@ func (b *Bot) Error(ctx context.Context, message string, args ...any) {
}
var noThreads bool
cfg, cerr := b.cfg.GetRoom(evt.RoomID)
cfg, cerr := b.cfg.GetRoom(ctx, evt.RoomID)
if cerr == nil {
noThreads = cfg.NoThreads()
}
@@ -115,16 +118,17 @@ func (b *Bot) Error(ctx context.Context, message string, args ...any) {
relatesTo = linkpearl.RelatesTo(threadID, noThreads)
}
b.lp.SendNotice(evt.RoomID, "ERROR: "+err.Error(), relatesTo)
b.lp.SendNotice(ctx, evt.RoomID, "ERROR: "+err.Error(), relatesTo)
}
// Start performs matrix /sync
func (b *Bot) Start(statusMsg string) error {
if err := b.migrateMautrix015(); err != nil {
ctx := context.Background()
if err := b.migrateMautrix015(ctx); err != nil {
return err
}
if err := b.syncRooms(); err != nil {
if err := b.syncRooms(ctx); err != nil {
return err
}
@@ -135,7 +139,8 @@ func (b *Bot) Start(statusMsg string) error {
// Stop the bot
func (b *Bot) Stop() {
err := b.lp.GetClient().SetPresence(event.PresenceOffline)
ctx := context.Background()
err := b.lp.GetClient().SetPresence(ctx, event.PresenceOffline)
if err != nil {
b.log.Error().Err(err).Msg("cannot set presence = offline")
}

View File

@@ -46,7 +46,7 @@ type (
key string
description string
sanitizer func(string) string
allowed func(id.UserID, id.RoomID) bool
allowed func(context.Context, id.UserID, id.RoomID) bool
}
commandList []command
)
@@ -351,7 +351,7 @@ func (b *Bot) initCommands() commandList {
func (b *Bot) handle(ctx context.Context) {
evt := eventFromContext(ctx)
err := b.lp.GetClient().MarkRead(evt.RoomID, evt.ID)
err := b.lp.GetClient().MarkRead(ctx, evt.RoomID, evt.ID)
if err != nil {
b.log.Error().Err(err).Msg("cannot send read receipt")
}
@@ -378,14 +378,14 @@ func (b *Bot) handle(ctx context.Context) {
if cmd == nil {
return
}
_, err = b.lp.GetClient().UserTyping(evt.RoomID, true, 30*time.Second)
_, err = b.lp.GetClient().UserTyping(ctx, evt.RoomID, true, 30*time.Second)
if err != nil {
b.log.Error().Err(err).Msg("cannot send typing notification")
}
defer b.lp.GetClient().UserTyping(evt.RoomID, false, 30*time.Second) //nolint:errcheck // we don't care
defer b.lp.GetClient().UserTyping(ctx, evt.RoomID, false, 30*time.Second) //nolint:errcheck // we don't care
if !cmd.allowed(evt.Sender, evt.RoomID) {
b.lp.SendNotice(evt.RoomID, "not allowed to do that, kupo")
if !cmd.allowed(ctx, evt.Sender, evt.RoomID) {
b.lp.SendNotice(ctx, evt.RoomID, "not allowed to do that, kupo")
return
}
@@ -452,7 +452,7 @@ func (b *Bot) parseCommand(message string, toLower bool) []string {
return strings.Split(strings.TrimSpace(message), " ")
}
func (b *Bot) sendIntroduction(roomID id.RoomID) {
func (b *Bot) sendIntroduction(ctx context.Context, roomID id.RoomID) {
var msg strings.Builder
msg.WriteString("Hello, kupo!\n\n")
@@ -468,7 +468,7 @@ func (b *Bot) sendIntroduction(roomID id.RoomID) {
msg.WriteString(utils.EmailsList("SOME_INBOX", ""))
msg.WriteString("` and have them appear in this room.")
b.lp.SendNotice(roomID, msg.String())
b.lp.SendNotice(ctx, roomID, msg.String())
}
func (b *Bot) getHelpValue(cfg config.Room, cmd command) string {
@@ -497,7 +497,7 @@ func (b *Bot) getHelpValue(cfg config.Room, cmd command) string {
func (b *Bot) sendHelp(ctx context.Context) {
evt := eventFromContext(ctx)
cfg, serr := b.cfg.GetRoom(evt.RoomID)
cfg, serr := b.cfg.GetRoom(ctx, evt.RoomID)
if serr != nil {
b.log.Error().Err(serr).Msg("cannot retrieve settings")
}
@@ -505,7 +505,7 @@ func (b *Bot) sendHelp(ctx context.Context) {
var msg strings.Builder
msg.WriteString("The following commands are supported and accessible to you:\n\n")
for _, cmd := range b.commands {
if !cmd.allowed(evt.Sender, evt.RoomID) {
if !cmd.allowed(ctx, evt.Sender, evt.RoomID) {
continue
}
if cmd.key == "" {
@@ -528,7 +528,7 @@ func (b *Bot) sendHelp(ctx context.Context) {
msg.WriteString("\n")
}
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) runSend(ctx context.Context) {
@@ -538,7 +538,7 @@ func (b *Bot) runSend(ctx context.Context) {
return
}
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve room settings: %v", err)
return
@@ -555,11 +555,11 @@ func (b *Bot) runSend(ctx context.Context) {
func (b *Bot) getSendDetails(ctx context.Context) (to, subject, body string, ok bool) {
evt := eventFromContext(ctx)
if !b.allowSend(evt.Sender, evt.RoomID) {
if !b.allowSend(ctx, evt.Sender, evt.RoomID) {
return "", "", "", false
}
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve room settings: %v", err)
return "", "", "", false
@@ -568,7 +568,7 @@ func (b *Bot) getSendDetails(ctx context.Context) (to, subject, body string, ok
commandSlice := b.parseCommand(evt.Content.AsMessage().Body, false)
to, subject, body, err = utils.ParseSend(commandSlice)
if errors.Is(err, utils.ErrInvalidArgs) {
b.lp.SendNotice(evt.RoomID, fmt.Sprintf(
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf(
"Usage:\n"+
"```\n"+
"%s send someone@example.com\n"+
@@ -585,7 +585,7 @@ func (b *Bot) getSendDetails(ctx context.Context) (to, subject, body string, ok
mailbox := cfg.Mailbox()
if mailbox == "" {
b.lp.SendNotice(evt.RoomID, "mailbox is not configured, kupo", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "mailbox is not configured, kupo", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return "", "", "", false
}
@@ -608,8 +608,8 @@ func (b *Bot) runSendCommand(ctx context.Context, cfg config.Room, tos []string,
}
}
b.lock(evt.RoomID, evt.ID)
defer b.unlock(evt.RoomID, evt.ID)
b.lock(ctx, evt.RoomID, evt.ID)
defer b.unlock(ctx, evt.RoomID, evt.ID)
domain := utils.SanitizeDomain(cfg.Domain())
from := cfg.Mailbox() + "@" + domain
@@ -617,12 +617,12 @@ func (b *Bot) runSendCommand(ctx context.Context, cfg config.Room, tos []string,
for _, to := range tos {
recipients := []string{to}
eml := email.New(ID, "", " "+ID, subject, from, to, to, "", body, htmlBody, nil, nil)
data := eml.Compose(b.cfg.GetBot().DKIMPrivateKey())
data := eml.Compose(b.cfg.GetBot(ctx).DKIMPrivateKey())
if data == "" {
b.lp.SendNotice(evt.RoomID, "email body is empty", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "email body is empty", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return
}
queued, err := b.Sendmail(evt.ID, from, to, data)
queued, err := b.Sendmail(ctx, evt.ID, from, to, data)
if queued {
b.log.Warn().Err(err).Msg("email has been queued")
b.saveSentMetadata(ctx, queued, evt.ID, recipients, eml, cfg)
@@ -635,6 +635,6 @@ func (b *Bot) runSendCommand(ctx context.Context, cfg config.Room, tos []string,
b.saveSentMetadata(ctx, false, evt.ID, recipients, eml, cfg)
}
if len(tos) > 1 {
b.lp.SendNotice(evt.RoomID, "All emails were sent.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "All emails were sent.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
}

View File

@@ -37,7 +37,7 @@ func (b *Bot) sendMailboxes(ctx context.Context) {
if !ok {
return true
}
cfg, err := b.cfg.GetRoom(roomID)
cfg, err := b.cfg.GetRoom(ctx, roomID)
if err != nil {
b.log.Error().Err(err).Msg("cannot retrieve settings")
}
@@ -49,7 +49,7 @@ func (b *Bot) sendMailboxes(ctx context.Context) {
sort.Strings(slice)
if len(slice) == 0 {
b.lp.SendNotice(evt.RoomID, "No mailboxes are managed by the bot so far, kupo!", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "No mailboxes are managed by the bot so far, kupo!", linkpearl.RelatesTo(evt.ID))
return
}
@@ -64,20 +64,20 @@ func (b *Bot) sendMailboxes(ctx context.Context) {
msg.WriteString("\n")
}
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runDelete(ctx context.Context, commandSlice []string) {
evt := eventFromContext(ctx)
if len(commandSlice) < 2 {
b.lp.SendNotice(evt.RoomID, fmt.Sprintf("Usage: `%s delete MAILBOX`", b.prefix), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf("Usage: `%s delete MAILBOX`", b.prefix), linkpearl.RelatesTo(evt.ID))
return
}
mailbox := utils.Mailbox(commandSlice[1])
v, ok := b.rooms.Load(mailbox)
if v == nil || !ok {
b.lp.SendNotice(evt.RoomID, "mailbox does not exists, kupo", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "mailbox does not exists, kupo", linkpearl.RelatesTo(evt.ID))
return
}
roomID, ok := v.(id.RoomID)
@@ -86,18 +86,18 @@ func (b *Bot) runDelete(ctx context.Context, commandSlice []string) {
}
b.rooms.Delete(mailbox)
err := b.cfg.SetRoom(roomID, config.Room{})
err := b.cfg.SetRoom(ctx, roomID, config.Room{})
if err != nil {
b.Error(ctx, "cannot update settings: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "mailbox has been deleted", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "mailbox has been deleted", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runUsers(ctx context.Context, commandSlice []string) {
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) < 2 {
var msg strings.Builder
users := cfg.Users()
@@ -112,35 +112,35 @@ func (b *Bot) runUsers(ctx context.Context, commandSlice []string) {
msg.WriteString("where each pattern is like `@someone:example.com`, ")
msg.WriteString("`@bot.*:example.com`, `@*:another.com`, or `@*:*`\n")
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
return
}
_, homeserver, err := b.lp.GetClient().UserID.Parse()
if err != nil {
b.lp.SendNotice(evt.RoomID, fmt.Sprintf("invalid userID: %v", err), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf("invalid userID: %v", err), linkpearl.RelatesTo(evt.ID))
}
patterns := commandSlice[1:]
allowedUsers, err := parseMXIDpatterns(patterns, "@*:"+homeserver)
if err != nil {
b.lp.SendNotice(evt.RoomID, fmt.Sprintf("invalid patterns: %v", err), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf("invalid patterns: %v", err), linkpearl.RelatesTo(evt.ID))
return
}
cfg.Set(config.BotUsers, strings.Join(patterns, " "))
err = b.cfg.SetBot(cfg)
err = b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot set bot config: %v", err)
}
b.allowedUsers = allowedUsers
b.lp.SendNotice(evt.RoomID, "allowed users updated", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "allowed users updated", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runDKIM(ctx context.Context, commandSlice []string) {
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) > 1 && commandSlice[1] == "reset" {
cfg.Set(config.BotDKIMPrivateKey, "")
cfg.Set(config.BotDKIMSignature, "")
@@ -157,14 +157,14 @@ func (b *Bot) runDKIM(ctx context.Context, commandSlice []string) {
}
cfg.Set(config.BotDKIMSignature, signature)
cfg.Set(config.BotDKIMPrivateKey, private)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot save bot options: %v", err)
return
}
}
b.lp.SendNotice(evt.RoomID, fmt.Sprintf(
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf(
"DKIM signature is: `%s`.\n"+
"You need to add it to DNS records of all domains added to postmoogle (if not already):\n"+
"Add new DNS record with type = `TXT`, key (subdomain/from): `postmoogle._domainkey` and value (to):\n ```\n%s\n```\n"+
@@ -177,7 +177,7 @@ func (b *Bot) runDKIM(ctx context.Context, commandSlice []string) {
func (b *Bot) runCatchAll(ctx context.Context, commandSlice []string) {
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) < 2 {
var msg strings.Builder
msg.WriteString("Currently: `")
@@ -195,30 +195,30 @@ func (b *Bot) runCatchAll(ctx context.Context, commandSlice []string) {
msg.WriteString(" catch-all MAILBOX`")
msg.WriteString("where mailbox is valid and existing mailbox name\n")
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
return
}
mailbox := utils.Mailbox(commandSlice[1])
_, ok := b.GetMapping(mailbox)
_, ok := b.GetMapping(ctx, mailbox)
if !ok {
b.lp.SendNotice(evt.RoomID, "mailbox does not exist, kupo.", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "mailbox does not exist, kupo.", linkpearl.RelatesTo(evt.ID))
return
}
cfg.Set(config.BotCatchAll, mailbox)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot save bot options: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, fmt.Sprintf("Catch-all is set to: `%s` (%s).", mailbox, utils.EmailsList(mailbox, "")), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf("Catch-all is set to: `%s` (%s).", mailbox, utils.EmailsList(mailbox, "")), linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runAdminRoom(ctx context.Context, commandSlice []string) {
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) < 2 {
var msg strings.Builder
msg.WriteString("Currently: `")
@@ -233,13 +233,13 @@ func (b *Bot) runAdminRoom(ctx context.Context, commandSlice []string) {
msg.WriteString(" adminroom ROOM_ID`")
msg.WriteString("where ROOM_ID is valid and existing matrix room id\n")
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
return
}
roomID := b.parseCommand(evt.Content.AsMessage().Body, false)[1] // get original value, without forced lower case
cfg.Set(config.BotAdminRoom, roomID)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot save bot options: %v", err)
return
@@ -247,12 +247,12 @@ func (b *Bot) runAdminRoom(ctx context.Context, commandSlice []string) {
b.adminRooms = append([]id.RoomID{id.RoomID(roomID)}, b.adminRooms...) // make it the first room in list on the fly
b.lp.SendNotice(evt.RoomID, fmt.Sprintf("Admin Room is set to: `%s`.", roomID), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf("Admin Room is set to: `%s`.", roomID), linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) printGreylist(ctx context.Context, roomID id.RoomID) {
cfg := b.cfg.GetBot()
greylist := b.cfg.GetGreylist()
cfg := b.cfg.GetBot(ctx)
greylist := b.cfg.GetGreylist(ctx)
var msg strings.Builder
size := len(greylist)
duration := cfg.Greylist()
@@ -278,7 +278,7 @@ func (b *Bot) printGreylist(ctx context.Context, roomID id.RoomID) {
msg.WriteString("where `MIN` is duration in minutes for automatic greylisting\n")
}
b.lp.SendNotice(roomID, msg.String(), linkpearl.RelatesTo(eventFromContext(ctx).ID))
b.lp.SendNotice(ctx, roomID, msg.String(), linkpearl.RelatesTo(eventFromContext(ctx).ID))
}
func (b *Bot) runGreylist(ctx context.Context, commandSlice []string) {
@@ -287,21 +287,21 @@ func (b *Bot) runGreylist(ctx context.Context, commandSlice []string) {
b.printGreylist(ctx, evt.RoomID)
return
}
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
value := utils.SanitizeIntString(commandSlice[1])
cfg.Set(config.BotGreylist, value)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot set bot config: %v", err)
}
b.lp.SendNotice(evt.RoomID, "greylist duration has been updated", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "greylist duration has been updated", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runBanlist(ctx context.Context, commandSlice []string) {
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) < 2 {
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
var msg strings.Builder
size := len(banlist)
if size > 0 {
@@ -322,26 +322,26 @@ func (b *Bot) runBanlist(ctx context.Context, commandSlice []string) {
msg.WriteString("where each ip is IPv4 or IPv6\n\n")
msg.WriteString("You can find current banlist values below:\n")
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.addBanlistTimeline(ctx, false)
return
}
value := utils.SanitizeBoolString(commandSlice[1])
cfg.Set(config.BotBanlistEnabled, value)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot set bot config: %v", err)
}
b.lp.SendNotice(evt.RoomID, "banlist has been updated", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "banlist has been updated", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runBanlistTotals(ctx context.Context) {
evt := eventFromContext(ctx)
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
var msg strings.Builder
size := len(banlist)
if size == 0 {
b.lp.SendNotice(evt.RoomID, "banlist is empty, kupo.", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "banlist is empty, kupo.", linkpearl.RelatesTo(evt.ID))
return
}
@@ -349,13 +349,13 @@ func (b *Bot) runBanlistTotals(ctx context.Context) {
msg.WriteString(strconv.Itoa(size))
msg.WriteString(" hosts banned\n\n")
msg.WriteString("You can find daily totals below:\n")
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.addBanlistTimeline(ctx, true)
}
func (b *Bot) runBanlistAuth(ctx context.Context, commandSlice []string) { //nolint:dupl // not in that case
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) < 2 {
var msg strings.Builder
msg.WriteString("Currently: `")
@@ -368,21 +368,21 @@ func (b *Bot) runBanlistAuth(ctx context.Context, commandSlice []string) { //nol
msg.WriteString(" banlist:auth true` (banlist itself must be enabled!)\n\n")
}
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
return
}
value := utils.SanitizeBoolString(commandSlice[1])
cfg.Set(config.BotBanlistAuth, value)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot set bot config: %v", err)
}
b.lp.SendNotice(evt.RoomID, "auth banning has been updated", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "auth banning has been updated", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runBanlistAuto(ctx context.Context, commandSlice []string) { //nolint:dupl // not in that case
evt := eventFromContext(ctx)
cfg := b.cfg.GetBot()
cfg := b.cfg.GetBot(ctx)
if len(commandSlice) < 2 {
var msg strings.Builder
msg.WriteString("Currently: `")
@@ -395,16 +395,16 @@ func (b *Bot) runBanlistAuto(ctx context.Context, commandSlice []string) { //nol
msg.WriteString(" banlist:auto true` (banlist itself must be enabled!)\n\n")
}
b.lp.SendNotice(evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, msg.String(), linkpearl.RelatesTo(evt.ID))
return
}
value := utils.SanitizeBoolString(commandSlice[1])
cfg.Set(config.BotBanlistAuto, value)
err := b.cfg.SetBot(cfg)
err := b.cfg.SetBot(ctx, cfg)
if err != nil {
b.Error(ctx, "cannot set bot config: %v", err)
}
b.lp.SendNotice(evt.RoomID, "auto banning has been updated", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "auto banning has been updated", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) runBanlistChange(ctx context.Context, mode string, commandSlice []string) {
@@ -413,11 +413,11 @@ func (b *Bot) runBanlistChange(ctx context.Context, mode string, commandSlice []
b.runBanlist(ctx, commandSlice)
return
}
if !b.cfg.GetBot().BanlistEnabled() {
b.lp.SendNotice(evt.RoomID, "banlist is disabled, you have to enable it first, kupo", linkpearl.RelatesTo(evt.ID))
if !b.cfg.GetBot(ctx).BanlistEnabled() {
b.lp.SendNotice(ctx, evt.RoomID, "banlist is disabled, you have to enable it first, kupo", linkpearl.RelatesTo(evt.ID))
return
}
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
var action func(net.Addr)
if mode == "remove" {
@@ -436,18 +436,18 @@ func (b *Bot) runBanlistChange(ctx context.Context, mode string, commandSlice []
action(addr)
}
err := b.cfg.SetBanlist(banlist)
err := b.cfg.SetBanlist(ctx, banlist)
if err != nil {
b.Error(ctx, "cannot set banlist: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "banlist has been updated, kupo", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "banlist has been updated, kupo", linkpearl.RelatesTo(evt.ID))
}
func (b *Bot) addBanlistTimeline(ctx context.Context, onlyTotals bool) {
evt := eventFromContext(ctx)
banlist := b.cfg.GetBanlist()
banlist := b.cfg.GetBanlist(ctx)
timeline := map[string][]string{}
for ip, ts := range banlist {
key := "???"
@@ -479,22 +479,22 @@ func (b *Bot) addBanlistTimeline(ctx context.Context, onlyTotals bool) {
txt.WriteString(strings.Join(data, "`, `"))
txt.WriteString("`\n")
}
b.lp.SendNotice(evt.RoomID, txt.String(), linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, txt.String(), linkpearl.RelatesTo(evt.ID))
}
}
func (b *Bot) runBanlistReset(ctx context.Context) {
evt := eventFromContext(ctx)
if !b.cfg.GetBot().BanlistEnabled() {
b.lp.SendNotice(evt.RoomID, "banlist is disabled, you have to enable it first, kupo", linkpearl.RelatesTo(evt.ID))
if !b.cfg.GetBot(ctx).BanlistEnabled() {
b.lp.SendNotice(ctx, evt.RoomID, "banlist is disabled, you have to enable it first, kupo", linkpearl.RelatesTo(evt.ID))
return
}
err := b.cfg.SetBanlist(config.List{})
err := b.cfg.SetBanlist(ctx, config.List{})
if err != nil {
b.Error(ctx, "cannot set banlist: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "banlist has been reset, kupo", linkpearl.RelatesTo(evt.ID))
b.lp.SendNotice(ctx, evt.RoomID, "banlist has been reset, kupo", linkpearl.RelatesTo(evt.ID))
}

View File

@@ -16,7 +16,7 @@ import (
func (b *Bot) runStop(ctx context.Context) {
evt := eventFromContext(ctx)
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve settings: %v", err)
return
@@ -24,19 +24,19 @@ func (b *Bot) runStop(ctx context.Context) {
mailbox := cfg.Get(config.RoomMailbox)
if mailbox == "" {
b.lp.SendNotice(evt.RoomID, "that room is not configured yet", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "that room is not configured yet", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return
}
b.rooms.Delete(mailbox)
err = b.cfg.SetRoom(evt.RoomID, config.Room{})
err = b.cfg.SetRoom(ctx, evt.RoomID, config.Room{})
if err != nil {
b.Error(ctx, "cannot update settings: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "mailbox has been disabled", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "mailbox has been disabled", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) handleOption(ctx context.Context, cmd []string) {
@@ -58,7 +58,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.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve settings: %v", err)
return
@@ -73,7 +73,7 @@ func (b *Bot) getOption(ctx context.Context, name string) {
msg := fmt.Sprintf("`%s` is not set, kupo.\n"+
"To set it, send a `%s %s VALUE` command.",
name, b.prefix, name)
b.lp.SendNotice(evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return
}
@@ -91,18 +91,18 @@ func (b *Bot) getOption(ctx context.Context, name string) {
"or just set a new one with `%s %s NEW_PASSWORD`.",
b.prefix, name)
}
b.lp.SendNotice(evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) setMailbox(ctx context.Context, value string) {
evt := eventFromContext(ctx)
existingID, ok := b.getMapping(value)
if (ok && existingID != "" && existingID != evt.RoomID) || b.isReserved(value) {
b.lp.SendNotice(evt.RoomID, fmt.Sprintf("Mailbox `%s` (%s) already taken, kupo", value, utils.EmailsList(value, "")))
b.lp.SendNotice(ctx, evt.RoomID, fmt.Sprintf("Mailbox `%s` (%s) already taken, kupo", value, utils.EmailsList(value, "")))
return
}
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve settings: %v", err)
return
@@ -113,23 +113,23 @@ func (b *Bot) setMailbox(ctx context.Context, value string) {
if old != "" {
b.rooms.Delete(old)
}
active := b.ActivateMailbox(evt.Sender, evt.RoomID, value)
active := b.ActivateMailbox(ctx, evt.Sender, evt.RoomID, value)
cfg.Set(config.RoomActive, strconv.FormatBool(active))
value = fmt.Sprintf("%s@%s", value, utils.SanitizeDomain(cfg.Domain()))
err = b.cfg.SetRoom(evt.RoomID, cfg)
err = b.cfg.SetRoom(ctx, evt.RoomID, cfg)
if err != nil {
b.Error(ctx, "cannot update settings: %v", err)
return
}
msg := fmt.Sprintf("mailbox of this room set to `%s`", value)
b.lp.SendNotice(evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) setPassword(ctx context.Context) {
evt := eventFromContext(ctx)
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve settings: %v", err)
return
@@ -143,13 +143,13 @@ func (b *Bot) setPassword(ctx context.Context) {
}
cfg.Set(config.RoomPassword, value)
err = b.cfg.SetRoom(evt.RoomID, cfg)
err = b.cfg.SetRoom(ctx, evt.RoomID, cfg)
if err != nil {
b.Error(ctx, "cannot update settings: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "SMTP password has been set", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "SMTP password has been set", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) setOption(ctx context.Context, name, value string) {
@@ -159,7 +159,7 @@ func (b *Bot) setOption(ctx context.Context, name, value string) {
}
evt := eventFromContext(ctx)
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "failed to retrieve settings: %v", err)
return
@@ -176,19 +176,19 @@ func (b *Bot) setOption(ctx context.Context, name, value string) {
old := cfg.Get(name)
if old == value {
b.lp.SendNotice(evt.RoomID, "nothing changed, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "nothing changed, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return
}
cfg.Set(name, value)
err = b.cfg.SetRoom(evt.RoomID, cfg)
err = b.cfg.SetRoom(ctx, evt.RoomID, cfg)
if err != nil {
b.Error(ctx, "cannot update settings: %v", err)
return
}
msg := fmt.Sprintf("`%s` of this room set to:\n```\n%s\n```", name, value)
b.lp.SendNotice(evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, msg, linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) runSpamlistAdd(ctx context.Context, commandSlice []string) {
@@ -197,7 +197,7 @@ func (b *Bot) runSpamlistAdd(ctx context.Context, commandSlice []string) {
b.getOption(ctx, config.RoomSpamlist)
return
}
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "cannot get room settings: %v", err)
return
@@ -212,7 +212,7 @@ func (b *Bot) runSpamlistAdd(ctx context.Context, commandSlice []string) {
}
cfg.Set(config.RoomSpamlist, utils.SliceString(spamlist))
err = b.cfg.SetRoom(evt.RoomID, cfg)
err = b.cfg.SetRoom(ctx, evt.RoomID, cfg)
if err != nil {
b.Error(ctx, "cannot store room settings: %v", err)
return
@@ -223,7 +223,7 @@ func (b *Bot) runSpamlistAdd(ctx context.Context, commandSlice []string) {
threadID = evt.ID
}
b.lp.SendNotice(evt.RoomID, "spamlist has been updated, kupo", linkpearl.RelatesTo(threadID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "spamlist has been updated, kupo", linkpearl.RelatesTo(threadID, cfg.NoThreads()))
}
func (b *Bot) runSpamlistRemove(ctx context.Context, commandSlice []string) {
@@ -232,7 +232,7 @@ func (b *Bot) runSpamlistRemove(ctx context.Context, commandSlice []string) {
b.getOption(ctx, config.RoomSpamlist)
return
}
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "cannot get room settings: %v", err)
return
@@ -248,7 +248,7 @@ func (b *Bot) runSpamlistRemove(ctx context.Context, commandSlice []string) {
toRemove[idx] = struct{}{}
}
if len(toRemove) == 0 {
b.lp.SendNotice(evt.RoomID, "nothing new, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "nothing new, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return
}
@@ -261,34 +261,34 @@ func (b *Bot) runSpamlistRemove(ctx context.Context, commandSlice []string) {
}
cfg.Set(config.RoomSpamlist, utils.SliceString(updatedSpamlist))
err = b.cfg.SetRoom(evt.RoomID, cfg)
err = b.cfg.SetRoom(ctx, evt.RoomID, cfg)
if err != nil {
b.Error(ctx, "cannot store room settings: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "spamlist has been updated, kupo", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "spamlist has been updated, kupo", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}
func (b *Bot) runSpamlistReset(ctx context.Context) {
evt := eventFromContext(ctx)
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "cannot get room settings: %v", err)
return
}
spamlist := utils.StringSlice(cfg[config.RoomSpamlist])
if len(spamlist) == 0 {
b.lp.SendNotice(evt.RoomID, "spamlist is empty, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "spamlist is empty, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
return
}
cfg.Set(config.RoomSpamlist, "")
err = b.cfg.SetRoom(evt.RoomID, cfg)
err = b.cfg.SetRoom(ctx, evt.RoomID, cfg)
if err != nil {
b.Error(ctx, "cannot store room settings: %v", err)
return
}
b.lp.SendNotice(evt.RoomID, "spamlist has been reset, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "spamlist has been reset, kupo.", linkpearl.RelatesTo(evt.ID, cfg.NoThreads()))
}

View File

@@ -1,6 +1,8 @@
package config
import (
"context"
"github.com/rs/zerolog"
"gitlab.com/etke.cc/linkpearl"
"maunium.net/go/mautrix/id"
@@ -27,10 +29,10 @@ func New(lp *linkpearl.Linkpearl, log *zerolog.Logger) *Manager {
}
// GetBot config
func (m *Manager) GetBot() Bot {
func (m *Manager) GetBot(ctx context.Context) Bot {
var err error
var config Bot
config, err = m.lp.GetAccountData(acBotKey)
config, err = m.lp.GetAccountData(ctx, acBotKey)
if err != nil {
m.log.Error().Err(err).Msg("cannot get bot settings")
}
@@ -43,13 +45,13 @@ func (m *Manager) GetBot() Bot {
}
// SetBot config
func (m *Manager) SetBot(cfg Bot) error {
return m.lp.SetAccountData(acBotKey, cfg)
func (m *Manager) SetBot(ctx context.Context, cfg Bot) error {
return m.lp.SetAccountData(ctx, acBotKey, cfg)
}
// GetRoom config
func (m *Manager) GetRoom(roomID id.RoomID) (Room, error) {
config, err := m.lp.GetRoomAccountData(roomID, acRoomKey)
func (m *Manager) GetRoom(ctx context.Context, roomID id.RoomID) (Room, error) {
config, err := m.lp.GetRoomAccountData(ctx, roomID, acRoomKey)
if err != nil {
m.log.Warn().Err(err).Str("room_id", roomID.String()).Msg("cannot get room settings")
}
@@ -61,19 +63,19 @@ func (m *Manager) GetRoom(roomID id.RoomID) (Room, error) {
}
// SetRoom config
func (m *Manager) SetRoom(roomID id.RoomID, cfg Room) error {
return m.lp.SetRoomAccountData(roomID, acRoomKey, cfg)
func (m *Manager) SetRoom(ctx context.Context, roomID id.RoomID, cfg Room) error {
return m.lp.SetRoomAccountData(ctx, roomID, acRoomKey, cfg)
}
// GetBanlist config
func (m *Manager) GetBanlist() List {
if !m.GetBot().BanlistEnabled() {
func (m *Manager) GetBanlist(ctx context.Context) List {
if !m.GetBot(ctx).BanlistEnabled() {
return make(List, 0)
}
m.mu.Lock("banlist")
defer m.mu.Unlock("banlist")
config, err := m.lp.GetAccountData(acBanlistKey)
config, err := m.lp.GetAccountData(ctx, acBanlistKey)
if err != nil {
m.log.Error().Err(err).Msg("cannot get banlist")
}
@@ -85,8 +87,8 @@ func (m *Manager) GetBanlist() List {
}
// SetBanlist config
func (m *Manager) SetBanlist(cfg List) error {
if !m.GetBot().BanlistEnabled() {
func (m *Manager) SetBanlist(ctx context.Context, cfg List) error {
if !m.GetBot(ctx).BanlistEnabled() {
return nil
}
@@ -96,12 +98,12 @@ func (m *Manager) SetBanlist(cfg List) error {
cfg = make(List, 0)
}
return m.lp.SetAccountData(acBanlistKey, cfg)
return m.lp.SetAccountData(ctx, acBanlistKey, cfg)
}
// GetGreylist config
func (m *Manager) GetGreylist() List {
config, err := m.lp.GetAccountData(acGreylistKey)
func (m *Manager) GetGreylist(ctx context.Context) List {
config, err := m.lp.GetAccountData(ctx, acGreylistKey)
if err != nil {
m.log.Error().Err(err).Msg("cannot get banlist")
}
@@ -114,6 +116,6 @@ func (m *Manager) GetGreylist() List {
}
// SetGreylist config
func (m *Manager) SetGreylist(cfg List) error {
return m.lp.SetAccountData(acGreylistKey, cfg)
func (m *Manager) SetGreylist(ctx context.Context, cfg List) error {
return m.lp.SetAccountData(ctx, acGreylistKey, cfg)
}

View File

@@ -15,8 +15,10 @@ const (
ctxThreadID ctxkey = iota
)
func newContext(evt *event.Event) context.Context {
ctx := context.Background()
func newContext(ctx context.Context, evt *event.Event) context.Context {
if ctx == nil {
ctx = context.Background()
}
hub := sentry.CurrentHub().Clone()
ctx = sentry.SetHubOnContext(ctx, hub)
ctx = eventToContext(ctx, evt)

View File

@@ -1,6 +1,7 @@
package bot
import (
"context"
"strconv"
"time"
@@ -9,21 +10,21 @@ import (
"gitlab.com/etke.cc/postmoogle/bot/config"
)
func (b *Bot) syncRooms() error {
func (b *Bot) syncRooms(ctx context.Context) error {
adminRooms := []id.RoomID{}
adminRoom := b.cfg.GetBot().AdminRoom()
adminRoom := b.cfg.GetBot(ctx).AdminRoom()
if adminRoom != "" {
adminRooms = append(adminRooms, adminRoom)
}
resp, err := b.lp.GetClient().JoinedRooms()
resp, err := b.lp.GetClient().JoinedRooms(ctx)
if err != nil {
return err
}
for _, roomID := range resp.JoinedRooms {
b.migrateRoomSettings(roomID)
cfg, serr := b.cfg.GetRoom(roomID)
b.migrateRoomSettings(ctx, roomID)
cfg, serr := b.cfg.GetRoom(ctx, roomID)
if serr != nil {
continue
}
@@ -33,7 +34,7 @@ func (b *Bot) syncRooms() error {
b.rooms.Store(mailbox, roomID)
}
if cfg.Owner() != "" && b.allowAdmin(id.UserID(cfg.Owner()), "") {
if cfg.Owner() != "" && b.allowAdmin(ctx, id.UserID(cfg.Owner()), "") {
adminRooms = append(adminRooms, roomID)
}
}
@@ -42,8 +43,8 @@ func (b *Bot) syncRooms() error {
return nil
}
func (b *Bot) migrateRoomSettings(roomID id.RoomID) {
cfg, err := b.cfg.GetRoom(roomID)
func (b *Bot) migrateRoomSettings(ctx context.Context, roomID id.RoomID) {
cfg, err := b.cfg.GetRoom(ctx, roomID)
if err != nil {
b.log.Error().Err(err).Msg("cannot retrieve room settings")
return
@@ -56,7 +57,7 @@ func (b *Bot) migrateRoomSettings(roomID id.RoomID) {
return
}
cfg.MigrateSpamlistSettings()
err = b.cfg.SetRoom(roomID, cfg)
err = b.cfg.SetRoom(ctx, roomID, cfg)
if err != nil {
b.log.Error().Err(err).Msg("cannot migrate room settings")
}
@@ -68,8 +69,8 @@ func (b *Bot) migrateRoomSettings(roomID id.RoomID) {
// alongside with other database configs to simplify maintenance,
// but with that simplification there is no proper way to migrate
// existing sync token and session info. No data loss, tho.
func (b *Bot) migrateMautrix015() error {
cfg := b.cfg.GetBot()
func (b *Bot) migrateMautrix015(ctx context.Context) error {
cfg := b.cfg.GetBot(ctx)
ts := cfg.Mautrix015Migration()
// already migrated
if ts > 0 {
@@ -82,11 +83,11 @@ func (b *Bot) migrateMautrix015() error {
tss := strconv.FormatInt(ts, 10)
cfg.Set(config.BotMautrix015Migration, tss)
return b.cfg.SetBot(cfg)
return b.cfg.SetBot(ctx, cfg)
}
func (b *Bot) initBotUsers() ([]string, error) {
cfg := b.cfg.GetBot()
func (b *Bot) initBotUsers(ctx context.Context) ([]string, error) {
cfg := b.cfg.GetBot(ctx)
cfgUsers := cfg.Users()
if len(cfgUsers) > 0 {
return cfgUsers, nil
@@ -97,10 +98,10 @@ func (b *Bot) initBotUsers() ([]string, error) {
return nil, err
}
cfg.Set(config.BotUsers, "@*:"+homeserver)
return cfg.Users(), b.cfg.SetBot(cfg)
return cfg.Users(), b.cfg.SetBot(ctx, cfg)
}
// SyncRooms and mailboxes
func (b *Bot) SyncRooms() {
b.syncRooms() //nolint:errcheck // nothing can be done here
b.syncRooms(context.Background()) //nolint:errcheck // nothing can be done here
}

View File

@@ -60,14 +60,14 @@ func (b *Bot) shouldQueue(msg string) bool {
// Sendmail tries to send email immediately, but if it gets 4xx error (greylisting),
// the email will be added to the queue and retried several times after that
func (b *Bot) Sendmail(eventID id.EventID, from, to, data string) (bool, error) {
func (b *Bot) Sendmail(ctx context.Context, eventID id.EventID, from, to, data string) (bool, error) {
log := b.log.With().Str("from", from).Str("to", to).Str("eventID", eventID.String()).Logger()
log.Info().Msg("attempting to deliver email")
err := b.sendmail(from, to, data)
if err != nil {
if b.shouldQueue(err.Error()) {
log.Info().Err(err).Msg("email has been added to the queue")
return true, b.q.Add(eventID.String(), from, to, data)
return true, b.q.Add(ctx, eventID.String(), from, to, data)
}
log.Warn().Err(err).Msg("email delivery failed")
return false, err
@@ -78,8 +78,8 @@ func (b *Bot) Sendmail(eventID id.EventID, from, to, data string) (bool, error)
}
// GetDKIMprivkey returns DKIM private key
func (b *Bot) GetDKIMprivkey() string {
return b.cfg.GetBot().DKIMPrivateKey()
func (b *Bot) GetDKIMprivkey(ctx context.Context) string {
return b.cfg.GetBot(ctx).DKIMPrivateKey()
}
func (b *Bot) getMapping(mailbox string) (id.RoomID, bool) {
@@ -97,10 +97,10 @@ func (b *Bot) getMapping(mailbox string) (id.RoomID, bool) {
}
// GetMapping returns mapping of mailbox = room
func (b *Bot) GetMapping(mailbox string) (id.RoomID, bool) {
func (b *Bot) GetMapping(ctx context.Context, mailbox string) (id.RoomID, bool) {
roomID, ok := b.getMapping(mailbox)
if !ok {
catchAll := b.cfg.GetBot().CatchAll()
catchAll := b.cfg.GetBot(ctx).CatchAll()
if catchAll == "" {
return roomID, ok
}
@@ -111,8 +111,8 @@ func (b *Bot) GetMapping(mailbox string) (id.RoomID, bool) {
}
// GetIFOptions returns incoming email filtering options (room settings)
func (b *Bot) GetIFOptions(roomID id.RoomID) email.IncomingFilteringOptions {
cfg, err := b.cfg.GetRoom(roomID)
func (b *Bot) GetIFOptions(ctx context.Context, roomID id.RoomID) email.IncomingFilteringOptions {
cfg, err := b.cfg.GetRoom(ctx, roomID)
if err != nil {
b.log.Error().Err(err).Msg("cannot retrieve room settings")
}
@@ -124,11 +124,11 @@ func (b *Bot) GetIFOptions(roomID id.RoomID) email.IncomingFilteringOptions {
//
//nolint:gocognit // TODO
func (b *Bot) IncomingEmail(ctx context.Context, eml *email.Email) error {
roomID, ok := b.GetMapping(eml.Mailbox(true))
roomID, ok := b.GetMapping(ctx, eml.Mailbox(true))
if !ok {
return ErrNoRoom
}
cfg, err := b.cfg.GetRoom(roomID)
cfg, err := b.cfg.GetRoom(ctx, roomID)
if err != nil {
b.Error(ctx, "cannot get settings: %v", err)
}
@@ -139,15 +139,15 @@ func (b *Bot) IncomingEmail(ctx context.Context, eml *email.Email) error {
var threadID id.EventID
newThread := true
if eml.InReplyTo != "" || eml.References != "" {
threadID = b.getThreadID(roomID, eml.InReplyTo, eml.References)
threadID = b.getThreadID(ctx, roomID, eml.InReplyTo, eml.References)
if threadID != "" {
newThread = false
ctx = threadIDToContext(ctx, threadID)
b.setThreadID(roomID, eml.MessageID, threadID)
b.setThreadID(ctx, roomID, eml.MessageID, threadID)
}
}
content := eml.Content(threadID, cfg.ContentOptions())
eventID, serr := b.lp.Send(roomID, content)
content := eml.Content(threadID, cfg.ContentOptions(), b.psd)
eventID, serr := b.lp.Send(ctx, roomID, content)
if serr != nil {
if !strings.Contains(serr.Error(), "M_UNKNOWN") { // if it's not an unknown event error
return serr
@@ -160,11 +160,11 @@ func (b *Bot) IncomingEmail(ctx context.Context, eml *email.Email) error {
ctx = threadIDToContext(ctx, threadID)
}
b.setThreadID(roomID, eml.MessageID, threadID)
b.setLastEventID(roomID, threadID, eventID)
b.setThreadID(ctx, roomID, eml.MessageID, threadID)
b.setLastEventID(ctx, roomID, threadID, eventID)
if newThread && cfg.Threadify() {
_, berr := b.lp.Send(roomID, eml.ContentBody(threadID, cfg.ContentOptions()))
_, berr := b.lp.Send(ctx, roomID, eml.ContentBody(threadID, cfg.ContentOptions()))
if berr != nil {
return berr
}
@@ -179,15 +179,15 @@ func (b *Bot) IncomingEmail(ctx context.Context, eml *email.Email) error {
}
if newThread && cfg.Autoreply() != "" {
b.sendAutoreply(roomID, threadID)
b.sendAutoreply(ctx, roomID, threadID)
}
return nil
}
//nolint:gocognit // TODO
func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
cfg, err := b.cfg.GetRoom(roomID)
func (b *Bot) sendAutoreply(ctx context.Context, roomID id.RoomID, threadID id.EventID) {
cfg, err := b.cfg.GetRoom(ctx, roomID)
if err != nil {
return
}
@@ -197,7 +197,7 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
return
}
threadEvt, err := b.lp.GetClient().GetEvent(roomID, threadID)
threadEvt, err := b.lp.GetClient().GetEvent(ctx, roomID, threadID)
if err != nil {
b.log.Error().Err(err).Msg("cannot get thread event for autoreply")
return
@@ -216,7 +216,7 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
},
}
meta := b.getParentEmail(evt, cfg.Mailbox())
meta := b.getParentEmail(ctx, evt, cfg.Mailbox())
if meta.To == "" {
return
@@ -246,16 +246,16 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
meta.References = meta.References + " " + meta.MessageID
b.log.Info().Any("meta", meta).Msg("sending automatic reply")
eml := email.New(meta.MessageID, meta.InReplyTo, meta.References, meta.Subject, meta.From, meta.To, meta.RcptTo, meta.CC, body, htmlBody, nil, nil)
data := eml.Compose(b.cfg.GetBot().DKIMPrivateKey())
data := eml.Compose(b.cfg.GetBot(ctx).DKIMPrivateKey())
if data == "" {
return
}
var queued bool
ctx := newContext(threadEvt)
ctx = newContext(ctx, threadEvt)
recipients := meta.Recipients
for _, to := range recipients {
queued, err = b.Sendmail(evt.ID, meta.From, to, data)
queued, err = b.Sendmail(ctx, evt.ID, meta.From, to, data)
if queued {
b.log.Info().Err(err).Str("from", meta.From).Str("to", to).Msg("email has been queued")
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent to "+to+" (queued)")
@@ -273,7 +273,7 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
func (b *Bot) canReply(ctx context.Context) bool {
evt := eventFromContext(ctx)
return b.allowSend(evt.Sender, evt.RoomID) && b.allowReply(evt.Sender, evt.RoomID)
return b.allowSend(ctx, evt.Sender, evt.RoomID) && b.allowReply(ctx, evt.Sender, evt.RoomID)
}
// SendEmailReply sends replies from matrix thread to email thread
@@ -284,7 +284,7 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
if !b.canReply(ctx) {
return
}
cfg, err := b.cfg.GetRoom(evt.RoomID)
cfg, err := b.cfg.GetRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "cannot retrieve room settings: %v", err)
return
@@ -295,10 +295,10 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
return
}
b.lock(evt.RoomID, evt.ID)
defer b.unlock(evt.RoomID, evt.ID)
b.lock(ctx, evt.RoomID, evt.ID)
defer b.unlock(ctx, evt.RoomID, evt.ID)
meta := b.getParentEmail(evt, mailbox)
meta := b.getParentEmail(ctx, evt, mailbox)
if meta.To == "" {
b.Error(ctx, "cannot find parent email and continue the thread. Please, start a new email thread")
@@ -306,7 +306,7 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
}
if meta.ThreadID == "" {
meta.ThreadID = b.getThreadID(evt.RoomID, meta.InReplyTo, meta.References)
meta.ThreadID = b.getThreadID(ctx, evt.RoomID, meta.InReplyTo, meta.References)
ctx = threadIDToContext(ctx, meta.ThreadID)
}
content := evt.Content.AsMessage()
@@ -330,16 +330,16 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
meta.References = meta.References + " " + meta.MessageID
b.log.Info().Any("meta", meta).Msg("sending email reply")
eml := email.New(meta.MessageID, meta.InReplyTo, meta.References, meta.Subject, meta.From, meta.To, meta.RcptTo, meta.CC, body, htmlBody, nil, nil)
data := eml.Compose(b.cfg.GetBot().DKIMPrivateKey())
data := eml.Compose(b.cfg.GetBot(ctx).DKIMPrivateKey())
if data == "" {
b.lp.SendNotice(evt.RoomID, "email body is empty", linkpearl.RelatesTo(meta.ThreadID, cfg.NoThreads()))
b.lp.SendNotice(ctx, evt.RoomID, "email body is empty", linkpearl.RelatesTo(meta.ThreadID, cfg.NoThreads()))
return
}
var queued bool
recipients := meta.Recipients
for _, to := range recipients {
queued, err = b.Sendmail(evt.ID, meta.From, to, data)
queued, err = b.Sendmail(ctx, evt.ID, meta.From, to, data)
if queued {
b.log.Info().Err(err).Str("from", meta.From).Str("to", to).Msg("email has been queued")
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg)
@@ -444,7 +444,7 @@ func (e *parentEmail) calculateRecipients(from string, forwardedFrom []string) {
e.Recipients = rcpts
}
func (b *Bot) getParentEvent(evt *event.Event) (id.EventID, *event.Event) {
func (b *Bot) getParentEvent(ctx context.Context, evt *event.Event) (id.EventID, *event.Event) {
content := evt.Content.AsMessage()
threadID := linkpearl.EventParent(evt.ID, content)
b.log.Debug().Str("eventID", evt.ID.String()).Str("threadID", threadID.String()).Msg("looking up for the parent event within thread")
@@ -452,23 +452,23 @@ func (b *Bot) getParentEvent(evt *event.Event) (id.EventID, *event.Event) {
b.log.Debug().Str("eventID", evt.ID.String()).Msg("event is the thread itself")
return threadID, evt
}
lastEventID := b.getLastEventID(evt.RoomID, threadID)
lastEventID := b.getLastEventID(ctx, evt.RoomID, threadID)
b.log.Debug().Str("eventID", evt.ID.String()).Str("threadID", threadID.String()).Str("lastEventID", lastEventID.String()).Msg("the last event of the thread (and parent of the event) has been found")
if lastEventID == evt.ID {
return threadID, evt
}
parentEvt, err := b.lp.GetClient().GetEvent(evt.RoomID, lastEventID)
parentEvt, err := b.lp.GetClient().GetEvent(ctx, evt.RoomID, lastEventID)
if err != nil {
b.log.Error().Err(err).Msg("cannot get parent event")
return threadID, nil
}
linkpearl.ParseContent(parentEvt, b.log)
if !b.lp.GetMachine().StateStore.IsEncrypted(evt.RoomID) {
if ok, _ := b.lp.GetMachine().StateStore.IsEncrypted(ctx, evt.RoomID); !ok { //nolint:errcheck // that's fine
return threadID, parentEvt
}
decrypted, err := b.lp.GetClient().Crypto.Decrypt(parentEvt)
decrypted, err := b.lp.GetClient().Crypto.Decrypt(ctx, parentEvt)
if err != nil {
b.log.Error().Err(err).Msg("cannot decrypt parent event")
return threadID, nil
@@ -477,9 +477,9 @@ func (b *Bot) getParentEvent(evt *event.Event) (id.EventID, *event.Event) {
return threadID, decrypted
}
func (b *Bot) getParentEmail(evt *event.Event, newFromMailbox string) *parentEmail {
func (b *Bot) getParentEmail(ctx context.Context, evt *event.Event, newFromMailbox string) *parentEmail {
parent := &parentEmail{}
threadID, parentEvt := b.getParentEvent(evt)
threadID, parentEvt := b.getParentEvent(ctx, evt)
parent.ThreadID = threadID
if parentEvt == nil {
return parent
@@ -527,7 +527,7 @@ func (b *Bot) saveSentMetadata(ctx context.Context, queued bool, threadID id.Eve
}
evt := eventFromContext(ctx)
content := eml.Content(threadID, cfg.ContentOptions())
content := eml.Content(threadID, cfg.ContentOptions(), b.psd)
notice := format.RenderMarkdown(text, true, true)
msgContent, ok := content.Parsed.(*event.MessageEventContent)
if !ok {
@@ -539,28 +539,28 @@ func (b *Bot) saveSentMetadata(ctx context.Context, queued bool, threadID id.Eve
msgContent.FormattedBody = notice.FormattedBody
msgContent.RelatesTo = linkpearl.RelatesTo(threadID, cfg.NoThreads())
content.Parsed = msgContent
msgID, err := b.lp.Send(evt.RoomID, content)
msgID, err := b.lp.Send(ctx, evt.RoomID, content)
if err != nil {
b.Error(ctx, "cannot send notice: %v", err)
return
}
domain := utils.SanitizeDomain(cfg.Domain())
b.setThreadID(evt.RoomID, email.MessageID(evt.ID, domain), threadID)
b.setThreadID(evt.RoomID, email.MessageID(msgID, domain), threadID)
b.setLastEventID(evt.RoomID, threadID, msgID)
b.setThreadID(ctx, evt.RoomID, email.MessageID(evt.ID, domain), threadID)
b.setThreadID(ctx, evt.RoomID, email.MessageID(msgID, domain), threadID)
b.setLastEventID(ctx, evt.RoomID, threadID, msgID)
}
func (b *Bot) sendFiles(ctx context.Context, roomID id.RoomID, files []*utils.File, noThreads bool, parentID id.EventID) {
for _, file := range files {
req := file.Convert()
err := b.lp.SendFile(roomID, req, file.MsgType, linkpearl.RelatesTo(parentID, noThreads))
err := b.lp.SendFile(ctx, roomID, req, file.MsgType, linkpearl.RelatesTo(parentID, noThreads))
if err != nil {
b.Error(ctx, "cannot upload file %s: %v", req.FileName, err)
}
}
}
func (b *Bot) getThreadID(roomID id.RoomID, messageID, references string) id.EventID {
func (b *Bot) getThreadID(ctx context.Context, roomID id.RoomID, messageID, references string) id.EventID {
refs := []string{messageID}
if references != "" {
refs = append(refs, strings.Split(references, " ")...)
@@ -568,7 +568,7 @@ func (b *Bot) getThreadID(roomID id.RoomID, messageID, references string) id.Eve
for _, refID := range refs {
key := acMessagePrefix + "." + refID
data, err := b.lp.GetRoomAccountData(roomID, key)
data, err := b.lp.GetRoomAccountData(ctx, roomID, key)
if err != nil {
b.log.Error().Err(err).Str("key", key).Msg("cannot retrieve thread ID")
continue
@@ -576,7 +576,7 @@ func (b *Bot) getThreadID(roomID id.RoomID, messageID, references string) id.Eve
if data["eventID"] == "" {
continue
}
resp, err := b.lp.GetClient().GetEvent(roomID, id.EventID(data["eventID"]))
resp, err := b.lp.GetClient().GetEvent(ctx, roomID, id.EventID(data["eventID"]))
if err != nil {
b.log.Warn().Err(err).Str("roomID", roomID.String()).Str("eventID", data["eventID"]).Msg("cannot get event by id (may be removed)")
continue
@@ -587,17 +587,17 @@ func (b *Bot) getThreadID(roomID id.RoomID, messageID, references string) id.Eve
return ""
}
func (b *Bot) setThreadID(roomID id.RoomID, messageID string, eventID id.EventID) {
func (b *Bot) setThreadID(ctx context.Context, roomID id.RoomID, messageID string, eventID id.EventID) {
key := acMessagePrefix + "." + messageID
err := b.lp.SetRoomAccountData(roomID, key, map[string]string{"eventID": eventID.String()})
err := b.lp.SetRoomAccountData(ctx, roomID, key, map[string]string{"eventID": eventID.String()})
if err != nil {
b.log.Error().Err(err).Str("key", key).Msg("cannot save thread ID")
}
}
func (b *Bot) getLastEventID(roomID id.RoomID, threadID id.EventID) id.EventID {
func (b *Bot) getLastEventID(ctx context.Context, roomID id.RoomID, threadID id.EventID) id.EventID {
key := acLastEventPrefix + "." + threadID.String()
data, err := b.lp.GetRoomAccountData(roomID, key)
data, err := b.lp.GetRoomAccountData(ctx, roomID, key)
if err != nil {
b.log.Error().Err(err).Str("key", key).Msg("cannot retrieve last event ID")
return threadID
@@ -609,9 +609,9 @@ func (b *Bot) getLastEventID(roomID id.RoomID, threadID id.EventID) id.EventID {
return threadID
}
func (b *Bot) setLastEventID(roomID id.RoomID, threadID, eventID id.EventID) {
func (b *Bot) setLastEventID(ctx context.Context, roomID id.RoomID, threadID, eventID id.EventID) {
key := acLastEventPrefix + "." + threadID.String()
err := b.lp.SetRoomAccountData(roomID, key, map[string]string{"eventID": eventID.String()})
err := b.lp.SetRoomAccountData(ctx, roomID, key, map[string]string{"eventID": eventID.String()})
if err != nil {
b.log.Error().Err(err).Str("key", key).Msg("cannot save thread ID")
}

View File

@@ -1,29 +1,31 @@
package bot
import (
"context"
"maunium.net/go/mautrix/id"
)
func (b *Bot) lock(roomID id.RoomID, optionalEventID ...id.EventID) {
func (b *Bot) lock(ctx context.Context, roomID id.RoomID, optionalEventID ...id.EventID) {
b.mu.Lock(roomID.String())
if len(optionalEventID) == 0 {
return
}
evtID := optionalEventID[0]
if _, err := b.lp.GetClient().SendReaction(roomID, evtID, "📨"); err != nil {
if _, err := b.lp.GetClient().SendReaction(ctx, roomID, evtID, "📨"); err != nil {
b.log.Error().Err(err).Str("roomID", roomID.String()).Str("eventID", evtID.String()).Msg("cannot send reaction on lock")
}
}
func (b *Bot) unlock(roomID id.RoomID, optionalEventID ...id.EventID) {
func (b *Bot) unlock(ctx context.Context, roomID id.RoomID, optionalEventID ...id.EventID) {
b.mu.Unlock(roomID.String())
if len(optionalEventID) == 0 {
return
}
evtID := optionalEventID[0]
if _, err := b.lp.GetClient().SendReaction(roomID, evtID, "✅"); err != nil {
if _, err := b.lp.GetClient().SendReaction(ctx, roomID, evtID, "✅"); err != nil {
b.log.Error().Err(err).Str("roomID", roomID.String()).Str("eventID", evtID.String()).Msg("cannot send reaction on unlock")
}
}

View File

@@ -1,6 +1,8 @@
package queue
import (
"context"
"github.com/rs/zerolog"
"gitlab.com/etke.cc/linkpearl"
@@ -41,7 +43,8 @@ func (q *Queue) SetSendmail(function func(string, string, string) error) {
// Process queue
func (q *Queue) Process() {
q.log.Debug().Msg("staring queue processing...")
cfg := q.cfg.GetBot()
ctx := context.Background()
cfg := q.cfg.GetBot(ctx)
batchSize := cfg.QueueBatch()
if batchSize == 0 {
@@ -55,7 +58,7 @@ func (q *Queue) Process() {
q.mu.Lock(acQueueKey)
defer q.mu.Unlock(acQueueKey)
index, err := q.lp.GetAccountData(acQueueKey)
index, err := q.lp.GetAccountData(ctx, acQueueKey)
if err != nil {
q.log.Error().Err(err).Msg("cannot get queue index")
}
@@ -66,9 +69,9 @@ func (q *Queue) Process() {
q.log.Debug().Msg("finished re-deliveries from queue")
return
}
if dequeue := q.try(itemkey, maxRetries); dequeue {
if dequeue := q.try(ctx, itemkey, maxRetries); dequeue {
q.log.Info().Str("id", id).Msg("email has been delivered")
err = q.Remove(id)
err = q.Remove(ctx, id)
if err != nil {
q.log.Error().Err(err).Str("id", id).Msg("cannot dequeue email")
}

View File

@@ -1,11 +1,12 @@
package queue
import (
"context"
"strconv"
)
// Add to queue
func (q *Queue) Add(id, from, to, data string) error {
func (q *Queue) Add(ctx context.Context, id, from, to, data string) error {
itemkey := acQueueKey + "." + id
item := map[string]string{
"attempts": "0",
@@ -17,7 +18,7 @@ func (q *Queue) Add(id, from, to, data string) error {
q.mu.Lock(itemkey)
defer q.mu.Unlock(itemkey)
err := q.lp.SetAccountData(itemkey, item)
err := q.lp.SetAccountData(ctx, itemkey, item)
if err != nil {
q.log.Error().Err(err).Str("id", id).Msg("cannot enqueue email")
return err
@@ -25,13 +26,13 @@ func (q *Queue) Add(id, from, to, data string) error {
q.mu.Lock(acQueueKey)
defer q.mu.Unlock(acQueueKey)
queueIndex, err := q.lp.GetAccountData(acQueueKey)
queueIndex, err := q.lp.GetAccountData(ctx, acQueueKey)
if err != nil {
q.log.Error().Err(err).Msg("cannot get queue index")
return err
}
queueIndex[id] = itemkey
err = q.lp.SetAccountData(acQueueKey, queueIndex)
err = q.lp.SetAccountData(ctx, acQueueKey, queueIndex)
if err != nil {
q.log.Error().Err(err).Msg("cannot save queue index")
return err
@@ -41,8 +42,8 @@ func (q *Queue) Add(id, from, to, data string) error {
}
// Remove from queue
func (q *Queue) Remove(id string) error {
index, err := q.lp.GetAccountData(acQueueKey)
func (q *Queue) Remove(ctx context.Context, id string) error {
index, err := q.lp.GetAccountData(ctx, acQueueKey)
if err != nil {
q.log.Error().Err(err).Msg("cannot get queue index")
return err
@@ -52,7 +53,7 @@ func (q *Queue) Remove(id string) error {
itemkey = acQueueKey + "." + id
}
delete(index, id)
err = q.lp.SetAccountData(acQueueKey, index)
err = q.lp.SetAccountData(ctx, acQueueKey, index)
if err != nil {
q.log.Error().Err(err).Msg("cannot update queue index")
return err
@@ -60,15 +61,15 @@ func (q *Queue) Remove(id string) error {
q.mu.Lock(itemkey)
defer q.mu.Unlock(itemkey)
return q.lp.SetAccountData(itemkey, map[string]string{})
return q.lp.SetAccountData(ctx, itemkey, map[string]string{})
}
// try to send email
func (q *Queue) try(itemkey string, maxRetries int) bool {
func (q *Queue) try(ctx context.Context, itemkey string, maxRetries int) bool {
q.mu.Lock(itemkey)
defer q.mu.Unlock(itemkey)
item, err := q.lp.GetAccountData(itemkey)
item, err := q.lp.GetAccountData(ctx, itemkey)
if err != nil {
q.log.Error().Err(err).Str("id", itemkey).Msg("cannot retrieve a queue item")
return false
@@ -92,7 +93,7 @@ func (q *Queue) try(itemkey string, maxRetries int) bool {
q.log.Info().Str("id", itemkey).Str("from", item["from"]).Str("to", item["to"]).Err(err).Msg("attempted to deliver email, but it's not ready yet")
attempts++
item["attempts"] = strconv.Itoa(attempts)
err = q.lp.SetAccountData(itemkey, item)
err = q.lp.SetAccountData(ctx, itemkey, item)
if err != nil {
q.log.Error().Err(err).Str("id", itemkey).Msg("cannot update attempt count on email")
}

View File

@@ -22,14 +22,14 @@ func (b *Bot) handleReaction(ctx context.Context) {
}
srcID := content.GetRelatesTo().EventID
srcEvt, err := b.lp.GetClient().GetEvent(evt.RoomID, srcID)
srcEvt, err := b.lp.GetClient().GetEvent(ctx, evt.RoomID, srcID)
if err != nil {
b.Error(ctx, "cannot find event %s: %v", srcID, err)
return
}
linkpearl.ParseContent(srcEvt, b.log)
if b.lp.GetMachine().StateStore.IsEncrypted(evt.RoomID) {
decrypted, derr := b.lp.GetClient().Crypto.Decrypt(srcEvt)
if ok, _ := b.lp.GetMachine().StateStore.IsEncrypted(ctx, evt.RoomID); ok { //nolint:errcheck // that's ok
decrypted, derr := b.lp.GetClient().Crypto.Decrypt(ctx, srcEvt)
if derr == nil {
srcEvt = decrypted
}

View File

@@ -3,7 +3,6 @@ package bot
import (
"context"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
)
@@ -12,27 +11,27 @@ func (b *Bot) initSync() {
b.lp.OnEventType(
event.StateMember,
func(_ mautrix.EventSource, evt *event.Event) {
go b.onMembership(evt)
func(ctx context.Context, evt *event.Event) {
go b.onMembership(ctx, evt)
},
)
b.lp.OnEventType(
event.EventMessage,
func(_ mautrix.EventSource, evt *event.Event) {
go b.onMessage(evt)
func(ctx context.Context, evt *event.Event) {
go b.onMessage(ctx, evt)
},
)
b.lp.OnEventType(
event.EventReaction,
func(_ mautrix.EventSource, evt *event.Event) {
go b.onReaction(evt)
func(ctx context.Context, evt *event.Event) {
go b.onReaction(ctx, evt)
},
)
}
// joinPermit is called by linkpearl when processing "invite" events and deciding if rooms should be auto-joined or not
func (b *Bot) joinPermit(evt *event.Event) bool {
if !b.allowUsers(evt.Sender, evt.RoomID) {
func (b *Bot) joinPermit(ctx context.Context, evt *event.Event) bool {
if !b.allowUsers(ctx, evt.Sender, evt.RoomID) {
b.log.Debug().Str("userID", evt.Sender.String()).Msg("Rejecting room invitation from unallowed user")
return false
}
@@ -40,13 +39,13 @@ func (b *Bot) joinPermit(evt *event.Event) bool {
return true
}
func (b *Bot) onMembership(evt *event.Event) {
func (b *Bot) onMembership(ctx context.Context, evt *event.Event) {
// mautrix 0.15.x migration
if b.ignoreBefore >= evt.Timestamp {
return
}
ctx := newContext(evt)
ctx = newContext(ctx, evt)
evtType := evt.Content.AsMember().Membership
if evtType == event.MembershipJoin && evt.Sender == b.lp.GetClient().UserID {
@@ -61,7 +60,7 @@ func (b *Bot) onMembership(evt *event.Event) {
// Potentially handle other membership events in the future
}
func (b *Bot) onMessage(evt *event.Event) {
func (b *Bot) onMessage(ctx context.Context, evt *event.Event) {
// ignore own messages
if evt.Sender == b.lp.GetClient().UserID {
return
@@ -71,11 +70,11 @@ func (b *Bot) onMessage(evt *event.Event) {
return
}
ctx := newContext(evt)
ctx = newContext(ctx, evt)
b.handle(ctx)
}
func (b *Bot) onReaction(evt *event.Event) {
func (b *Bot) onReaction(ctx context.Context, evt *event.Event) {
// ignore own messages
if evt.Sender == b.lp.GetClient().UserID {
return
@@ -85,7 +84,7 @@ func (b *Bot) onReaction(evt *event.Event) {
return
}
ctx := newContext(evt)
ctx = newContext(ctx, evt)
b.handleReaction(ctx)
}
@@ -100,7 +99,7 @@ func (b *Bot) onBotJoin(ctx context.Context) {
return
}
b.sendIntroduction(evt.RoomID)
b.sendIntroduction(ctx, evt.RoomID)
b.sendHelp(ctx)
}
@@ -111,7 +110,7 @@ func (b *Bot) onLeave(ctx context.Context) {
b.log.Info().Str("eventID", evt.ID.String()).Msg("Suppressing already handled event")
return
}
members, err := b.lp.GetClient().StateStore.GetRoomJoinedOrInvitedMembers(evt.RoomID)
members, err := b.lp.GetClient().StateStore.GetRoomJoinedOrInvitedMembers(ctx, evt.RoomID)
if err != nil {
b.log.Error().Err(err).Str("roomID", evt.RoomID.String()).Msg("cannot get joined or invited members")
return
@@ -121,7 +120,7 @@ func (b *Bot) onLeave(ctx context.Context) {
if count == 1 && members[0] == b.lp.GetClient().UserID {
b.log.Info().Str("roomID", evt.RoomID.String()).Msg("no more users left in the room")
b.runStop(ctx)
_, err := b.lp.GetClient().LeaveRoom(evt.RoomID)
_, err := b.lp.GetClient().LeaveRoom(ctx, evt.RoomID)
if err != nil {
b.Error(ctx, "cannot leave empty room: %v", err)
}