Procházet zdrojové kódy

Add option to not set room meta in encrypted rooms

Tulir Asokan před 2 roky
rodič
revize
0fcb64c1aa
6 změnil soubory, kde provedl 67 přidání a 52 odebrání
  1. 2 2
      config/bridge.go
  2. 9 1
      config/upgrade.go
  3. 5 3
      example-config.yaml
  4. 10 10
      matrix.go
  5. 32 24
      portal.go
  6. 9 12
      puppet.go

+ 2 - 2
config/bridge.go

@@ -1,5 +1,5 @@
 // mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
-// Copyright (C) 2021 Tulir Asokan
+// Copyright (C) 2023 Tulir Asokan
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
@@ -99,7 +99,7 @@ type BridgeConfig struct {
 	DoublePuppetAllowDiscovery bool              `yaml:"double_puppet_allow_discovery"`
 	LoginSharedSecretMap       map[string]string `yaml:"login_shared_secret_map"`
 
-	PrivateChatPortalMeta bool   `yaml:"private_chat_portal_meta"`
+	PrivateChatPortalMeta string `yaml:"private_chat_portal_meta"`
 	ParallelMemberSync    bool   `yaml:"parallel_member_sync"`
 	BridgeNotices         bool   `yaml:"bridge_notices"`
 	ResendBridgeInfo      bool   `yaml:"resend_bridge_info"`

+ 9 - 1
config/upgrade.go

@@ -77,7 +77,15 @@ func DoUpgrade(helper *up.Helper) {
 	} else {
 		helper.Copy(up.Map, "bridge", "login_shared_secret_map")
 	}
-	helper.Copy(up.Bool, "bridge", "private_chat_portal_meta")
+	if legacyPrivateChatPortalMeta, ok := helper.Get(up.Bool, "bridge", "private_chat_portal_meta"); ok {
+		updatedPrivateChatPortalMeta := "default"
+		if legacyPrivateChatPortalMeta == "true" {
+			updatedPrivateChatPortalMeta = "always"
+		}
+		helper.Set(up.Str, updatedPrivateChatPortalMeta, "bridge", "private_chat_portal_meta")
+	} else {
+		helper.Copy(up.Str, "bridge", "private_chat_portal_meta")
+	}
 	helper.Copy(up.Bool, "bridge", "parallel_member_sync")
 	helper.Copy(up.Bool, "bridge", "bridge_notices")
 	helper.Copy(up.Bool, "bridge", "resend_bridge_info")

+ 5 - 3
example-config.yaml

@@ -254,9 +254,11 @@ bridge:
     # manually.
     login_shared_secret_map:
         example.com: foobar
-    # Should the bridge explicitly set the avatar and room name for private chat portal rooms?
-    # This is implicitly enabled in encrypted rooms.
-    private_chat_portal_meta: false
+    # Whether to explicitly set the avatar and room name for private chat portal rooms.
+    # If set to `default`, this will be enabled in encrypted rooms and disabled in unencrypted rooms.
+    # If set to `always`, all DM rooms will have explicit names and avatars set.
+    # If set to `never`, DM rooms will never have names and avatars set.
+    private_chat_portal_meta: default
     # Should group members be synced in parallel? This makes member sync faster
     parallel_member_sync: false
     # Should Matrix m.notice-type messages be bridged?

+ 10 - 10
matrix.go

@@ -67,16 +67,9 @@ func (br *WABridge) createPrivatePortalFromInvite(roomID id.RoomID, inviter *Use
 	}
 	portal.MXID = roomID
 	portal.Topic = PrivateChatTopic
-	_, _ = portal.MainIntent().SetRoomTopic(portal.MXID, portal.Topic)
-	if portal.bridge.Config.Bridge.PrivateChatPortalMeta || br.Config.Bridge.Encryption.Default || encryptionEnabled {
-		portal.Name = puppet.Displayname
-		portal.AvatarURL = puppet.AvatarURL
-		portal.Avatar = puppet.Avatar
-		_, _ = portal.MainIntent().SetRoomName(portal.MXID, portal.Name)
-		_, _ = portal.MainIntent().SetRoomAvatar(portal.MXID, portal.AvatarURL)
-	} else {
-		portal.Name = ""
-	}
+	portal.Name = puppet.Displayname
+	portal.AvatarURL = puppet.AvatarURL
+	portal.Avatar = puppet.Avatar
 	portal.log.Infofln("Created private chat portal in %s after invite from %s", roomID, inviter.MXID)
 	intent := puppet.DefaultIntent()
 
@@ -100,6 +93,13 @@ func (br *WABridge) createPrivatePortalFromInvite(roomID id.RoomID, inviter *Use
 		br.AS.StateStore.SetMembership(roomID, br.Bot.UserID, event.MembershipJoin)
 		portal.Encrypted = true
 	}
+	_, _ = portal.MainIntent().SetRoomTopic(portal.MXID, portal.Topic)
+	if portal.shouldSetDMRoomMetadata() {
+		_, err = portal.MainIntent().SetRoomName(portal.MXID, portal.Name)
+		portal.NameSet = err == nil
+		_, err = portal.MainIntent().SetRoomAvatar(portal.MXID, portal.AvatarURL)
+		portal.AvatarSet = err == nil
+	}
 	portal.Update(nil)
 	portal.UpdateBridgeInfo()
 	_, _ = intent.SendNotice(roomID, "Private chat portal created")

+ 32 - 24
portal.go

@@ -1156,7 +1156,7 @@ func (portal *Portal) UpdateName(name string, setBy types.JID, updateInfo bool)
 	if name == "" && portal.IsBroadcastList() {
 		name = UnnamedBroadcastName
 	}
-	if portal.Name != name || (!portal.NameSet && len(portal.MXID) > 0) {
+	if portal.Name != name || (!portal.NameSet && len(portal.MXID) > 0 && portal.shouldSetDMRoomMetadata()) {
 		portal.log.Debugfln("Updating name %q -> %q", portal.Name, name)
 		portal.Name = name
 		portal.NameSet = false
@@ -1164,7 +1164,9 @@ func (portal *Portal) UpdateName(name string, setBy types.JID, updateInfo bool)
 			defer portal.Update(nil)
 		}
 
-		if len(portal.MXID) > 0 {
+		if len(portal.MXID) > 0 && !portal.shouldSetDMRoomMetadata() {
+			portal.UpdateBridgeInfo()
+		} else if len(portal.MXID) > 0 {
 			intent := portal.MainIntent()
 			if !setBy.IsEmpty() {
 				intent = portal.bridge.GetPuppetByJID(setBy).IntentFor(portal)
@@ -1497,6 +1499,12 @@ func (portal *Portal) updateChildRooms() {
 	}
 }
 
+func (portal *Portal) shouldSetDMRoomMetadata() bool {
+	return !portal.IsPrivateChat() ||
+		portal.bridge.Config.Bridge.PrivateChatPortalMeta == "always" ||
+		(portal.IsEncrypted() && portal.bridge.Config.Bridge.PrivateChatPortalMeta != "never")
+}
+
 func (portal *Portal) GetEncryptionEventContent() (evt *event.EncryptionEventContent) {
 	evt = &event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1}
 	if rot := portal.bridge.Config.Bridge.Encryption.Rotation; rot.EnableCustom {
@@ -1524,13 +1532,9 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
 	if portal.IsPrivateChat() {
 		puppet := portal.bridge.GetPuppetByJID(portal.Key.JID)
 		puppet.SyncContact(user, true, false, "creating private chat portal")
-		if portal.bridge.Config.Bridge.PrivateChatPortalMeta || portal.bridge.Config.Bridge.Encryption.Default {
-			portal.Name = puppet.Displayname
-			portal.AvatarURL = puppet.AvatarURL
-			portal.Avatar = puppet.Avatar
-		} else {
-			portal.Name = ""
-		}
+		portal.Name = puppet.Displayname
+		portal.AvatarURL = puppet.AvatarURL
+		portal.Avatar = puppet.Avatar
 		portal.Topic = PrivateChatTopic
 	} else if portal.IsStatusBroadcastList() {
 		if !portal.bridge.Config.Bridge.EnableStatusBroadcast {
@@ -1616,18 +1620,7 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
 		Content:  event.Content{Parsed: bridgeInfo},
 		StateKey: &bridgeInfoStateKey,
 	}}
-	if !portal.AvatarURL.IsEmpty() {
-		initialState = append(initialState, &event.Event{
-			Type: event.StateRoomAvatar,
-			Content: event.Content{
-				Parsed: event.RoomAvatarEventContent{URL: portal.AvatarURL},
-			},
-		})
-		portal.AvatarSet = true
-	}
-
 	var invite []id.UserID
-
 	if portal.bridge.Config.Bridge.Encryption.Default {
 		initialState = append(initialState, &event.Event{
 			Type: event.StateEncryption,
@@ -1640,6 +1633,17 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
 			invite = append(invite, portal.bridge.Bot.UserID)
 		}
 	}
+	if !portal.AvatarURL.IsEmpty() && portal.shouldSetDMRoomMetadata() {
+		initialState = append(initialState, &event.Event{
+			Type: event.StateRoomAvatar,
+			Content: event.Content{
+				Parsed: event.RoomAvatarEventContent{URL: portal.AvatarURL},
+			},
+		})
+		portal.AvatarSet = true
+	} else {
+		portal.AvatarSet = false
+	}
 
 	creationContent := make(map[string]interface{})
 	if !portal.bridge.Config.Bridge.FederateRooms {
@@ -1674,7 +1678,7 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
 			invite = append(invite, user.MXID)
 		}
 	}
-	resp, err := intent.CreateRoom(&mautrix.ReqCreateRoom{
+	req := &mautrix.ReqCreateRoom{
 		Visibility:      "private",
 		Name:            portal.Name,
 		Topic:           portal.Topic,
@@ -1685,14 +1689,18 @@ func (portal *Portal) CreateMatrixRoom(user *User, groupInfo *types.GroupInfo, i
 		CreationContent: creationContent,
 
 		BeeperAutoJoinInvites: autoJoinInvites,
-	})
+	}
+	if !portal.shouldSetDMRoomMetadata() {
+		req.Name = ""
+	}
+	resp, err := intent.CreateRoom(req)
 	if err != nil {
 		return err
 	}
 	portal.log.Infoln("Matrix room created:", resp.RoomID)
 	portal.InSpace = false
-	portal.NameSet = len(portal.Name) > 0
-	portal.TopicSet = len(portal.Topic) > 0
+	portal.NameSet = len(req.Name) > 0
+	portal.TopicSet = len(req.Topic) > 0
 	portal.MXID = resp.RoomID
 	portal.bridge.portalsLock.Lock()
 	portal.bridge.portalsByMXID[portal.MXID] = portal

+ 9 - 12
puppet.go

@@ -294,29 +294,26 @@ func (puppet *Puppet) UpdateContactInfo() bool {
 }
 
 func (puppet *Puppet) updatePortalMeta(meta func(portal *Portal)) {
-	if puppet.bridge.Config.Bridge.PrivateChatPortalMeta || puppet.bridge.Config.Bridge.Encryption.Allow {
-		for _, portal := range puppet.bridge.GetAllPortalsByJID(puppet.JID) {
-			if !puppet.bridge.Config.Bridge.PrivateChatPortalMeta && !portal.Encrypted {
-				continue
-			}
-			// Get room create lock to prevent races between receiving contact info and room creation.
-			portal.roomCreateLock.Lock()
-			meta(portal)
-			portal.roomCreateLock.Unlock()
-		}
+	for _, portal := range puppet.bridge.GetAllPortalsByJID(puppet.JID) {
+		// Get room create lock to prevent races between receiving contact info and room creation.
+		portal.roomCreateLock.Lock()
+		meta(portal)
+		portal.roomCreateLock.Unlock()
 	}
 }
 
 func (puppet *Puppet) updatePortalAvatar() {
 	puppet.updatePortalMeta(func(portal *Portal) {
-		if portal.Avatar == puppet.Avatar && portal.AvatarURL == puppet.AvatarURL && portal.AvatarSet {
+		if portal.Avatar == puppet.Avatar && portal.AvatarURL == puppet.AvatarURL && (portal.AvatarSet || !portal.shouldSetDMRoomMetadata()) {
 			return
 		}
 		portal.AvatarURL = puppet.AvatarURL
 		portal.Avatar = puppet.Avatar
 		portal.AvatarSet = false
 		defer portal.Update(nil)
-		if len(portal.MXID) > 0 {
+		if len(portal.MXID) > 0 && !portal.shouldSetDMRoomMetadata() {
+			portal.UpdateBridgeInfo()
+		} else if len(portal.MXID) > 0 {
 			_, err := portal.MainIntent().SetRoomAvatar(portal.MXID, puppet.AvatarURL)
 			if err != nil {
 				portal.log.Warnln("Failed to set avatar:", err)