diff --git a/changelog/705.bugfix.rst b/changelog/705.bugfix.rst new file mode 100644 index 0000000000..0848932e8b --- /dev/null +++ b/changelog/705.bugfix.rst @@ -0,0 +1 @@ +Fixed an issue where it would be possible to remove other features when enabling or disabling the ``COMMUNITY`` feature for a :class:`.Guild`. diff --git a/disnake/guild.py b/disnake/guild.py index ac23d819c8..c654cbe1b8 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -1975,16 +1975,28 @@ async def edit( fields["system_channel_flags"] = system_channel_flags.value if community is not MISSING: - features = [] - if community: - if "rules_channel_id" in fields and "public_updates_channel_id" in fields: - features.append("COMMUNITY") + # If we don't have complete feature information for the guild, + # it is possible to disable or enable other features that we didn't intend to touch. + # To enable or disable a feature, we will need to provide all of the existing features in advance. + if self.unavailable: + raise RuntimeError( + "cannot modify features of an unavailable guild due to potentially destructive results." + ) + features = set(self.features) + if community is not MISSING: + if not isinstance(community, bool): + raise TypeError("community must be a bool instance") + if community: + if "rules_channel_id" in fields and "public_updates_channel_id" in fields: + features.add("COMMUNITY") + else: + raise ValueError( + "community field requires both rules_channel and public_updates_channel fields to be provided" + ) else: - raise ValueError( - "community field requires both rules_channel and public_updates_channel fields to be provided" - ) + features.discard("COMMUNITY") - fields["features"] = features + fields["features"] = list(features) if premium_progress_bar_enabled is not MISSING: fields["premium_progress_bar_enabled"] = premium_progress_bar_enabled