Automatically re-login-matrix on M_UNKNOWN_TOKEN

This commit is contained in:
Tulir Asokan 2021-02-11 20:47:10 +02:00
parent 481af6cbe4
commit 67a39bb6c8
4 changed files with 44 additions and 12 deletions

View file

@ -20,6 +20,7 @@ import (
"io/ioutil"
"gopkg.in/yaml.v2"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/appservice"
)
@ -77,6 +78,17 @@ type Config struct {
Logging appservice.LogConfig `yaml:"logging"`
}
func (config *Config) CanDoublePuppet(userID id.UserID) bool {
if len(config.Bridge.LoginSharedSecret) == 0 {
// Automatic login not enabled
return false
} else if _, homeserver, _ := userID.Parse(); homeserver != config.Homeserver.Domain {
// user is on another homeserver
return false
}
return true
}
func (config *Config) setDefaults() {
config.AppService.Database.MaxOpenConns = 20
config.AppService.Database.MaxIdleConns = 2

View file

@ -44,7 +44,7 @@ func (puppet *Puppet) SwitchCustomMXID(accessToken string, mxid id.UserID) error
puppet.CustomMXID = mxid
puppet.AccessToken = accessToken
err := puppet.StartCustomMXID()
err := puppet.StartCustomMXID(false)
if err != nil {
return err
}
@ -108,7 +108,7 @@ func (puppet *Puppet) clearCustomMXID() {
puppet.customUser = nil
}
func (puppet *Puppet) StartCustomMXID() error {
func (puppet *Puppet) StartCustomMXID(reloginOnFail bool) error {
if len(puppet.CustomMXID) == 0 {
puppet.clearCustomMXID()
return nil
@ -120,10 +120,12 @@ func (puppet *Puppet) StartCustomMXID() error {
}
resp, err := intent.Whoami()
if err != nil {
puppet.clearCustomMXID()
return err
}
if resp.UserID != puppet.CustomMXID {
if !reloginOnFail || (errors.Is(err, mautrix.MUnknownToken) && !puppet.tryRelogin(err, "initializing double puppeting")) {
puppet.clearCustomMXID()
return err
}
intent.AccessToken = puppet.AccessToken
} else if resp.UserID != puppet.CustomMXID {
puppet.clearCustomMXID()
return ErrMismatchingMXID
}
@ -250,8 +252,30 @@ func (puppet *Puppet) handleTypingEvent(portal *Portal, evt *event.Event) {
}
}
func (puppet *Puppet) tryRelogin(cause error, action string) bool {
if !puppet.bridge.Config.CanDoublePuppet(puppet.CustomMXID) {
return false
}
puppet.log.Debugfln("Trying to relogin after '%v' while %s", cause, action)
accessToken, err := puppet.loginWithSharedSecret(puppet.CustomMXID)
if err != nil {
puppet.log.Errorfln("Failed to relogin after '%v' while %s: %v", cause, action, err)
return false
}
puppet.log.Infofln("Successfully relogined after '%v' while %s", cause, action)
puppet.AccessToken = accessToken
return true
}
func (puppet *Puppet) OnFailedSync(_ *mautrix.RespSync, err error) (time.Duration, error) {
puppet.log.Warnln("Sync error:", err)
if errors.Is(err, mautrix.MUnknownToken) {
if !puppet.tryRelogin(err, "syncing") {
return 0, err
}
puppet.customIntent.AccessToken = puppet.AccessToken
return 0, nil
}
return 10 * time.Second, nil
}

View file

@ -363,7 +363,7 @@ func (bridge *Bridge) StartUsers() {
for _, loopuppet := range bridge.GetAllPuppetsWithCustomMXID() {
go func(puppet *Puppet) {
puppet.log.Debugln("Starting custom puppet", puppet.CustomMXID)
err := puppet.StartCustomMXID()
err := puppet.StartCustomMXID(true)
if err != nil {
puppet.log.Errorln("Failed to start custom puppet:", err)
}

View file

@ -461,11 +461,7 @@ func (user *User) PostLogin() {
}
func (user *User) tryAutomaticDoublePuppeting() {
if len(user.bridge.Config.Bridge.LoginSharedSecret) == 0 {
// Automatic login not enabled
return
} else if _, homeserver, _ := user.MXID.Parse(); homeserver != user.bridge.Config.Homeserver.Domain {
// user is on another homeserver
if !user.bridge.Config.CanDoublePuppet(user.MXID) {
return
}
user.log.Debugln("Checking if double puppeting needs to be enabled")