MM-34549 shared channels; add users to channel that were already sync'd (#17361)
Fixes a bug and adds a feature for shared channels: - The Bug: when creating new shared channels, users that had already been sync'd via another channel were not added to the new channel's member list, since the users were not sync'd again. This PR sync's users per channel. - The Feature: support custom statuses
Этот коммит содержится в:
@@ -832,6 +832,7 @@ type AppIface interface {
|
||||
Notification() einterfaces.NotificationInterface
|
||||
NotificationsLog() *mlog.Logger
|
||||
NotifyAndSetWarnMetricAck(warnMetricId string, sender *model.User, forceAck bool, isBot bool) *model.AppError
|
||||
NotifySharedChannelUserUpdate(user *model.User)
|
||||
OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError
|
||||
OriginChecker() func(*http.Request) bool
|
||||
PatchChannel(channel *model.Channel, patch *model.ChannelPatch, userID string) (*model.Channel, *model.AppError)
|
||||
|
||||
@@ -11401,6 +11401,21 @@ func (a *OpenTracingAppLayer) NotifySessionsExpired() *model.AppError {
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) NotifySharedChannelUserUpdate(user *model.User) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.NotifySharedChannelUserUpdate")
|
||||
|
||||
a.ctx = newCtx
|
||||
a.app.Srv().Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
a.app.Srv().Store.SetContext(origCtx)
|
||||
a.ctx = origCtx
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
a.app.NotifySharedChannelUserUpdate(user)
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.OpenInteractiveDialog")
|
||||
|
||||
@@ -147,3 +147,9 @@ func (a *App) GetSharedChannelRemotesStatus(channelID string) ([]*model.SharedCh
|
||||
}
|
||||
return a.Srv().Store.SharedChannel().GetRemotesStatus(channelID)
|
||||
}
|
||||
|
||||
// SharedChannelUsers
|
||||
|
||||
func (a *App) NotifySharedChannelUserUpdate(user *model.User) {
|
||||
a.sendUpdatedUserEvent(*user)
|
||||
}
|
||||
|
||||
@@ -116,7 +116,11 @@ func (rp *RemoteProvider) doInvite(a *app.App, args *model.CommandArgs, margs ma
|
||||
if name == "" {
|
||||
return responsef(args.T("api.command_remote.missing_empty", map[string]interface{}{"Arg": "name"}))
|
||||
}
|
||||
|
||||
displayname := margs["displayname"]
|
||||
if displayname == "" {
|
||||
displayname = name
|
||||
}
|
||||
|
||||
url := a.GetSiteURL()
|
||||
if url == "" {
|
||||
@@ -163,7 +167,11 @@ func (rp *RemoteProvider) doAccept(a *app.App, args *model.CommandArgs, margs ma
|
||||
if name == "" {
|
||||
return responsef(args.T("api.command_remote.missing_empty", map[string]interface{}{"Arg": "name"}))
|
||||
}
|
||||
|
||||
displayname := margs["displayname"]
|
||||
if displayname == "" {
|
||||
displayname = name
|
||||
}
|
||||
|
||||
blob := margs["invite"]
|
||||
if blob == "" {
|
||||
|
||||
@@ -183,6 +183,7 @@ type SharedChannelRemoteStatus struct {
|
||||
type SharedChannelUser struct {
|
||||
Id string `json:"id"`
|
||||
UserId string `json:"user_id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
RemoteId string `json:"remote_id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
LastSyncAt int64 `json:"last_sync_at"`
|
||||
@@ -202,6 +203,10 @@ func (scu *SharedChannelUser) IsValid() *AppError {
|
||||
return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "UserId="+scu.UserId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidId(scu.ChannelId) {
|
||||
return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "ChannelId="+scu.ChannelId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if !IsValidId(scu.RemoteId) {
|
||||
return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "RemoteId="+scu.RemoteId, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -230,6 +230,11 @@ func (_m *MockAppIface) GetOrCreateDirectChannel(userId string, otherUserId stri
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// InvalidateCacheForUser provides a mock function with given fields: userID
|
||||
func (_m *MockAppIface) InvalidateCacheForUser(userID string) {
|
||||
_m.Called(userID)
|
||||
}
|
||||
|
||||
// MentionsToTeamMembers provides a mock function with given fields: message, teamID
|
||||
func (_m *MockAppIface) MentionsToTeamMembers(message string, teamID string) model.UserMentionMap {
|
||||
ret := _m.Called(message, teamID)
|
||||
@@ -246,6 +251,11 @@ func (_m *MockAppIface) MentionsToTeamMembers(message string, teamID string) mod
|
||||
return r0
|
||||
}
|
||||
|
||||
// NotifySharedChannelUserUpdate provides a mock function with given fields: user
|
||||
func (_m *MockAppIface) NotifySharedChannelUserUpdate(user *model.User) {
|
||||
_m.Called(user)
|
||||
}
|
||||
|
||||
// PatchChannelModerationsForChannel provides a mock function with given fields: channel, channelModerationsPatch
|
||||
func (_m *MockAppIface) PatchChannelModerationsForChannel(channel *model.Channel, channelModerationsPatch []*model.ChannelModerationPatch) ([]*model.ChannelModeration, *model.AppError) {
|
||||
ret := _m.Called(channel, channelModerationsPatch)
|
||||
|
||||
@@ -52,10 +52,10 @@ func (u userCache) Add(id string) {
|
||||
|
||||
// postsToSyncMessages takes a slice of posts and converts to a `RemoteClusterMsg` which can be
|
||||
// sent to a remote cluster.
|
||||
func (scs *Service) postsToSyncMessages(posts []*model.Post, rc *model.RemoteCluster, nextSyncAt int64) ([]syncMsg, error) {
|
||||
func (scs *Service) postsToSyncMessages(posts []*model.Post, channelID string, rc *model.RemoteCluster, nextSyncAt int64) ([]syncMsg, error) {
|
||||
syncMessages := make([]syncMsg, 0, len(posts))
|
||||
|
||||
var teamId string
|
||||
var teamID string
|
||||
uCache := make(userCache)
|
||||
|
||||
for _, p := range posts {
|
||||
@@ -64,7 +64,7 @@ func (scs *Service) postsToSyncMessages(posts []*model.Post, rc *model.RemoteClu
|
||||
}
|
||||
|
||||
// lookup team id once
|
||||
if teamId == "" {
|
||||
if teamID == "" {
|
||||
sc, err := scs.server.GetStore().SharedChannel().Get(p.ChannelId)
|
||||
if err != nil {
|
||||
scs.server.GetLogger().Log(mlog.LvlSharedChannelServiceError, "Could not get shared channel for post",
|
||||
@@ -73,7 +73,7 @@ func (scs *Service) postsToSyncMessages(posts []*model.Post, rc *model.RemoteClu
|
||||
)
|
||||
continue
|
||||
}
|
||||
teamId = sc.TeamId
|
||||
teamID = sc.TeamId
|
||||
}
|
||||
|
||||
// any reactions originating from the remote cluster are filtered out
|
||||
@@ -119,7 +119,7 @@ func (scs *Service) postsToSyncMessages(posts []*model.Post, rc *model.RemoteClu
|
||||
}
|
||||
|
||||
// any users originating from the remote cluster are filtered out
|
||||
users := scs.usersForPost(postSync, reactions, teamId, rc, uCache)
|
||||
users := scs.usersForPost(postSync, reactions, channelID, teamID, rc, uCache)
|
||||
|
||||
// if everything was filtered out then don't send an empty message.
|
||||
if postSync == nil && len(reactions) == 0 && len(users) == 0 {
|
||||
@@ -142,7 +142,7 @@ func (scs *Service) postsToSyncMessages(posts []*model.Post, rc *model.RemoteClu
|
||||
// usersForPost provides a list of Users associated with the post that need to be synchronized.
|
||||
// The user cache ensures the same user is not synchronized redundantly if they appear in multiple
|
||||
// posts for this sync batch.
|
||||
func (scs *Service) usersForPost(post *model.Post, reactions []*model.Reaction, teamID string, rc *model.RemoteCluster, uCache userCache) []*model.User {
|
||||
func (scs *Service) usersForPost(post *model.Post, reactions []*model.Reaction, channelID string, teamID string, rc *model.RemoteCluster, uCache userCache) []*model.User {
|
||||
userIds := make([]string, 0)
|
||||
var mentionMap model.UserMentionMap
|
||||
|
||||
@@ -178,7 +178,7 @@ func (scs *Service) usersForPost(post *model.Post, reactions []*model.Reaction,
|
||||
for _, id := range userIds {
|
||||
user, err := scs.server.GetStore().User().Get(context.Background(), id)
|
||||
if err == nil {
|
||||
if sync, err2 := scs.shouldUserSync(user, rc); err2 != nil {
|
||||
if sync, err2 := scs.shouldUserSync(user, channelID, rc); err2 != nil {
|
||||
scs.server.GetLogger().Log(mlog.LvlSharedChannelServiceError, "Could not find user for post",
|
||||
mlog.String("user_id", id),
|
||||
mlog.Err(err2),
|
||||
@@ -238,15 +238,15 @@ func sanitizeUserForSync(user *model.User) *model.User {
|
||||
}
|
||||
|
||||
// shouldUserSync determines if a user needs to be synchronized.
|
||||
// User should be synchronized if it has no entry in the SharedChannelUsers table,
|
||||
// User should be synchronized if it has no entry in the SharedChannelUsers table for the specified channel,
|
||||
// or there is an entry but the LastSyncAt is less than user.UpdateAt
|
||||
func (scs *Service) shouldUserSync(user *model.User, rc *model.RemoteCluster) (bool, error) {
|
||||
func (scs *Service) shouldUserSync(user *model.User, channelID string, rc *model.RemoteCluster) (bool, error) {
|
||||
// don't sync users with the remote they originated from.
|
||||
if user.RemoteId != nil && *user.RemoteId == rc.RemoteId {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
scu, err := scs.server.GetStore().SharedChannel().GetUser(user.Id, rc.RemoteId)
|
||||
scu, err := scs.server.GetStore().SharedChannel().GetUser(user.Id, channelID, rc.RemoteId)
|
||||
if err != nil {
|
||||
if _, ok := err.(errNotFound); !ok {
|
||||
return false, err
|
||||
@@ -254,13 +254,16 @@ func (scs *Service) shouldUserSync(user *model.User, rc *model.RemoteCluster) (b
|
||||
|
||||
// user not in the SharedChannelUsers table, so we must add them.
|
||||
scu = &model.SharedChannelUser{
|
||||
UserId: user.Id,
|
||||
RemoteId: rc.RemoteId,
|
||||
UserId: user.Id,
|
||||
RemoteId: rc.RemoteId,
|
||||
ChannelId: channelID,
|
||||
}
|
||||
if _, err = scs.server.GetStore().SharedChannel().SaveUser(scu); err != nil {
|
||||
scs.server.GetLogger().Log(mlog.LvlSharedChannelServiceError, "Error adding user to shared channel users",
|
||||
mlog.String("remote_id", rc.RemoteId),
|
||||
mlog.String("user_id", user.Id),
|
||||
mlog.String("channel_id", user.Id),
|
||||
mlog.Err(err),
|
||||
)
|
||||
}
|
||||
} else if scu.LastSyncAt >= user.UpdateAt {
|
||||
|
||||
@@ -57,6 +57,8 @@ type AppIface interface {
|
||||
CreateUploadSession(us *model.UploadSession) (*model.UploadSession, *model.AppError)
|
||||
FileReader(path string) (filestore.ReadCloseSeeker, *model.AppError)
|
||||
MentionsToTeamMembers(message, teamID string) model.UserMentionMap
|
||||
InvalidateCacheForUser(userID string)
|
||||
NotifySharedChannelUserUpdate(user *model.User)
|
||||
}
|
||||
|
||||
// errNotFound allows checking against Store.ErrNotFound errors without making Store a dependency.
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/services/remotecluster"
|
||||
@@ -194,6 +195,7 @@ func (scs *Service) upsertSyncUser(user *model.User, channel *model.Channel, rc
|
||||
FirstName: &user.FirstName,
|
||||
LastName: &user.LastName,
|
||||
Email: &user.Email,
|
||||
Props: user.Props,
|
||||
Position: &user.Position,
|
||||
Locale: &user.Locale,
|
||||
Timezone: user.Timezone,
|
||||
@@ -226,7 +228,7 @@ func (scs *Service) insertSyncUser(user *model.User, channel *model.Channel, rc
|
||||
var userSaved *model.User
|
||||
var suffix string
|
||||
|
||||
// save the originals in props (if not already done by another remote)
|
||||
// save the original username and email in props (if not already done by another remote)
|
||||
if _, ok := user.GetProp(KeyRemoteUsername); !ok {
|
||||
user.SetProp(KeyRemoteUsername, user.Username)
|
||||
}
|
||||
@@ -262,6 +264,7 @@ func (scs *Service) insertSyncUser(user *model.User, channel *model.Channel, rc
|
||||
)
|
||||
}
|
||||
} else {
|
||||
scs.app.NotifySharedChannelUserUpdate(userSaved)
|
||||
return userSaved, nil
|
||||
}
|
||||
}
|
||||
@@ -273,14 +276,22 @@ func (scs *Service) updateSyncUser(patch *model.UserPatch, user *model.User, cha
|
||||
var update *model.UserUpdate
|
||||
var suffix string
|
||||
|
||||
if patch.Username != nil {
|
||||
user.SetProp(KeyRemoteUsername, *patch.Username)
|
||||
// preserve existing real username/email since Patch will over-write them;
|
||||
// the real username/email in props can be updated if they don't contain colons,
|
||||
// meaning the update is coming from the user's origin server (not munged).
|
||||
realUsername, _ := user.GetProp(KeyRemoteUsername)
|
||||
realEmail, _ := user.GetProp(KeyRemoteEmail)
|
||||
|
||||
if patch.Username != nil && !strings.Contains(*patch.Username, ":") {
|
||||
realUsername = *patch.Username
|
||||
}
|
||||
if patch.Email != nil {
|
||||
user.SetProp(KeyRemoteEmail, *patch.Email)
|
||||
if patch.Email != nil && !strings.Contains(*patch.Email, ":") {
|
||||
realEmail = *patch.Email
|
||||
}
|
||||
|
||||
user.Patch(patch)
|
||||
user.SetProp(KeyRemoteUsername, realUsername)
|
||||
user.SetProp(KeyRemoteEmail, realEmail)
|
||||
|
||||
// Apply a suffix to the username until it is unique.
|
||||
for i := 1; i <= MaxUpsertRetries; i++ {
|
||||
@@ -306,6 +317,8 @@ func (scs *Service) updateSyncUser(patch *model.UserPatch, user *model.User, cha
|
||||
)
|
||||
}
|
||||
} else {
|
||||
scs.app.InvalidateCacheForUser(update.New.Id)
|
||||
scs.app.NotifySharedChannelUserUpdate(update.New)
|
||||
return update.New, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ func (scs *Service) updateForRemote(task syncTask, rc *model.RemoteCluster) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
syncMessages, err := scs.postsToSyncMessages(posts, rc, scr.NextSyncAt)
|
||||
syncMessages, err := scs.postsToSyncMessages(posts, task.channelId, rc, scr.NextSyncAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -365,7 +365,7 @@ func (scs *Service) updateForRemote(task syncTask, rc *model.RemoteCluster) erro
|
||||
}
|
||||
|
||||
// update NextSyncAt for all the users that were synchronized
|
||||
scs.updateSyncUsers(syncResp.UsersSyncd, rc, nextSince)
|
||||
scs.updateSyncUsers(syncResp.UsersSyncd, task.channelId, rc, nextSince)
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
@@ -470,9 +470,9 @@ func (scs *Service) updateNextSyncForRemote(scrId string, rc *model.RemoteCluste
|
||||
)
|
||||
}
|
||||
|
||||
func (scs *Service) updateSyncUsers(userIds []string, rc *model.RemoteCluster, lastSyncAt int64) {
|
||||
func (scs *Service) updateSyncUsers(userIds []string, channelID string, rc *model.RemoteCluster, lastSyncAt int64) {
|
||||
for _, uid := range userIds {
|
||||
scu, err := scs.server.GetStore().SharedChannel().GetUser(uid, rc.RemoteId)
|
||||
scu, err := scs.server.GetStore().SharedChannel().GetUser(uid, channelID, rc.RemoteId)
|
||||
if err != nil {
|
||||
scs.server.GetLogger().Log(mlog.LvlSharedChannelServiceError, "error getting user for lastSyncAt update",
|
||||
mlog.String("remote", rc.DisplayName),
|
||||
@@ -486,12 +486,14 @@ func (scs *Service) updateSyncUsers(userIds []string, rc *model.RemoteCluster, l
|
||||
scs.server.GetLogger().Log(mlog.LvlSharedChannelServiceError, "error updating lastSyncAt for user",
|
||||
mlog.String("remote", rc.DisplayName),
|
||||
mlog.String("user_id", uid),
|
||||
mlog.String("channel_id", channelID),
|
||||
mlog.Err(err),
|
||||
)
|
||||
} else {
|
||||
scs.server.GetLogger().Log(mlog.LvlSharedChannelServiceDebug, "updated lastSyncAt for user",
|
||||
mlog.String("remote", rc.DisplayName),
|
||||
mlog.String("user_id", scu.UserId),
|
||||
mlog.String("channel_id", channelID),
|
||||
mlog.Int64("last_update_at", lastSyncAt),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6904,7 +6904,7 @@ func (s *OpenTracingLayerSharedChannelStore) GetRemotesStatus(channelId string)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSharedChannelStore) GetUser(userId string, remoteId string) (*model.SharedChannelUser, error) {
|
||||
func (s *OpenTracingLayerSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.GetUser")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -6913,7 +6913,7 @@ func (s *OpenTracingLayerSharedChannelStore) GetUser(userId string, remoteId str
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.SharedChannelStore.GetUser(userId, remoteId)
|
||||
result, err := s.SharedChannelStore.GetUser(userID, channelID, remoteID)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
|
||||
@@ -7486,11 +7486,11 @@ func (s *RetryLayerSharedChannelStore) GetRemotesStatus(channelId string) ([]*mo
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSharedChannelStore) GetUser(userId string, remoteId string) (*model.SharedChannelUser, error) {
|
||||
func (s *RetryLayerSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.SharedChannelStore.GetUser(userId, remoteId)
|
||||
result, err := s.SharedChannelStore.GetUser(userID, channelID, remoteID)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ func newSqlSharedChannelStore(sqlStore *SqlStore) store.SharedChannelStore {
|
||||
tableSharedChannelUsers.ColMap("Id").SetMaxSize(26)
|
||||
tableSharedChannelUsers.ColMap("UserId").SetMaxSize(26)
|
||||
tableSharedChannelUsers.ColMap("RemoteId").SetMaxSize(26)
|
||||
tableSharedChannelUsers.SetUniqueTogether("UserId", "RemoteId")
|
||||
tableSharedChannelUsers.ColMap("ChannelId").SetMaxSize(26)
|
||||
tableSharedChannelUsers.SetUniqueTogether("UserId", "ChannelId", "RemoteId")
|
||||
|
||||
tableSharedChannelFiles := db.AddTableWithName(model.SharedChannelAttachment{}, "SharedChannelAttachments").SetKeys(false, "Id")
|
||||
tableSharedChannelFiles.ColMap("Id").SetMaxSize(26)
|
||||
@@ -557,14 +558,15 @@ func (s SqlSharedChannelStore) SaveUser(scUser *model.SharedChannelUser) (*model
|
||||
}
|
||||
|
||||
// GetUser fetches a shared channel user based on user_id and remoteId.
|
||||
func (s SqlSharedChannelStore) GetUser(userId string, remoteId string) (*model.SharedChannelUser, error) {
|
||||
func (s SqlSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
var scu model.SharedChannelUser
|
||||
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
Select("*").
|
||||
From("SharedChannelUsers").
|
||||
Where(sq.Eq{"SharedChannelUsers.UserId": userId}).
|
||||
Where(sq.Eq{"SharedChannelUsers.RemoteId": remoteId}).
|
||||
Where(sq.Eq{"SharedChannelUsers.UserId": userID}).
|
||||
Where(sq.Eq{"SharedChannelUsers.RemoteId": remoteID}).
|
||||
Where(sq.Eq{"SharedChannelUsers.ChannelId": channelID}).
|
||||
ToSql()
|
||||
|
||||
if err != nil {
|
||||
@@ -573,9 +575,9 @@ func (s SqlSharedChannelStore) GetUser(userId string, remoteId string) (*model.S
|
||||
|
||||
if err := s.GetReplica().SelectOne(&scu, squery, args...); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, store.NewErrNotFound("SharedChannelUser", userId)
|
||||
return nil, store.NewErrNotFound("SharedChannelUser", userID)
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to find shared channel user with UserId=%s, RemoteId=%s", userId, remoteId)
|
||||
return nil, errors.Wrapf(err, "failed to find shared channel user with UserId=%s, ChannelId=%s, RemoteId=%s", userID, channelID, remoteID)
|
||||
}
|
||||
return &scu, nil
|
||||
}
|
||||
|
||||
@@ -1030,6 +1030,7 @@ func upgradeDatabaseToVersion535(sqlStore *SqlStore) {
|
||||
uniquenessColumns = []string{"RemoteTeamId", "SiteUrl(168)"}
|
||||
}
|
||||
sqlStore.CreateUniqueCompositeIndexIfNotExists(RemoteClusterSiteURLUniqueIndex, "RemoteClusters", uniquenessColumns)
|
||||
sqlStore.CreateColumnIfNotExists("SharedChannelUsers", "ChannelId", "VARCHAR(26)", "VARCHAR(26)", "")
|
||||
|
||||
// note: setting default 0 on pre-5.0 tables causes test-db-migration script to fail, so this column will be added to ignore list
|
||||
sqlStore.CreateColumnIfNotExists("ChannelMembers", "MentionCountRoot", "bigint", "bigint", "0")
|
||||
|
||||
@@ -828,7 +828,7 @@ type SharedChannelStore interface {
|
||||
GetRemotesStatus(channelId string) ([]*model.SharedChannelRemoteStatus, error)
|
||||
|
||||
SaveUser(remote *model.SharedChannelUser) (*model.SharedChannelUser, error)
|
||||
GetUser(userId string, remoteId string) (*model.SharedChannelUser, error)
|
||||
GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error)
|
||||
UpdateUserLastSyncAt(id string, syncTime int64) error
|
||||
|
||||
SaveAttachment(remote *model.SharedChannelAttachment) (*model.SharedChannelAttachment, error)
|
||||
|
||||
@@ -261,13 +261,13 @@ func (_m *SharedChannelStore) GetRemotesStatus(channelId string) ([]*model.Share
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUser provides a mock function with given fields: userId, remoteId
|
||||
func (_m *SharedChannelStore) GetUser(userId string, remoteId string) (*model.SharedChannelUser, error) {
|
||||
ret := _m.Called(userId, remoteId)
|
||||
// GetUser provides a mock function with given fields: userID, channelID, remoteID
|
||||
func (_m *SharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
ret := _m.Called(userID, channelID, remoteID)
|
||||
|
||||
var r0 *model.SharedChannelUser
|
||||
if rf, ok := ret.Get(0).(func(string, string) *model.SharedChannelUser); ok {
|
||||
r0 = rf(userId, remoteId)
|
||||
if rf, ok := ret.Get(0).(func(string, string, string) *model.SharedChannelUser); ok {
|
||||
r0 = rf(userID, channelID, remoteID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.SharedChannelUser)
|
||||
@@ -275,8 +275,8 @@ func (_m *SharedChannelStore) GetUser(userId string, remoteId string) (*model.Sh
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(userId, remoteId)
|
||||
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
|
||||
r1 = rf(userID, channelID, remoteID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func testRemoteClusterSave(t *testing.T, ss store.Store) {
|
||||
|
||||
rcSaved, err := ss.RemoteCluster().Save(rc)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, rc.DisplayName, rcSaved.DisplayName)
|
||||
require.Equal(t, rc.Name, rcSaved.Name)
|
||||
require.Equal(t, rc.SiteURL, rcSaved.SiteURL)
|
||||
require.Greater(t, rc.CreateAt, int64(0))
|
||||
require.Equal(t, rc.LastPingAt, int64(0))
|
||||
@@ -53,7 +53,7 @@ func testRemoteClusterSave(t *testing.T, ss store.Store) {
|
||||
|
||||
t.Run("Save missing creator id", func(t *testing.T) {
|
||||
rc := &model.RemoteCluster{
|
||||
Name: "some_remote 2",
|
||||
Name: "some_remote_2",
|
||||
SiteURL: "somewhere.com",
|
||||
}
|
||||
_, err := ss.RemoteCluster().Save(rc)
|
||||
|
||||
@@ -843,8 +843,9 @@ func clearSharedChannels(ss store.Store) error {
|
||||
func testSaveSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
t.Run("Save shared channel user", func(t *testing.T) {
|
||||
scUser := &model.SharedChannelUser{
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
ChannelId: model.NewId(),
|
||||
}
|
||||
|
||||
userSaved, err := ss.SharedChannel().SaveUser(scUser)
|
||||
@@ -877,15 +878,16 @@ func testSaveSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
|
||||
func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
scUser := &model.SharedChannelUser{
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
ChannelId: model.NewId(),
|
||||
}
|
||||
|
||||
userSaved, err := ss.SharedChannel().SaveUser(scUser)
|
||||
require.NoError(t, err, "could not save user", err)
|
||||
|
||||
t.Run("Get existing shared channel user", func(t *testing.T) {
|
||||
r, err := ss.SharedChannel().GetUser(userSaved.UserId, userSaved.RemoteId)
|
||||
r, err := ss.SharedChannel().GetUser(userSaved.UserId, userSaved.ChannelId, userSaved.RemoteId)
|
||||
require.NoError(t, err, "couldn't get shared channel user", err)
|
||||
|
||||
require.Equal(t, userSaved.Id, r.Id)
|
||||
@@ -895,7 +897,7 @@ func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("Get non-existent shared channel user", func(t *testing.T) {
|
||||
u, err := ss.SharedChannel().GetUser(model.NewId(), model.NewId())
|
||||
u, err := ss.SharedChannel().GetUser(model.NewId(), model.NewId(), model.NewId())
|
||||
require.Error(t, err)
|
||||
require.Nil(t, u)
|
||||
})
|
||||
@@ -903,8 +905,9 @@ func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
|
||||
func testUpdateSharedChannelUserLastSyncAt(t *testing.T, ss store.Store) {
|
||||
scUser := &model.SharedChannelUser{
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
ChannelId: model.NewId(),
|
||||
}
|
||||
|
||||
userSaved, err := ss.SharedChannel().SaveUser(scUser)
|
||||
@@ -916,7 +919,7 @@ func testUpdateSharedChannelUserLastSyncAt(t *testing.T, ss store.Store) {
|
||||
err := ss.SharedChannel().UpdateUserLastSyncAt(userSaved.Id, future)
|
||||
require.NoError(t, err, "updateLastSyncAt should not error", err)
|
||||
|
||||
u, err := ss.SharedChannel().GetUser(userSaved.UserId, userSaved.RemoteId)
|
||||
u, err := ss.SharedChannel().GetUser(userSaved.UserId, userSaved.ChannelId, userSaved.RemoteId)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, future, u.LastSyncAt)
|
||||
})
|
||||
|
||||
@@ -6238,10 +6238,10 @@ func (s *TimerLayerSharedChannelStore) GetRemotesStatus(channelId string) ([]*mo
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSharedChannelStore) GetUser(userId string, remoteId string) (*model.SharedChannelUser, error) {
|
||||
func (s *TimerLayerSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.SharedChannelStore.GetUser(userId, remoteId)
|
||||
result, err := s.SharedChannelStore.GetUser(userID, channelID, remoteID)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
|
||||
Ссылка в новой задаче
Block a user