From 89ca64733036dcb1476a5e85c21c2aee24f168ed Mon Sep 17 00:00:00 2001 From: Miguel de la Cruz Date: Thu, 10 Apr 2025 15:23:38 +0200 Subject: [PATCH] Unshares a channel when uninviting the last remote (#30568) Co-authored-by: Miguel de la Cruz (aider) Co-authored-by: Mattermost Build --- .../services/sharedchannel/service_api.go | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/server/platform/services/sharedchannel/service_api.go b/server/platform/services/sharedchannel/service_api.go index 6e96a58bf0..bddbd9e36a 100644 --- a/server/platform/services/sharedchannel/service_api.go +++ b/server/platform/services/sharedchannel/service_api.go @@ -178,6 +178,28 @@ func (scs *Service) InviteRemoteToChannel(channelID, remoteID, userID string, sh return nil } +// unshareChannelIfNoActiveRemotes checks if there are any remaining +// non-deleted remotes for the channel and unshares the channel if +// there are none. Returns true if the channel was unshared. +func (scs *Service) unshareChannelIfNoActiveRemotes(channelID string) (bool, error) { + opts := model.SharedChannelRemoteFilterOpts{ChannelId: channelID} + remotes, err := scs.server.GetStore().SharedChannel().GetRemotes(0, 1, opts) + if err != nil { + return false, fmt.Errorf("failed to check remaining remotes: %w", err) + } + + // If no remotes remain, unshare the channel + if len(remotes) == 0 { + unshared, err := scs.UnshareChannel(channelID) + if err != nil { + return false, fmt.Errorf("failed to automatically unshare channel after removing last remote: %w", err) + } + return unshared, nil + } + + return false, nil +} + func (scs *Service) UninviteRemoteFromChannel(channelID, remoteID string) error { scr, err := scs.server.GetStore().SharedChannel().GetRemoteByIds(channelID, remoteID) if err != nil || scr.ChannelId != channelID || scr.DeleteAt != 0 { @@ -195,6 +217,16 @@ func (scs *Service) UninviteRemoteFromChannel(channelID, remoteID string) error return model.NewAppError("UninviteRemoteFromChannel", "api.command_share.could_not_uninvite.error", map[string]any{"RemoteId": remoteID, "Error": err.Error()}, "", code) } + + _, unshareErr := scs.unshareChannelIfNoActiveRemotes(channelID) + if unshareErr != nil { + // We don't want to fail the uninvite operation if the unshare fails + scs.server.Log().Error("Error during automatic unshare after uninvite", + mlog.String("channel_id", channelID), + mlog.Err(unshareErr), + ) + } + return nil }