Reimplement more things

This commit is contained in:
Tulir Asokan 2021-11-05 12:17:56 +02:00
parent 7e20452783
commit 433aaf3829
6 changed files with 88 additions and 75 deletions

View file

@ -323,6 +323,7 @@ func (handler *CommandHandler) CommandCreate(ce *CommandEvent) {
var roomNameEvent event.RoomNameEventContent var roomNameEvent event.RoomNameEventContent
err = ce.Bot.StateEvent(ce.RoomID, event.StateRoomName, "", &roomNameEvent) err = ce.Bot.StateEvent(ce.RoomID, event.StateRoomName, "", &roomNameEvent)
if err != nil && !errors.Is(err, mautrix.MNotFound) { if err != nil && !errors.Is(err, mautrix.MNotFound) {
handler.log.Errorln("Failed to get room name to create group:", err)
ce.Reply("Failed to get room name") ce.Reply("Failed to get room name")
return return
} else if len(roomNameEvent.Name) == 0 { } else if len(roomNameEvent.Name) == 0 {
@ -337,45 +338,57 @@ func (handler *CommandHandler) CommandCreate(ce *CommandEvent) {
return return
} }
participants := []types.JID{ce.User.JID.ToNonAD()} var participants []types.JID
participantDedup := make(map[types.JID]bool)
participantDedup[ce.User.JID.ToNonAD()] = true
participantDedup[types.EmptyJID] = true
for userID := range members.Joined { for userID := range members.Joined {
jid, ok := handler.bridge.ParsePuppetMXID(userID) jid, ok := handler.bridge.ParsePuppetMXID(userID)
if ok && jid.User != ce.User.JID.User { if !ok {
user := handler.bridge.GetUserByMXID(userID)
if user != nil && !user.JID.IsEmpty() {
jid = user.JID.ToNonAD()
}
}
if !participantDedup[jid] {
participantDedup[jid] = true
participants = append(participants, jid) participants = append(participants, jid)
} }
} }
ce.Reply("Not yet implemented") handler.log.Infofln("Creating group for %s with name %s and participants %+v", ce.RoomID, roomNameEvent.Name, participants)
// TODO reimplement resp, err := ce.User.Client.CreateGroup(roomNameEvent.Name, participants)
//resp, err := ce.User.Conn.CreateGroup(roomNameEvent.Name, participants) if err != nil {
//if err != nil { ce.Reply("Failed to create group: %v", err)
// ce.Reply("Failed to create group: %v", err) return
// return }
//} portal := ce.User.GetPortalByJID(resp.JID)
//portal := handler.bridge.GetPortalByJID(database.GroupPortalKey(resp.GroupID)) portal.roomCreateLock.Lock()
//portal.roomCreateLock.Lock() defer portal.roomCreateLock.Unlock()
//defer portal.roomCreateLock.Unlock() if len(portal.MXID) != 0 {
//if len(portal.MXID) != 0 { portal.log.Warnln("Detected race condition in room creation")
// portal.log.Warnln("Detected race condition in room creation") // TODO race condition, clean up the old room
// // TODO race condition, clean up the old room }
//} portal.MXID = ce.RoomID
//portal.MXID = ce.RoomID portal.Name = roomNameEvent.Name
//portal.Name = roomNameEvent.Name portal.Encrypted = encryptionEvent.Algorithm == id.AlgorithmMegolmV1
//portal.Encrypted = encryptionEvent.Algorithm == id.AlgorithmMegolmV1 if !portal.Encrypted && handler.bridge.Config.Bridge.Encryption.Default {
//if !portal.Encrypted && handler.bridge.Config.Bridge.Encryption.Default { _, err = portal.MainIntent().SendStateEvent(portal.MXID, event.StateEncryption, "", &event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1})
// _, err = portal.MainIntent().SendStateEvent(portal.MXID, event.StateEncryption, "", &event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1}) if err != nil {
// if err != nil { portal.log.Warnln("Failed to enable encryption in room:", err)
// portal.log.Warnln("Failed to enable e2be:", err) if errors.Is(err, mautrix.MForbidden) {
// } ce.Reply("I don't seem to have permission to enable encryption in this room.")
// portal.Encrypted = true } else {
//} ce.Reply("Failed to enable encryption in room: %v", err)
// }
//portal.Update() }
//portal.UpdateBridgeInfo() portal.Encrypted = true
// }
//ce.Reply("Successfully created WhatsApp group %s", portal.Key.JID)
//inCommunity := ce.User.addPortalToCommunity(portal) portal.Update()
//ce.User.CreateUserPortal(database.PortalKeyWithMeta{PortalKey: portal.Key, InCommunity: inCommunity}) portal.UpdateBridgeInfo()
ce.Reply("Successfully created WhatsApp group %s", portal.Key.JID)
} }
func parseInviteMeta(meta map[string]interface{}) (jid, inviter types.JID, code string, expiration int64, ok bool) { func parseInviteMeta(meta map[string]interface{}) (jid, inviter types.JID, code string, expiration int64, ok bool) {

View file

@ -138,6 +138,6 @@ func (puppet *Puppet) Update() {
_, err := puppet.db.Exec("UPDATE puppet SET displayname=$1, name_quality=$2, avatar=$3, avatar_url=$4, custom_mxid=$5, access_token=$6, next_batch=$7, enable_presence=$8, enable_receipts=$9 WHERE username=$10", _, err := puppet.db.Exec("UPDATE puppet SET displayname=$1, name_quality=$2, avatar=$3, avatar_url=$4, custom_mxid=$5, access_token=$6, next_batch=$7, enable_presence=$8, enable_receipts=$9 WHERE username=$10",
puppet.Displayname, puppet.NameQuality, puppet.Avatar, puppet.AvatarURL.String(), puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch, puppet.EnablePresence, puppet.EnableReceipts, puppet.JID.User) puppet.Displayname, puppet.NameQuality, puppet.Avatar, puppet.AvatarURL.String(), puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch, puppet.EnablePresence, puppet.EnableReceipts, puppet.JID.User)
if err != nil { if err != nil {
puppet.log.Warnfln("Failed to update %s->%s: %v", puppet.JID, err) puppet.log.Warnfln("Failed to update %s: %v", puppet.JID, err)
} }
} }

View file

@ -218,13 +218,13 @@ func (store *SQLStateStore) GetPowerLevels(roomID id.RoomID) (levels *event.Powe
var data []byte var data []byte
err := row.Scan(&data) err := row.Scan(&data)
if err != nil { if err != nil {
store.log.Errorln("Failed to scan power levels of %s: %v", roomID, err) store.log.Errorfln("Failed to scan power levels of %s: %v", roomID, err)
return return
} }
levels = &event.PowerLevelsEventContent{} levels = &event.PowerLevelsEventContent{}
err = json.Unmarshal(data, levels) err = json.Unmarshal(data, levels)
if err != nil { if err != nil {
store.log.Errorln("Failed to parse power levels of %s: %v", roomID, err) store.log.Errorfln("Failed to parse power levels of %s: %v", roomID, err)
return nil return nil
} }
return return
@ -242,7 +242,7 @@ func (store *SQLStateStore) GetPowerLevel(roomID id.RoomID, userID id.UserID) in
var powerLevel int var powerLevel int
err := row.Scan(&powerLevel) err := row.Scan(&powerLevel)
if err != nil { if err != nil {
store.log.Errorln("Failed to scan power level of %s in %s: %v", userID, roomID, err) store.log.Errorfln("Failed to scan power level of %s in %s: %v", userID, roomID, err)
} }
return powerLevel return powerLevel
} }
@ -267,7 +267,7 @@ func (store *SQLStateStore) GetPowerLevelRequirement(roomID id.RoomID, eventType
var powerLevel int var powerLevel int
err := row.Scan(&powerLevel) err := row.Scan(&powerLevel)
if err != nil { if err != nil {
store.log.Errorln("Failed to scan power level for %s in %s: %v", eventType, roomID, err) store.log.Errorfln("Failed to scan power level for %s in %s: %v", eventType, roomID, err)
} }
return powerLevel return powerLevel
} }
@ -294,7 +294,7 @@ func (store *SQLStateStore) HasPowerLevel(roomID id.RoomID, userID id.UserID, ev
var hasPower bool var hasPower bool
err := row.Scan(&hasPower) err := row.Scan(&hasPower)
if err != nil { if err != nil {
store.log.Errorln("Failed to scan power level for %s in %s: %v", eventType, roomID, err) store.log.Errorfln("Failed to scan power level for %s in %s: %v", eventType, roomID, err)
} }
return hasPower return hasPower
} }

4
go.mod
View file

@ -8,13 +8,13 @@ require (
github.com/mattn/go-sqlite3 v1.14.9 github.com/mattn/go-sqlite3 v1.14.9
github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_golang v1.11.0
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
go.mau.fi/whatsmeow v0.0.0-20211103125516-00d0df2dd132 go.mau.fi/whatsmeow v0.0.0-20211105101612-33697884c521
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
google.golang.org/protobuf v1.27.1 google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
maunium.net/go/mauflag v1.0.0 maunium.net/go/mauflag v1.0.0
maunium.net/go/maulogger/v2 v2.3.1 maunium.net/go/maulogger/v2 v2.3.1
maunium.net/go/mautrix v0.10.1-0.20211103193019-010782c6021e maunium.net/go/mautrix v0.10.1
) )
require ( require (

8
go.sum
View file

@ -139,8 +139,8 @@ github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8=
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs= github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2 h1:xpQTMgJGGaF+c8jV/LA/FVXAPJxZbSAGeflOc+Ly6uQ= go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2 h1:xpQTMgJGGaF+c8jV/LA/FVXAPJxZbSAGeflOc+Ly6uQ=
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2/go.mod h1:3XlVlwOfp8f9Wri+C1D4ORqgUsN4ZvunJOoPjQMBhos= go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2/go.mod h1:3XlVlwOfp8f9Wri+C1D4ORqgUsN4ZvunJOoPjQMBhos=
go.mau.fi/whatsmeow v0.0.0-20211103125516-00d0df2dd132 h1:wgpiQPdoKCTyhK/GfNfeNhbXjG5A3Fjkbfsmww6ojcY= go.mau.fi/whatsmeow v0.0.0-20211105101612-33697884c521 h1:rkqvvX5qemi5DHMcwS5T/NmYBrzX3TAqKLW7P5lyHZg=
go.mau.fi/whatsmeow v0.0.0-20211103125516-00d0df2dd132/go.mod h1:ODEmmqeUn9eBDQHFc1S902YA3YFLtmaBujYRRFl53jI= go.mau.fi/whatsmeow v0.0.0-20211105101612-33697884c521/go.mod h1:ODEmmqeUn9eBDQHFc1S902YA3YFLtmaBujYRRFl53jI=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -219,5 +219,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/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
maunium.net/go/maulogger/v2 v2.3.1 h1:fwBYJne0pHvJrrIPHK+TAPfyxxbBEz46oVGez2x0ODE= maunium.net/go/maulogger/v2 v2.3.1 h1:fwBYJne0pHvJrrIPHK+TAPfyxxbBEz46oVGez2x0ODE=
maunium.net/go/maulogger/v2 v2.3.1/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A= maunium.net/go/maulogger/v2 v2.3.1/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
maunium.net/go/mautrix v0.10.1-0.20211103193019-010782c6021e h1:yvKCw2P/nHEfjvKAVA8aokbe1UYIgJcswnv50EZaSRU= maunium.net/go/mautrix v0.10.1 h1:sJeygU2CpvoeHKpCOLxUstclHG740IeBfTtKgKnC+nU=
maunium.net/go/mautrix v0.10.1-0.20211103193019-010782c6021e/go.mod h1:k4Ng5oci83MEbqPL6KOjPdbU7f8v01KlMjR/zTQ+7mA= maunium.net/go/mautrix v0.10.1/go.mod h1:k4Ng5oci83MEbqPL6KOjPdbU7f8v01KlMjR/zTQ+7mA=

View file

@ -1423,10 +1423,10 @@ func (portal *Portal) HandleWhatsAppKick(source *User, senderJID types.JID, jids
sender := portal.bridge.GetPuppetByJID(senderJID) sender := portal.bridge.GetPuppetByJID(senderJID)
senderIntent := sender.IntentFor(portal) senderIntent := sender.IntentFor(portal)
for _, jid := range jids { for _, jid := range jids {
if source != nil && source.JID.User == jid.User { //if source != nil && source.JID.User == jid.User {
portal.log.Debugln("Ignoring self-kick by", source.MXID) // portal.log.Debugln("Ignoring self-kick by", source.MXID)
continue // continue
} //}
puppet := portal.bridge.GetPuppetByJID(jid) puppet := portal.bridge.GetPuppetByJID(jid)
portal.removeUser(puppet.JID == sender.JID, senderIntent, puppet.MXID, puppet.DefaultIntent()) portal.removeUser(puppet.JID == sender.JID, senderIntent, puppet.MXID, puppet.DefaultIntent())
@ -1452,7 +1452,8 @@ func (portal *Portal) leaveWithPuppetMeta(intent *appservice.IntentAPI) (*mautri
doublePuppetField: true, doublePuppetField: true,
}, },
} }
return intent.SendStateEvent(portal.MXID, event.StateMember, intent.UserID.String(), &content) // Bypass IntentAPI, we don't want to EnsureJoined here
return intent.Client.SendStateEvent(portal.MXID, event.StateMember, intent.UserID.String(), &content)
} }
func (portal *Portal) HandleWhatsAppInvite(source *User, senderJID *types.JID, jids []types.JID) (evtID id.EventID) { func (portal *Portal) HandleWhatsAppInvite(source *User, senderJID *types.JID, jids []types.JID) (evtID id.EventID) {
@ -2250,13 +2251,11 @@ func (portal *Portal) HandleMatrixLeave(sender *User) {
portal.Cleanup(false) portal.Cleanup(false)
return return
} else if portal.bridge.Config.Bridge.BridgeMatrixLeave { } else if portal.bridge.Config.Bridge.BridgeMatrixLeave {
// TODO should we somehow deduplicate this call if this leave was sent by the bridge? err := sender.Client.LeaveGroup(portal.Key.JID)
// FIXME reimplement if err != nil {
//resp, err := sender.Client.LeaveGroup(portal.Key.JID) portal.log.Errorfln("Failed to leave group as %s: %v", sender.MXID, err)
//if err != nil { return
// portal.log.Errorfln("Failed to leave group as %s: %v", sender.MXID, err) }
// return
//}
//portal.log.Infoln("Leave response:", <-resp) //portal.log.Infoln("Leave response:", <-resp)
} }
portal.CleanupIfEmpty() portal.CleanupIfEmpty()
@ -2265,12 +2264,13 @@ func (portal *Portal) HandleMatrixLeave(sender *User) {
func (portal *Portal) HandleMatrixKick(sender *User, evt *event.Event) { func (portal *Portal) HandleMatrixKick(sender *User, evt *event.Event) {
puppet := portal.bridge.GetPuppetByMXID(id.UserID(evt.GetStateKey())) puppet := portal.bridge.GetPuppetByMXID(id.UserID(evt.GetStateKey()))
if puppet != nil { if puppet != nil {
// FIXME reimplement _, err := sender.Client.UpdateGroupParticipants(portal.Key.JID, map[types.JID]whatsmeow.ParticipantChange{
//resp, err := sender.Conn.RemoveMember(portal.Key.JID, []string{puppet.JID}) puppet.JID: whatsmeow.ParticipantChangeRemove,
//if err != nil { })
// portal.log.Errorfln("Failed to kick %s from group as %s: %v", puppet.JID, sender.MXID, err) if err != nil {
// return portal.log.Errorfln("Failed to kick %s from group as %s: %v", puppet.JID, sender.MXID, err)
//} return
}
//portal.log.Infoln("Kick %s response: %s", puppet.JID, <-resp) //portal.log.Infoln("Kick %s response: %s", puppet.JID, <-resp)
} }
} }
@ -2278,12 +2278,13 @@ func (portal *Portal) HandleMatrixKick(sender *User, evt *event.Event) {
func (portal *Portal) HandleMatrixInvite(sender *User, evt *event.Event) { func (portal *Portal) HandleMatrixInvite(sender *User, evt *event.Event) {
puppet := portal.bridge.GetPuppetByMXID(id.UserID(evt.GetStateKey())) puppet := portal.bridge.GetPuppetByMXID(id.UserID(evt.GetStateKey()))
if puppet != nil { if puppet != nil {
// FIXME reimplement _, err := sender.Client.UpdateGroupParticipants(portal.Key.JID, map[types.JID]whatsmeow.ParticipantChange{
//resp, err := sender.Conn.AddMember(portal.Key.JID, []string{puppet.JID}) puppet.JID: whatsmeow.ParticipantChangeAdd,
//if err != nil { })
// portal.log.Errorfln("Failed to add %s to group as %s: %v", puppet.JID, sender.MXID, err) if err != nil {
// return portal.log.Errorfln("Failed to add %s to group as %s: %v", puppet.JID, sender.MXID, err)
//} return
}
//portal.log.Infofln("Add %s response: %s", puppet.JID, <-resp) //portal.log.Infofln("Add %s response: %s", puppet.JID, <-resp)
} }
} }
@ -2295,17 +2296,16 @@ func (portal *Portal) HandleMatrixMeta(sender *User, evt *event.Event) {
if content.Name == portal.Name { if content.Name == portal.Name {
return return
} }
// FIXME reimplement portal.Name = content.Name
//portal.Name = content.Name err = sender.Client.SetGroupName(portal.Key.JID, content.Name)
//resp, err = sender.Conn.UpdateGroupSubject(content.Name, portal.Key.JID)
case *event.TopicEventContent: case *event.TopicEventContent:
if content.Topic == portal.Topic { if content.Topic == portal.Topic {
return return
} }
// FIXME reimplement portal.Topic = content.Topic
//portal.Topic = content.Topic err = sender.Client.SetGroupTopic(portal.Key.JID, "", "", content.Topic)
//resp, err = sender.Conn.UpdateGroupDescription(sender.JID, portal.Key.JID, content.Topic)
case *event.RoomAvatarEventContent: case *event.RoomAvatarEventContent:
// TODO implement
return return
} }
if err != nil { if err != nil {