diff --git a/config/upgrade.go b/config/upgrade.go index 8338105..ff3d22c 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -17,8 +17,8 @@ package config import ( - "maunium.net/go/mautrix/appservice" "maunium.net/go/mautrix/bridge/bridgeconfig" + "maunium.net/go/mautrix/util" up "maunium.net/go/mautrix/util/configupgrade" ) @@ -61,7 +61,7 @@ func DoUpgrade(helper *up.Helper) { helper.Copy(up.Str, "bridge", "provisioning", "prefix") if secret, ok := helper.Get(up.Str, "bridge", "provisioning", "shared_secret"); !ok || secret == "generate" { - sharedSecret := appservice.RandomString(64) + sharedSecret := util.RandomString(64) helper.Set(up.Str, sharedSecret, "bridge", "provisioning", "shared_secret") } else { helper.Copy(up.Str, "bridge", "provisioning", "shared_secret") diff --git a/database/database.go b/database/database.go index 34aca2d..1b69d7e 100644 --- a/database/database.go +++ b/database/database.go @@ -5,6 +5,7 @@ import ( _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" + "maunium.net/go/maulogger/v2" "maunium.net/go/mautrix/util/dbutil" @@ -25,44 +26,44 @@ type Database struct { Role *RoleQuery } -func New(baseDB *dbutil.Database) *Database { +func New(baseDB *dbutil.Database, log maulogger.Logger) *Database { db := &Database{Database: baseDB} db.UpgradeTable = upgrades.Table db.User = &UserQuery{ db: db, - log: db.Log.Sub("User"), + log: log.Sub("User"), } db.Portal = &PortalQuery{ db: db, - log: db.Log.Sub("Portal"), + log: log.Sub("Portal"), } db.Puppet = &PuppetQuery{ db: db, - log: db.Log.Sub("Puppet"), + log: log.Sub("Puppet"), } db.Message = &MessageQuery{ db: db, - log: db.Log.Sub("Message"), + log: log.Sub("Message"), } db.Thread = &ThreadQuery{ db: db, - log: db.Log.Sub("Thread"), + log: log.Sub("Thread"), } db.Reaction = &ReactionQuery{ db: db, - log: db.Log.Sub("Reaction"), + log: log.Sub("Reaction"), } db.Emoji = &EmojiQuery{ db: db, - log: db.Log.Sub("Emoji"), + log: log.Sub("Emoji"), } db.Guild = &GuildQuery{ db: db, - log: db.Log.Sub("Guild"), + log: log.Sub("Guild"), } db.Role = &RoleQuery{ db: db, - log: db.Log.Sub("Role"), + log: log.Sub("Role"), } return db } diff --git a/go.mod b/go.mod index cf44d26..72731f5 100644 --- a/go.mod +++ b/go.mod @@ -11,10 +11,13 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/yuin/goldmark v1.4.12 maunium.net/go/maulogger/v2 v2.3.2 - maunium.net/go/mautrix v0.11.1-0.20220708142125-1f795238d635 + maunium.net/go/mautrix v0.11.1-0.20220815133425-ba1fce8fce24 ) require ( + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/rs/zerolog v1.27.0 // indirect github.com/tidwall/gjson v1.14.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect diff --git a/go.sum b/go.sum index ed68b1a..b61b07e 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -8,10 +12,18 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= +github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -42,6 +54,8 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -59,5 +73,5 @@ maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= maunium.net/go/maulogger/v2 v2.3.2 h1:1XmIYmMd3PoQfp9J+PaHhpt80zpfmMqaShzUTC7FwY0= maunium.net/go/maulogger/v2 v2.3.2/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A= -maunium.net/go/mautrix v0.11.1-0.20220708142125-1f795238d635 h1:/kbw/ZW+MzViciUoTmhJoasmZcqHhcKSPws+FfKwb0s= -maunium.net/go/mautrix v0.11.1-0.20220708142125-1f795238d635/go.mod h1:85mjebfgKX7jjca7XNKTt7lHueX3YQsFUU+5o/FxpTw= +maunium.net/go/mautrix v0.11.1-0.20220815133425-ba1fce8fce24 h1:40cxOxHwTw+UYdDTV//tHw9bjNMmJ9uH6ye+C1SbOGA= +maunium.net/go/mautrix v0.11.1-0.20220815133425-ba1fce8fce24/go.mod h1:hHvNi5iKVAiI2MAdAeXHtP4g9BvNEX2rsQpSF/x6Kx4= diff --git a/main.go b/main.go index 2d2dccd..c707e3d 100644 --- a/main.go +++ b/main.go @@ -88,7 +88,7 @@ func (br *DiscordBridge) Init() { br.CommandProcessor = commands.NewProcessor(&br.Bridge) br.RegisterCommands() - br.DB = database.New(br.Bridge.DB) + br.DB = database.New(br.Bridge.DB, br.Log.Sub("Database")) discordLog = br.Log.Sub("Discord") } diff --git a/portal.go b/portal.go index f162046..ee61331 100644 --- a/portal.go +++ b/portal.go @@ -9,6 +9,7 @@ import ( "sync" "time" + "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/crypto/attachment" "maunium.net/go/mautrix/util/variationselector" @@ -984,7 +985,7 @@ var ( errUnknownEmoji = errors.New("unknown emoji") ) -func errorToStatusReason(err error) (reason event.MessageStatusReason, isCertain, canRetry, sendNotice bool) { +func errorToStatusReason(err error) (reason event.MessageStatusReason, status event.MessageStatus, isCertain, sendNotice bool, humanMessage string) { switch { case errors.Is(err, errUnknownMsgType), errors.Is(err, errUnknownRelationType), @@ -993,19 +994,19 @@ func errorToStatusReason(err error) (reason event.MessageStatusReason, isCertain errors.Is(err, id.InvalidContentURI), errors.Is(err, attachment.UnsupportedVersion), errors.Is(err, attachment.UnsupportedAlgorithm): - return event.MessageStatusUnsupported, true, false, true + return event.MessageStatusUnsupported, event.MessageStatusFail, true, true, "" case errors.Is(err, attachment.HashMismatch), errors.Is(err, attachment.InvalidKey), errors.Is(err, attachment.InvalidInitVector): - return event.MessageStatusUndecryptable, true, false, true + return event.MessageStatusUndecryptable, event.MessageStatusFail, true, true, "" case errors.Is(err, errUserNotReceiver): - return event.MessageStatusNoPermission, true, false, false + return event.MessageStatusNoPermission, event.MessageStatusFail, true, false, "" case errors.Is(err, errUnknownEditTarget): - return event.MessageStatusGenericError, true, false, false + return event.MessageStatusGenericError, event.MessageStatusFail, true, false, "" case errors.Is(err, errTargetNotFound): - return event.MessageStatusGenericError, true, false, true + return event.MessageStatusGenericError, event.MessageStatusFail, true, true, "" default: - return event.MessageStatusGenericError, false, true, true + return event.MessageStatusGenericError, event.MessageStatusRetriable, false, true, "" } } @@ -1025,13 +1026,12 @@ func (portal *Portal) sendStatusEvent(evtID id.EventID, err error) { Type: event.RelReference, EventID: evtID, }, - Success: err == nil, + Status: event.MessageStatusSuccess, } - if !content.Success { - reason, isCertain, canRetry, _ := errorToStatusReason(err) - content.Reason = reason - content.IsCertain = &isCertain - content.CanRetry = &canRetry + if err == nil { + content.Status = event.MessageStatusSuccess + } else { + content.Reason, content.Status, _, _, content.Message = errorToStatusReason(err) content.Error = err.Error() } _, err = intent.SendMessageEvent(portal.MXID, event.BeeperMessageStatus, &content) @@ -1062,9 +1062,9 @@ func (portal *Portal) sendMessageMetrics(evt *event.Event, err error, part strin level = log.LevelDebug } portal.log.Logfln(level, "%s %s %s from %s: %v", part, msgType, evtDescription, evt.Sender, err) - reason, isCertain, _, sendNotice := errorToStatusReason(err) - status := bridge.ReasonToCheckpointStatus(reason) - portal.bridge.SendMessageCheckpoint(evt, bridge.MsgStepRemote, err, status, 0) + reason, statusCode, isCertain, sendNotice, _ := errorToStatusReason(err) + checkpointStatus := status.ReasonToCheckpointStatus(reason, statusCode) + portal.bridge.SendMessageCheckpoint(evt, status.MsgStepRemote, err, checkpointStatus, 0) if sendNotice { portal.sendErrorMessage(msgType, err.Error(), isCertain) } @@ -1072,7 +1072,7 @@ func (portal *Portal) sendMessageMetrics(evt *event.Event, err error, part strin } else { portal.log.Debugfln("Handled Matrix %s %s", msgType, evtDescription) portal.sendDeliveryReceipt(evt.ID) - portal.bridge.SendMessageSuccessCheckpoint(evt, bridge.MsgStepRemote, 0) + portal.bridge.SendMessageSuccessCheckpoint(evt, status.MsgStepRemote, 0) portal.sendStatusEvent(evt.ID, nil) } } diff --git a/user.go b/user.go index 2c36db4..09490cb 100644 --- a/user.go +++ b/user.go @@ -19,6 +19,7 @@ import ( "maunium.net/go/mautrix/appservice" "maunium.net/go/mautrix/bridge" "maunium.net/go/mautrix/bridge/bridgeconfig" + "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" @@ -215,22 +216,22 @@ func (br *DiscordBridge) startUsers() { usersWithToken := br.getAllUsersWithToken() for _, u := range usersWithToken { go func(user *User) { - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnecting}) + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting}) err := user.Connect() if err != nil { user.log.Errorfln("Error connecting: %v", err) if closeErr := (&websocket.CloseError{}); errors.As(err, &closeErr) && closeErr.Code == 4004 { - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateBadCredentials, Message: err.Error()}) + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: err.Error()}) user.DiscordToken = "" user.Update() } else { - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateUnknownError, Message: err.Error()}) + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Message: err.Error()}) } } }(u) } if len(usersWithToken) == 0 { - br.SendGlobalBridgeState(bridge.State{StateEvent: bridge.StateUnconfigured}.Fill(nil)) + br.SendGlobalBridgeState(status.BridgeState{StateEvent: status.StateUnconfigured}.Fill(nil)) } br.Log.Debugln("Starting custom puppets") @@ -530,7 +531,7 @@ func (user *User) readyHandler(_ *discordgo.Session, r *discordgo.Ready) { user.DiscordID = r.User.ID user.Update() } - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateBackfilling}) + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBackfilling}) updateTS := time.Now() portalsInSpace := make(map[string]bool) @@ -558,7 +559,7 @@ func (user *User) readyHandler(_ *discordgo.Session, r *discordgo.Ready) { user.Update() } - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnected}) + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected}) } func (user *User) addPrivateChannelToSpace(portal *Portal) bool { @@ -706,14 +707,14 @@ func (user *User) connectedHandler(_ *discordgo.Session, c *discordgo.Connect) { user.log.Debugln("Connected to discord") user.tryAutomaticDoublePuppeting() - if user.BridgeState.GetPrev().StateEvent == bridge.StateTransientDisconnect { - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnected}) + if user.BridgeState.GetPrev().StateEvent == status.StateTransientDisconnect { + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected}) } } func (user *User) disconnectedHandler(_ *discordgo.Session, d *discordgo.Disconnect) { user.log.Debugln("Disconnected from discord") - user.BridgeState.Send(bridge.State{StateEvent: bridge.StateTransientDisconnect}) + user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect}) } func (user *User) guildCreateHandler(_ *discordgo.Session, g *discordgo.GuildCreate) {