MM-64531: [Shared Channels] Users on different remote servers should not communicate unless the remotes have established secure connection. (#30985) (#33434)

Automatic Merge
Этот коммит содержится в:
Mattermost Build
2025-07-15 11:58:41 +03:00
коммит произвёл GitHub
родитель 3a6aeee57e
Коммит 07a34f02b6
20 изменённых файлов: 764 добавлений и 59 удалений

Просмотреть файл

@@ -28,6 +28,7 @@ type SharedChannelServiceIFace interface {
CheckChannelIsShared(channelID string) error
CheckCanInviteToSharedChannel(channelId string) error
HandleMembershipChange(channelID, userID string, isAdd bool, remoteID string)
IsRemoteClusterDirectlyConnected(remoteId string) bool
TransformMentionsOnReceiveForTesting(ctx request.CTX, post *model.Post, targetChannel *model.Channel, rc *model.RemoteCluster, mentionTransforms map[string]string)
}
@@ -100,3 +101,11 @@ func (mrcs *mockSharedChannelService) HandleMembershipChange(channelID, userID s
mrcs.SharedChannelServiceIFace.HandleMembershipChange(channelID, userID, isAdd, remoteID)
}
}
func (mrcs *mockSharedChannelService) IsRemoteClusterDirectlyConnected(remoteId string) bool {
if mrcs.SharedChannelServiceIFace != nil {
return mrcs.SharedChannelServiceIFace.IsRemoteClusterDirectlyConnected(remoteId)
}
// Default behavior for mock: Local server is always connected
return remoteId == ""
}

Просмотреть файл

@@ -9,6 +9,7 @@ import (
"database/sql"
"encoding/json"
"errors"
"os"
"path/filepath"
"strings"
"testing"
@@ -26,6 +27,7 @@ import (
"github.com/mattermost/mattermost/server/v8/channels/utils/testutils"
"github.com/mattermost/mattermost/server/v8/einterfaces"
"github.com/mattermost/mattermost/server/v8/einterfaces/mocks"
"github.com/mattermost/mattermost/server/v8/platform/services/sharedchannel"
)
func TestCreateOAuthUser(t *testing.T) {
@@ -2411,3 +2413,74 @@ func TestGetUsersForReporting(t *testing.T) {
require.NotNil(t, userReports)
})
}
// Helper functions for remote user testing
func setupRemoteClusterTest(t *testing.T) (*TestHelper, store.Store) {
os.Setenv("MM_FEATUREFLAGS_ENABLESHAREDCHANNELSDMS", "true")
t.Cleanup(func() { os.Unsetenv("MM_FEATUREFLAGS_ENABLESHAREDCHANNELSDMS") })
th := setupSharedChannels(t).InitBasic()
t.Cleanup(th.TearDown)
return th, th.App.Srv().Store()
}
func createTestRemoteCluster(t *testing.T, th *TestHelper, ss store.Store, name, siteURL string, confirmed bool) *model.RemoteCluster {
cluster := &model.RemoteCluster{
RemoteId: model.NewId(),
Name: name,
SiteURL: siteURL,
CreateAt: model.GetMillis(),
LastPingAt: model.GetMillis(),
Token: model.NewId(),
CreatorId: th.BasicUser.Id,
}
if confirmed {
cluster.RemoteToken = model.NewId()
}
savedCluster, err := ss.RemoteCluster().Save(cluster)
require.NoError(t, err)
return savedCluster
}
func createRemoteUser(t *testing.T, th *TestHelper, remoteCluster *model.RemoteCluster) *model.User {
user := th.CreateUser()
user.RemoteId = &remoteCluster.RemoteId
updatedUser, appErr := th.App.UpdateUser(th.Context, user, false)
require.Nil(t, appErr)
return updatedUser
}
func ensureRemoteClusterConnected(t *testing.T, ss store.Store, cluster *model.RemoteCluster, connected bool) {
if connected {
cluster.SiteURL = "https://example.com"
cluster.RemoteToken = model.NewId()
cluster.LastPingAt = model.GetMillis()
} else {
cluster.SiteURL = model.SiteURLPending + "example.com"
cluster.RemoteToken = ""
}
_, err := ss.RemoteCluster().Update(cluster)
require.NoError(t, err)
}
// TestRemoteUserDirectChannelCreation tests direct channel creation with remote users
func TestRemoteUserDirectChannelCreation(t *testing.T) {
th, ss := setupRemoteClusterTest(t)
connectedRC := createTestRemoteCluster(t, th, ss, "connected-cluster", "https://example-connected.com", true)
user1 := createRemoteUser(t, th, connectedRC)
t.Run("Can create DM with user from connected remote", func(t *testing.T) {
ensureRemoteClusterConnected(t, ss, connectedRC, true)
scs := th.App.Srv().GetSharedChannelSyncService()
service, ok := scs.(*sharedchannel.Service)
require.True(t, ok)
require.True(t, service.IsRemoteClusterDirectlyConnected(connectedRC.RemoteId))
channel, appErr := th.App.GetOrCreateDirectChannel(th.Context, th.BasicUser.Id, user1.Id)
assert.NotNil(t, channel)
assert.Nil(t, appErr)
assert.Equal(t, model.ChannelTypeDirect, channel.Type)
})
}