diff --git a/.golangci.yml b/.golangci.yml index b48316f..16665c9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -53,7 +53,7 @@ linters-settings: sections: - standard - default - - prefix(gitlab.com/etke.cc/int/scheduler) + - prefix(gitlab.com/etke.cc/postmoogle) section-separators: - newLine linters: diff --git a/bot/bot.go b/bot/bot.go index 973fc48..6cbc4dd 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -10,10 +10,11 @@ import ( "github.com/getsentry/sentry-go" "gitlab.com/etke.cc/go/logger" "gitlab.com/etke.cc/linkpearl" - "gitlab.com/etke.cc/postmoogle/utils" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/format" "maunium.net/go/mautrix/id" + + "gitlab.com/etke.cc/postmoogle/utils" ) // Bot represents matrix bot diff --git a/bot/command.go b/bot/command.go index f03175f..7a51b35 100644 --- a/bot/command.go +++ b/bot/command.go @@ -8,14 +8,29 @@ import ( "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/format" "maunium.net/go/mautrix/id" + + "gitlab.com/etke.cc/postmoogle/utils" ) -var commands = map[string]string{ - "mailbox": "Get or set mailbox of that room", - "owner": "Get or set owner of that room", - "nosender": "Get or set `nosender` of that room (`true` - hide email sender; `false` - show email sender)", - "help": "Get help", -} +type sanitizerFunc func(string) string + +var ( + commands = map[string]string{ + // special commands + "help": "Get help", + + // options commands + "mailbox": "Get or set mailbox of that room", + "owner": "Get or set owner of that room", + "nosender": "Get or set `nosender` of that room (`true` - hide email sender; `false` - show email sender)", + } + + // sanitizers is map of option name => sanitizer function + sanitizers = map[string]sanitizerFunc{ + "mailbox": utils.Mailbox, + "nosender": utils.SanitizeBoolString, + } +) func (b *Bot) handleCommand(ctx context.Context, evt *event.Event, command []string) { if _, ok := commands[command[0]]; !ok { @@ -30,11 +45,7 @@ func (b *Bot) handleCommand(ctx context.Context, evt *event.Event, command []str switch command[0] { case "help": b.sendHelp(ctx, evt.RoomID) - case "owner": - b.handleOption(ctx, evt, command) - case "mailbox": - b.handleOption(ctx, evt, command) - case "nosender": + default: b.handleOption(ctx, evt, command) } } @@ -74,3 +85,82 @@ func (b *Bot) sendHelp(ctx context.Context, roomID id.RoomID) { b.Error(span.Context(), roomID, "cannot send message: %v", err) } } + +func (b *Bot) handleOption(ctx context.Context, evt *event.Event, command []string) { + if len(command) == 1 { + b.getOption(ctx, evt, command[0]) + return + } + b.setOption(ctx, evt, command[0], command[1]) +} + +func (b *Bot) getOption(ctx context.Context, evt *event.Event, name string) { + msg := "`%s` of this room is %s" + span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("getOption")) + defer span.Finish() + + cfg, err := b.getSettings(span.Context(), evt.RoomID) + if err != nil { + b.Error(span.Context(), evt.RoomID, "failed to retrieve settings: %v", err) + return + } + + value := cfg.Get(name) + if value == "" { + b.Notice(span.Context(), evt.RoomID, "`%s` is not set", name) + return + } + + if name == "mailbox" { + msg = msg + "@" + b.domain + } + + b.Notice(span.Context(), evt.RoomID, msg, name, value) +} + +func (b *Bot) setOption(ctx context.Context, evt *event.Event, name, value string) { + span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("setOption")) + defer span.Finish() + msg := "`%s` of this room set to %s" + + sanitizer, ok := sanitizers[name] + if ok { + value = sanitizer(value) + } + + if name == "mailbox" { + existingID, ok := b.GetMapping(ctx, value) + if ok && existingID != "" && existingID != evt.RoomID { + b.Notice(span.Context(), evt.RoomID, "Mailbox %s@%s already taken", value, b.domain) + return + } + } + + cfg, err := b.getSettings(span.Context(), evt.RoomID) + if err != nil { + b.Error(span.Context(), evt.RoomID, "failed to retrieve settings: %v", err) + return + } + + if !cfg.Allowed(b.noowner, evt.Sender) { + b.Notice(span.Context(), evt.RoomID, "you don't have permission to do that") + return + } + + cfg.Set(name, value) + if name == "mailbox" { + msg = msg + "@" + b.domain + cfg.Set("owner", evt.Sender.String()) + b.roomsmu.Lock() + b.rooms[value] = evt.RoomID + b.roomsmu.Unlock() + } + + err = b.setSettings(span.Context(), evt.RoomID, cfg) + if err != nil { + b.Error(span.Context(), evt.RoomID, "cannot update settings: %v", err) + return + } + + b.Notice(span.Context(), evt.RoomID, msg, name, value) +} diff --git a/bot/data.go b/bot/data.go index 7f92302..3b83a08 100644 --- a/bot/data.go +++ b/bot/data.go @@ -13,9 +13,10 @@ const settingskey = "cc.etke.postmoogle.settings" var migrations = []string{} +// settings of a room type settings map[string]string -// settingsStruct of a room +// settingsOld of a room type settingsOld struct { Mailbox string Owner id.UserID diff --git a/bot/options.go b/bot/options.go deleted file mode 100644 index 097546e..0000000 --- a/bot/options.go +++ /dev/null @@ -1,96 +0,0 @@ -package bot - -import ( - "context" - - "github.com/getsentry/sentry-go" - "gitlab.com/etke.cc/postmoogle/utils" - "maunium.net/go/mautrix/event" -) - -type sanitizerFunc func(string) string - -// sanitizers is map of option name => sanitizer function -var sanitizers = map[string]sanitizerFunc{ - "mailbox": utils.Mailbox, - "nosender": utils.SanitizeBoolString, -} - -func (b *Bot) handleOption(ctx context.Context, evt *event.Event, command []string) { - if len(command) == 1 { - b.getOption(ctx, evt, command[0]) - return - } - b.setOption(ctx, evt, command[0], command[1]) -} - -func (b *Bot) getOption(ctx context.Context, evt *event.Event, name string) { - msg := "`%s` of this room is %s" - span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("getOption")) - defer span.Finish() - - cfg, err := b.getSettings(span.Context(), evt.RoomID) - if err != nil { - b.Error(span.Context(), evt.RoomID, "failed to retrieve settings: %v", err) - return - } - - value := cfg.Get(name) - if value == "" { - b.Notice(span.Context(), evt.RoomID, "`%s` is not set", name) - return - } - - if name == "mailbox" { - msg = msg + "@" + b.domain - } - - b.Notice(span.Context(), evt.RoomID, msg, name, value) -} - -func (b *Bot) setOption(ctx context.Context, evt *event.Event, name, value string) { - span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("setOption")) - defer span.Finish() - msg := "`%s` of this room set to %s" - - sanitizer, ok := sanitizers[name] - if ok { - value = sanitizer(value) - } - - if name == "mailbox" { - existingID, ok := b.GetMapping(ctx, value) - if ok && existingID != "" && existingID != evt.RoomID { - b.Notice(span.Context(), evt.RoomID, "Mailbox %s@%s already taken", value, b.domain) - return - } - } - - cfg, err := b.getSettings(span.Context(), evt.RoomID) - if err != nil { - b.Error(span.Context(), evt.RoomID, "failed to retrieve settings: %v", err) - return - } - - if !cfg.Allowed(b.noowner, evt.Sender) { - b.Notice(span.Context(), evt.RoomID, "you don't have permission to do that") - return - } - - cfg.Set(name, value) - if name == "mailbox" { - msg = msg + "@" + b.domain - cfg.Set("owner", evt.Sender.String()) - b.roomsmu.Lock() - b.rooms[value] = evt.RoomID - b.roomsmu.Unlock() - } - - err = b.setSettings(span.Context(), evt.RoomID, cfg) - if err != nil { - b.Error(span.Context(), evt.RoomID, "cannot update settings: %v", err) - return - } - - b.Notice(span.Context(), evt.RoomID, msg, name, value) -} diff --git a/cmd/cmd.go b/cmd/cmd.go index 2782c8b..add9cb6 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -13,6 +13,7 @@ import ( "gitlab.com/etke.cc/go/logger" "gitlab.com/etke.cc/linkpearl" lpcfg "gitlab.com/etke.cc/linkpearl/config" + "gitlab.com/etke.cc/postmoogle/bot" "gitlab.com/etke.cc/postmoogle/config" "gitlab.com/etke.cc/postmoogle/smtp" diff --git a/smtp/session.go b/smtp/session.go index a054469..4c6a9be 100644 --- a/smtp/session.go +++ b/smtp/session.go @@ -8,6 +8,7 @@ import ( "github.com/getsentry/sentry-go" "github.com/jhillyerd/enmime" "gitlab.com/etke.cc/go/logger" + "gitlab.com/etke.cc/postmoogle/utils" ) diff --git a/smtp/smtp.go b/smtp/smtp.go index c7d44de..5c1e409 100644 --- a/smtp/smtp.go +++ b/smtp/smtp.go @@ -3,8 +3,9 @@ package smtp import ( "context" - "gitlab.com/etke.cc/postmoogle/utils" "maunium.net/go/mautrix/id" + + "gitlab.com/etke.cc/postmoogle/utils" ) // Client interface to send emails