Files
postmoogle/bot/bot.go
Slavi Pantaleev 8ad2e29930 Add support for configuring user whitelisting
This does not do anything useful just yet.
It will be hooked to access control checks later on.

Wildcards are converted to regular expressions, because it was simpler
to do that than to write (or include) some ugly wildcard matcher library.
It also provides more flexibility, should we wish to use it later.
Regular expressions should also work well performance-wise.

We compile wildcards to regexes early on (during configuration
processing) and fail if we detect a bad pattern. This is meant to
catch various problems (typos or other mistakes) that could happen.

For this to work, configuration building had to be redone, since it can
now return an error. This may be useful in the future for validating
other configuration settings.

Related to https://gitlab.com/etke.cc/postmoogle/-/issues/1
2022-08-27 07:50:41 +03:00

104 lines
2.5 KiB
Go

package bot
import (
"context"
"fmt"
"regexp"
"sync"
"github.com/getsentry/sentry-go"
"gitlab.com/etke.cc/go/logger"
"gitlab.com/etke.cc/linkpearl"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/format"
"maunium.net/go/mautrix/id"
)
// Bot represents matrix bot
type Bot struct {
noowner bool
federation bool
prefix string
domain string
allowedUsers []*regexp.Regexp
rooms sync.Map
log *logger.Logger
lp *linkpearl.Linkpearl
handledMembershipEvents sync.Map
}
// New creates a new matrix bot
func New(lp *linkpearl.Linkpearl, log *logger.Logger, prefix, domain string, noowner, federation bool, allowedUsers []*regexp.Regexp) *Bot {
return &Bot{
noowner: noowner,
federation: federation,
prefix: prefix,
domain: domain,
allowedUsers: allowedUsers,
rooms: sync.Map{},
log: log,
lp: lp,
}
}
// Error message to the log and matrix room
func (b *Bot) Error(ctx context.Context, roomID id.RoomID, message string, args ...interface{}) {
b.log.Error(message, args...)
sentry.GetHubFromContext(ctx).CaptureException(fmt.Errorf(message, args...))
if roomID != "" {
// nolint // if something goes wrong here nobody can help...
b.lp.Send(roomID, &event.MessageEventContent{
MsgType: event.MsgNotice,
Body: "ERROR: " + fmt.Sprintf(message, args...),
})
}
}
// Notice sends a notice message to the matrix room
func (b *Bot) Notice(ctx context.Context, roomID id.RoomID, message string) {
content := format.RenderMarkdown(message, true, true)
content.MsgType = event.MsgNotice
_, err := b.lp.Send(roomID, &content)
if err != nil {
sentry.GetHubFromContext(ctx).CaptureException(err)
}
}
// Start performs matrix /sync
func (b *Bot) Start(statusMsg string) error {
if err := b.migrate(); err != nil {
return err
}
if err := b.syncRooms(); err != nil {
return err
}
b.initSync()
b.log.Info("Postmoogle has been started")
return b.lp.Start(statusMsg)
}
// GetMappings returns mapping of mailbox = room
func (b *Bot) GetMapping(mailbox string) (id.RoomID, bool) {
v, ok := b.rooms.Load(mailbox)
if !ok {
return "", ok
}
roomID, ok := v.(id.RoomID)
if !ok {
return "", ok
}
return roomID, ok
}
// Stop the bot
func (b *Bot) Stop() {
err := b.lp.GetClient().SetPresence(event.PresenceOffline)
if err != nil {
b.log.Error("cannot set presence = offline: %v", err)
}
b.lp.GetClient().StopSync()
}