From cb03009992d1516b6f719f1b79536a7383173d8c Mon Sep 17 00:00:00 2001 From: Miguel de la Cruz Date: Thu, 24 Oct 2024 19:38:00 +0200 Subject: [PATCH] Adds a feature flag to control availability of DMs in shared channels (#28920) * Adds a feature flag to control availability of DMs in shared channels * Reverse feature flag wording --- server/channels/app/channel.go | 10 ++++++---- server/channels/app/post.go | 2 +- server/platform/services/sharedchannel/service_api.go | 2 +- server/public/model/feature_flags.go | 4 ++++ .../advanced_text_editor/advanced_text_editor.tsx | 9 +++++---- webapp/channels/src/i18n/en.json | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/server/channels/app/channel.go b/server/channels/app/channel.go index a254748e84..a724d7c5ef 100644 --- a/server/channels/app/channel.go +++ b/server/channels/app/channel.go @@ -424,7 +424,7 @@ func (a *App) createDirectChannel(c request.CTX, userID string, otherUserID stri } func (a *App) createDirectChannelWithUser(c request.CTX, user, otherUser *model.User, channelOptions ...model.ChannelOption) (*model.Channel, *model.AppError) { - if user.IsRemote() || otherUser.IsRemote() { + if !a.Config().FeatureFlags.EnableSharedChannelsDMs && (user.IsRemote() || otherUser.IsRemote()) { return nil, model.NewAppError("createDirectChannelWithUser", "api.channel.create_channel.direct_channel.remote_restricted.app_error", nil, "", http.StatusForbidden) } @@ -528,9 +528,11 @@ func (a *App) createGroupChannel(c request.CTX, userIDs []string) (*model.Channe return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJSON(userIDs), http.StatusBadRequest) } - for _, user := range users { - if user.IsRemote() { - return nil, model.NewAppError("createGroupChannel", "api.channel.create_group.remote_restricted.app_error", nil, "", http.StatusForbidden) + if !a.Config().FeatureFlags.EnableSharedChannelsDMs { + for _, user := range users { + if user.IsRemote() { + return nil, model.NewAppError("createGroupChannel", "api.channel.create_group.remote_restricted.app_error", nil, "", http.StatusForbidden) + } } } diff --git a/server/channels/app/post.go b/server/channels/app/post.go index c5272b839c..7eae544cb0 100644 --- a/server/channels/app/post.go +++ b/server/channels/app/post.go @@ -141,7 +141,7 @@ func (a *App) deduplicateCreatePost(rctx request.CTX, post *model.Post) (foundPo } func (a *App) CreatePost(c request.CTX, post *model.Post, channel *model.Channel, flags model.CreatePostFlags) (savedPost *model.Post, err *model.AppError) { - if channel.IsShared() && (channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup) { + if !a.Config().FeatureFlags.EnableSharedChannelsDMs && channel.IsShared() && (channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup) { return nil, model.NewAppError("CreatePost", "app.post.create_post.shared_dm_or_gm.app_error", nil, "", http.StatusBadRequest) } diff --git a/server/platform/services/sharedchannel/service_api.go b/server/platform/services/sharedchannel/service_api.go index 3fbc0a8148..6e96a58bf0 100644 --- a/server/platform/services/sharedchannel/service_api.go +++ b/server/platform/services/sharedchannel/service_api.go @@ -22,7 +22,7 @@ func (scs *Service) ShareChannel(sc *model.SharedChannel) (*model.SharedChannel, return nil, fmt.Errorf("cannot fetch channel while sharing channel %s: %w", sc.ChannelId, err) } - if channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup { + if !scs.server.Config().FeatureFlags.EnableSharedChannelsDMs && (channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup) { return nil, errors.New("cannot share a direct or group channel") } diff --git a/server/public/model/feature_flags.go b/server/public/model/feature_flags.go index 6651bd499d..2a00b2b0c5 100644 --- a/server/public/model/feature_flags.go +++ b/server/public/model/feature_flags.go @@ -19,6 +19,9 @@ type FeatureFlags struct { // Enable the remote cluster service for shared channels. EnableRemoteClusterService bool + // Enable DMs and GMs for shared channels. + EnableSharedChannelsDMs bool + // AppsEnabled toggles the Apps framework functionalities both in server and client side AppsEnabled bool @@ -58,6 +61,7 @@ func (f *FeatureFlags) SetDefaults() { f.TestFeature = "off" f.TestBoolFeature = false f.EnableRemoteClusterService = false + f.EnableSharedChannelsDMs = false f.AppsEnabled = false f.NormalizeLdapDNs = false f.DeprecateCloudFree = false diff --git a/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx b/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx index fb042d5149..24f01665a9 100644 --- a/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx +++ b/webapp/channels/src/components/advanced_text_editor/advanced_text_editor.tsx @@ -11,7 +11,7 @@ import type {ServerError} from '@mattermost/types/errors'; import {savePreferences} from 'mattermost-redux/actions/preferences'; import {Permissions} from 'mattermost-redux/constants'; import {getChannel, makeGetChannel, getDirectChannel} from 'mattermost-redux/selectors/entities/channels'; -import {getConfig} from 'mattermost-redux/selectors/entities/general'; +import {getConfig, getFeatureFlagValue} from 'mattermost-redux/selectors/entities/general'; import {get, getBool, getInt} from 'mattermost-redux/selectors/entities/preferences'; import {haveIChannelPermission} from 'mattermost-redux/selectors/entities/roles'; import {getCurrentUserId, isCurrentUserGuestUser, getStatusForUserId, makeGetDisplayName} from 'mattermost-redux/selectors/entities/users'; @@ -168,8 +168,9 @@ const AdvancedTextEditor = ({ const readOnlyChannel = !canPost; const hasDraftMessage = Boolean(draft.message); + const enableSharedChannelsDMs = useSelector((state: GlobalState) => getFeatureFlagValue(state, 'EnableSharedChannelsDMs') === 'true'); const isDMOrGMRemote = isChannelShared && (channelType === Constants.DM_CHANNEL || channelType === Constants.GM_CHANNEL); - const isDisabled = Boolean(readOnlyChannel || isDMOrGMRemote); + const isDisabled = Boolean(readOnlyChannel || (!enableSharedChannelsDMs && isDMOrGMRemote)); const handleShowPreview = useCallback(() => { setShowPreview((prev) => !prev); @@ -484,11 +485,11 @@ const AdvancedTextEditor = ({ defaultMessage: 'This channel is read-only. Only members with permission can post here.', }, ); - } else if (isDMOrGMRemote) { + } else if (!enableSharedChannelsDMs && isDMOrGMRemote) { createMessage = formatMessage( { id: 'create_post.dm_or_gm_remote', - defaultMessage: 'Direct Messagess and Group Messages with remote users are not supported.', + defaultMessage: 'Direct Messages and Group Messages with remote users are not supported.', }, ); } else { diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 6d7fff1559..6e4f83dc22 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -3437,7 +3437,7 @@ "create_group_memberships_modal.create": "Yes", "create_group_memberships_modal.desc": "You're about to add or re-add {username} to teams and channels based on their LDAP group membership. You can revert this change at any time.", "create_group_memberships_modal.title": "Re-add {username} to teams and channels", - "create_post.dm_or_gm_remote": "Direct Messagess and Group Messages with remote users are not supported.", + "create_post.dm_or_gm_remote": "Direct Messages and Group Messages with remote users are not supported.", "create_post.error_message": "Your message is too long. Character count: {length}/{limit}", "create_post.file_limit_sticky_banner.admin_message": "New uploads will automatically archive older files. To view them again, you can delete older files or upgrade to a paid plan.", "create_post.file_limit_sticky_banner.messageTitle": "Your free plan is limited to {storageGB} of files.",