Browse Source

Clear in_space flag in portals when deleting parent

Tulir Asokan 2 years ago
parent
commit
74e6c5f53e
2 changed files with 45 additions and 3 deletions
  1. 22 2
      database/portal.go
  2. 23 1
      portal.go

+ 22 - 2
database/portal.go

@@ -244,8 +244,28 @@ func (portal *Portal) Update(txn dbutil.Execable) {
 }
 
 func (portal *Portal) Delete() {
-	_, err := portal.db.Exec("DELETE FROM portal WHERE jid=$1 AND receiver=$2", portal.Key.JID, portal.Key.Receiver)
+	txn, err := portal.db.Begin()
 	if err != nil {
-		portal.log.Warnfln("Failed to delete %s: %v", portal.Key, err)
+		portal.log.Errorfln("Failed to begin transaction to delete portal %v: %v", portal.Key, err)
+		return
+	}
+	defer func() {
+		if err != nil {
+			err = txn.Rollback()
+			if err != nil {
+				portal.log.Warnfln("Failed to rollback failed portal delete transaction: %v", err)
+			}
+		} else if err = txn.Commit(); err != nil {
+			portal.log.Warnfln("Failed to commit portal delete transaction: %v", err)
+		}
+	}()
+	_, err = portal.db.Exec("UPDATE portal SET in_space=false WHERE parent_group=$1", portal.Key.JID)
+	if err != nil {
+		portal.log.Warnfln("Failed to mark child groups of %v as not in space: %v", portal.Key.JID, err)
+		return
+	}
+	_, err = portal.db.Exec("DELETE FROM portal WHERE jid=$1 AND receiver=$2", portal.Key.JID, portal.Key.Receiver)
+	if err != nil {
+		portal.log.Warnfln("Failed to delete %v: %v", portal.Key, err)
 	}
 }

+ 23 - 1
portal.go

@@ -1262,8 +1262,8 @@ func (portal *Portal) UpdateMetadata(user *User, groupInfo *types.GroupInfo) boo
 		if portal.MXID != "" {
 			portal.log.Warnfln("Existing group changed is_parent from %t to %t", portal.IsParent, groupInfo.IsParent)
 		}
+		portal.IsParent = groupInfo.IsParent
 		update = true
-		portal.IsParent = true
 	}
 
 	portal.RestrictMessageSending(groupInfo.IsAnnounce)
@@ -1731,6 +1731,13 @@ func (portal *Portal) addToPersonalSpace(user *User) {
 	}
 }
 
+func (portal *Portal) removeSpaceParentEvent(space id.RoomID) {
+	_, err := portal.MainIntent().SendStateEvent(portal.MXID, event.StateSpaceParent, space.String(), &event.SpaceParentEventContent{})
+	if err != nil {
+		portal.log.Warnfln("Failed to send m.space.parent event to remove portal from %s: %v", space, err)
+	}
+}
+
 func (portal *Portal) updateCommunitySpace(user *User, add, updateDB bool) bool {
 	if add == portal.InSpace {
 		return false
@@ -4147,6 +4154,20 @@ func (portal *Portal) canBridgeFrom(sender *User, allowRelay bool) error {
 	return nil
 }
 
+func (portal *Portal) resetChildSpaceStatus() {
+	for _, childPortal := range portal.bridge.portalsByJID {
+		if childPortal.ParentGroup == portal.Key.JID {
+			if portal.MXID != "" && childPortal.InSpace {
+				go childPortal.removeSpaceParentEvent(portal.MXID)
+			}
+			childPortal.InSpace = false
+			if childPortal.parentPortal == portal {
+				childPortal.parentPortal = nil
+			}
+		}
+	}
+}
+
 func (portal *Portal) Delete() {
 	portal.Portal.Delete()
 	portal.bridge.portalsLock.Lock()
@@ -4154,6 +4175,7 @@ func (portal *Portal) Delete() {
 	if len(portal.MXID) > 0 {
 		delete(portal.bridge.portalsByMXID, portal.MXID)
 	}
+	portal.resetChildSpaceStatus()
 	portal.bridge.portalsLock.Unlock()
 }