fix access checks; fix duplicate metadata message; better email sanitization
This commit is contained in:
@@ -22,14 +22,24 @@ func parseMXIDpatterns(patterns []string, defaultPattern string) ([]*regexp.Rege
|
||||
return mxidwc.ParsePatterns(patterns)
|
||||
}
|
||||
|
||||
func (b *Bot) allowUsers(actorID id.UserID) bool {
|
||||
if len(b.allowedUsers) != 0 {
|
||||
if !mxidwc.Match(actorID.String(), b.allowedUsers) {
|
||||
return false
|
||||
}
|
||||
func (b *Bot) allowUsers(actorID id.UserID, targetRoomID id.RoomID) bool {
|
||||
// first, check if it's an allowed user
|
||||
if mxidwc.Match(actorID.String(), b.allowedUsers) {
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
// second, check if it's an admin (admin may not fit the allowed users pattern)
|
||||
if b.allowAdmin(actorID, targetRoomID) {
|
||||
return true
|
||||
}
|
||||
|
||||
// then, check if it's the owner (same as above)
|
||||
cfg, err := b.cfg.GetRoom(targetRoomID)
|
||||
if err == nil && cfg.Owner() == actorID.String() {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Bot) allowAnyone(_ id.UserID, _ id.RoomID) bool {
|
||||
@@ -37,7 +47,7 @@ func (b *Bot) allowAnyone(_ id.UserID, _ id.RoomID) bool {
|
||||
}
|
||||
|
||||
func (b *Bot) allowOwner(actorID id.UserID, targetRoomID id.RoomID) bool {
|
||||
if !b.allowUsers(actorID) {
|
||||
if !b.allowUsers(actorID, targetRoomID) {
|
||||
return false
|
||||
}
|
||||
cfg, err := b.cfg.GetRoom(targetRoomID)
|
||||
@@ -59,7 +69,7 @@ func (b *Bot) allowAdmin(actorID id.UserID, _ id.RoomID) bool {
|
||||
}
|
||||
|
||||
func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
|
||||
if !b.allowUsers(actorID) {
|
||||
if !b.allowUsers(actorID, targetRoomID) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -73,7 +83,7 @@ func (b *Bot) allowSend(actorID id.UserID, targetRoomID id.RoomID) bool {
|
||||
}
|
||||
|
||||
func (b *Bot) allowReply(actorID id.UserID, targetRoomID id.RoomID) bool {
|
||||
if !b.allowUsers(actorID) {
|
||||
if !b.allowUsers(actorID, targetRoomID) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
32
bot/email.go
32
bot/email.go
@@ -3,7 +3,9 @@ package bot
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitlab.com/etke.cc/linkpearl"
|
||||
"maunium.net/go/mautrix/event"
|
||||
@@ -71,7 +73,7 @@ func (b *Bot) Sendmail(eventID id.EventID, from, to, data string) (bool, error)
|
||||
return false, err
|
||||
}
|
||||
|
||||
log.Warn().Err(err).Msg("email delivery succeeded")
|
||||
log.Info().Msg("email delivery succeeded")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -202,7 +204,7 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
|
||||
}
|
||||
|
||||
evt := &event.Event{
|
||||
ID: threadID + "-autoreply",
|
||||
ID: id.EventID(fmt.Sprintf("%s-autoreply-%s", threadID, time.Now().UTC().Format("20060102T150405Z"))),
|
||||
RoomID: roomID,
|
||||
Content: event.Content{
|
||||
Parsed: &event.MessageEventContent{
|
||||
@@ -256,17 +258,17 @@ func (b *Bot) sendAutoreply(roomID id.RoomID, threadID id.EventID) {
|
||||
queued, err = b.Sendmail(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 (queued)")
|
||||
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent to "+to+" (queued)")
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
b.Error(ctx, "cannot send email: %v", err)
|
||||
b.Error(ctx, "cannot send email to %q: %v", to, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent")
|
||||
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg, "Autoreply has been sent to "+to)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) canReply(ctx context.Context) bool {
|
||||
@@ -345,12 +347,12 @@ func (b *Bot) SendEmailReply(ctx context.Context) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
b.Error(ctx, "cannot send email: %v", err)
|
||||
b.Error(ctx, "cannot send email to %q: %v", to, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg)
|
||||
b.saveSentMetadata(ctx, queued, meta.ThreadID, recipients, eml, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
type parentEmail struct {
|
||||
@@ -420,7 +422,7 @@ func (e *parentEmail) fixtofrom(newSenderMailbox string, domains []string) strin
|
||||
|
||||
func (e *parentEmail) calculateRecipients(from string, forwardedFrom []string) {
|
||||
recipients := map[string]struct{}{}
|
||||
recipients[e.From] = struct{}{}
|
||||
recipients[email.Address(e.From)] = struct{}{}
|
||||
|
||||
for _, addr := range strings.Split(email.Address(e.To), ",") {
|
||||
recipients[addr] = struct{}{}
|
||||
@@ -436,7 +438,7 @@ func (e *parentEmail) calculateRecipients(from string, forwardedFrom []string) {
|
||||
|
||||
rcpts := make([]string, 0, len(recipients))
|
||||
for rcpt := range recipients {
|
||||
rcpts = append(rcpts, rcpt)
|
||||
rcpts = append(rcpts, email.Address(rcpt))
|
||||
}
|
||||
|
||||
e.Recipients = rcpts
|
||||
@@ -486,10 +488,10 @@ func (b *Bot) getParentEmail(evt *event.Event, newFromMailbox string) *parentEma
|
||||
return parent
|
||||
}
|
||||
|
||||
parent.From = linkpearl.EventField[string](&parentEvt.Content, eventFromKey)
|
||||
parent.To = linkpearl.EventField[string](&parentEvt.Content, eventToKey)
|
||||
parent.CC = linkpearl.EventField[string](&parentEvt.Content, eventCcKey)
|
||||
parent.RcptTo = linkpearl.EventField[string](&parentEvt.Content, eventRcptToKey)
|
||||
parent.From = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventFromKey))
|
||||
parent.To = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventToKey))
|
||||
parent.CC = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventCcKey))
|
||||
parent.RcptTo = email.Address(linkpearl.EventField[string](&parentEvt.Content, eventRcptToKey))
|
||||
parent.InReplyTo = linkpearl.EventField[string](&parentEvt.Content, eventMessageIDkey)
|
||||
parent.References = linkpearl.EventField[string](&parentEvt.Content, eventReferencesKey)
|
||||
senderEmail := parent.fixtofrom(newFromMailbox, b.domains)
|
||||
|
||||
@@ -3,7 +3,6 @@ package bot
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/etke.cc/go/mxidwc"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
)
|
||||
@@ -33,7 +32,7 @@ func (b *Bot) initSync() {
|
||||
|
||||
// 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 !mxidwc.Match(evt.Sender.String(), b.allowedUsers) {
|
||||
if !b.allowUsers(evt.Sender, evt.RoomID) {
|
||||
b.log.Debug().Str("userID", evt.Sender.String()).Msg("Rejecting room invitation from unallowed user")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func (s *incomingSession) Mail(from string, opts smtp.MailOptions) error {
|
||||
s.ban(s.addr)
|
||||
return ErrBanned
|
||||
}
|
||||
s.from = from
|
||||
s.from = email.Address(from)
|
||||
s.log.Debug().Str("from", from).Any("options", opts).Msg("incoming mail")
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user