diff --git a/config/bridge.go b/config/bridge.go index f8678ab..2c1f60c 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -46,6 +46,7 @@ type BridgeConfig struct { SyncDirectChatList bool `yaml:"sync_direct_chat_list"` ResendBridgeInfo bool `yaml:"resend_bridge_info"` DeletePortalOnChannelDelete bool `yaml:"delete_portal_on_channel_delete"` + DeleteGuildOnLeave bool `yaml:"delete_guild_on_leave"` FederateRooms bool `yaml:"federate_rooms"` DoublePuppetServerMap map[string]string `yaml:"double_puppet_server_map"` diff --git a/config/upgrade.go b/config/upgrade.go index a33ad3b..8b4c3d4 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -41,6 +41,7 @@ func DoUpgrade(helper *up.Helper) { helper.Copy(up.Bool, "bridge", "sync_direct_chat_list") helper.Copy(up.Bool, "bridge", "resend_bridge_info") helper.Copy(up.Bool, "bridge", "delete_portal_on_channel_delete") + helper.Copy(up.Bool, "bridge", "delete_guild_on_leave") helper.Copy(up.Bool, "bridge", "federate_rooms") helper.Copy(up.Map, "bridge", "double_puppet_server_map") helper.Copy(up.Bool, "bridge", "double_puppet_allow_discovery") diff --git a/database/userportal.go b/database/userportal.go index b4eacf4..d5e869e 100644 --- a/database/userportal.go +++ b/database/userportal.go @@ -96,6 +96,16 @@ func (u *User) MarkNotInPortal(discordID string) { } } +func (u *User) PortalHasOtherUsers(discordID string) (hasOtherUsers bool) { + query := `SELECT COUNT(*) > 0 FROM user_portal WHERE user_mxid<>$1 AND discord_id=$2` + err := u.db.QueryRow(query, u.MXID, discordID).Scan(&hasOtherUsers) + if err != nil { + u.log.Errorfln("Failed to check if %s has users other than %s: %v", discordID, u.MXID, err) + panic(err) + } + return +} + func (u *User) PrunePortalList(beforeTS time.Time) []UserPortal { query := ` DELETE FROM user_portal diff --git a/example-config.yaml b/example-config.yaml index 3eced6c..8fe8f0f 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -128,6 +128,9 @@ bridge: # Should the bridge attempt to completely delete portal rooms when a channel is deleted on Discord? # If true, the bridge will try to kick Matrix users from the room. Otherwise, the bridge only makes ghosts leave. delete_portal_on_channel_delete: false + # Should the bridge delete all portal rooms when you leave a guild on Discord? + # This only applies if the guild has no other Matrix users on this bridge instance. + delete_guild_on_leave: true # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. federate_rooms: true diff --git a/user.go b/user.go index 1136fe9..2672989 100644 --- a/user.go +++ b/user.go @@ -780,7 +780,12 @@ func (user *User) guildDeleteHandler(_ *discordgo.Session, g *discordgo.GuildDel if guild == nil || guild.MXID == "" { return } - // TODO clean up? + if user.bridge.Config.Bridge.DeleteGuildOnLeave && !user.PortalHasOtherUsers(g.ID) { + err := user.unbridgeGuild(g.ID) + if err != nil { + user.log.Warnfln("Failed to unbridge guild that was deleted: %v", err) + } + } } func (user *User) guildUpdateHandler(_ *discordgo.Session, g *discordgo.GuildUpdate) { @@ -1086,8 +1091,8 @@ func (user *User) bridgeGuild(guildID string, everything bool) error { } func (user *User) unbridgeGuild(guildID string) error { - if user.PermissionLevel < bridgeconfig.PermissionLevelAdmin { - return errors.New("only bridge admins can unbridge guilds") + if user.PermissionLevel < bridgeconfig.PermissionLevelAdmin && user.PortalHasOtherUsers(guildID) { + return errors.New("only bridge admins can unbridge guilds with other users") } guild := user.bridge.GetGuildByID(guildID, false) if guild == nil {