Files
postmoogle/bot/bot.go
Slavi Pantaleev a057654962 Put command access checks on the command level
Checking using `settings.Allowed` is odd. Not all commands are related
to setting configuration settings. Admin commands are coming in the
future, for which this is certainly not the case.

We now do access checks early on (during command processing), so command
handlers can be clean of access checks. If we're inside of a command
handler, the user is privileged to run it.
2022-08-29 10:27:53 +03:00

106 lines
2.6 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
allowedAdmins []*regexp.Regexp
commands commandList
rooms sync.Map
log *logger.Logger
lp *linkpearl.Linkpearl
mu map[id.RoomID]*sync.Mutex
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,
allowedAdmins []*regexp.Regexp,
) *Bot {
b := &Bot{
noowner: noowner,
federation: federation,
prefix: prefix,
domain: domain,
allowedUsers: allowedUsers,
allowedAdmins: allowedAdmins,
rooms: sync.Map{},
log: log,
lp: lp,
mu: map[id.RoomID]*sync.Mutex{},
}
b.commands = b.buildCommandList()
return b
}
// 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)
}
// 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()
}