MM-62745: [Shared Channels] Fix duplicate mentioning - local user with the same username as someone on the remote server - Part2 (#32101) (#33414)

Automatic Merge
Этот коммит содержится в:
Mattermost Build
2025-07-14 19:28:42 +03:00
коммит произвёл GitHub
родитель b6e80b9f59
Коммит 7f4fbd803a
7 изменённых файлов: 394 добавлений и 24 удалений

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

@@ -197,7 +197,7 @@ func (scs *Service) processSyncMessage(c request.CTX, syncMsg *model.SyncMsg, rc
}
// add/update post
rpost, err := scs.upsertSyncPost(post, targetChannel, rc)
rpost, err := scs.upsertSyncPost(post, targetChannel, rc, syncMsg.MentionTransforms)
if err != nil {
syncResp.PostErrors = append(syncResp.PostErrors, post.Id)
scs.server.Log().Log(mlog.LvlSharedChannelServiceError, "Error upserting sync post",
@@ -454,7 +454,7 @@ func (scs *Service) updateSyncUser(rctx request.CTX, patch *model.UserPatch, use
return nil, fmt.Errorf("error updating sync user %s: %w", user.Id, err)
}
func (scs *Service) upsertSyncPost(post *model.Post, targetChannel *model.Channel, rc *model.RemoteCluster) (*model.Post, error) {
func (scs *Service) upsertSyncPost(post *model.Post, targetChannel *model.Channel, rc *model.RemoteCluster, mentionTransforms map[string]string) (*model.Post, error) {
var appErr *model.AppError
post.RemoteId = model.NewPointer(rc.RemoteId)
@@ -483,11 +483,14 @@ func (scs *Service) upsertSyncPost(post *model.Post, targetChannel *model.Channe
return nil, fmt.Errorf("post sync failed: %w", ErrRemoteIDMismatch)
}
scs.transformMentionsOnReceive(rctx, post, targetChannel, rc, mentionTransforms)
rpost, appErr = scs.app.CreatePost(rctx, post, targetChannel, model.CreatePostFlags{TriggerWebhooks: true, SetOnline: true})
if appErr == nil {
scs.server.Log().Log(mlog.LvlSharedChannelServiceDebug, "Created sync post",
mlog.String("post_id", post.Id),
mlog.String("channel_id", post.ChannelId))
mlog.String("channel_id", post.ChannelId),
)
}
} else if post.DeleteAt > 0 {
// delete post
@@ -499,6 +502,7 @@ func (scs *Service) upsertSyncPost(post *model.Post, targetChannel *model.Channe
)
}
} else if post.EditAt > rpost.EditAt || post.Message != rpost.Message || post.UpdateAt > rpost.UpdateAt || post.Metadata != nil {
scs.transformMentionsOnReceive(rctx, post, targetChannel, rc, mentionTransforms)
var priority *model.PostPriority
var acknowledgements []*model.PostAcknowledgement
@@ -741,3 +745,44 @@ func (scs *Service) upsertSyncAcknowledgement(acknowledgement *model.PostAcknowl
}
return savedAcknowledgement, retErr
}
// transformMentionsOnReceive transforms mentions in received posts using explicit mentionTransforms.
func (scs *Service) transformMentionsOnReceive(rctx request.CTX, post *model.Post, targetChannel *model.Channel, rc *model.RemoteCluster, mentionTransforms map[string]string) {
if post.Message == "" || len(mentionTransforms) == 0 {
return
}
// Process mentions directly using mentionTransforms - no need to re-parse with regex
for mention, userID := range mentionTransforms {
oldMention := "@" + mention
var newMention string
// Get the user to determine transformation type
if user, err := scs.server.GetStore().User().Get(context.Background(), userID); err == nil && user != nil {
// User exists in receiver's database
if strings.Contains(mention, ":") {
// Colon mention (e.g., "@admin:remote1") - always use the user's actual username
newMention = "@" + user.Username
} else {
// Simple mention (e.g., "@admin")
if user.GetRemoteID() == "" {
// This is a local user, keep as-is
newMention = "@" + mention
} else {
// This is a remote user that was synced, use their synced username
newMention = "@" + user.Username
}
}
} else {
// User doesn't exist in receiver's database
if strings.Contains(mention, ":") {
// Colon mention for unknown user - keep as-is
newMention = oldMention
} else {
// Simple mention for unknown user - add cluster suffix to indicate it's from remote
newMention = "@" + mention + ":" + rc.Name
}
}
post.Message = strings.ReplaceAll(post.Message, oldMention, newMention)
}
}