From b9d00a1f286891ff6678b2bf9960ae8fc6a1a9d3 Mon Sep 17 00:00:00 2001 From: Shota Gvinepadze Date: Wed, 9 Nov 2022 12:16:20 +0400 Subject: [PATCH 01/32] Simplify thread_store/GetThreadForUser (#21588) --- api4/post_test.go | 2 +- api4/user.go | 2 +- app/app_iface.go | 2 +- app/channel.go | 2 +- app/channel_test.go | 2 +- app/notification.go | 2 +- app/notification_test.go | 2 +- app/opentracing/opentracing_layer.go | 4 ++-- app/post_test.go | 6 +++--- app/user.go | 8 ++++---- store/opentracinglayer/opentracinglayer.go | 4 ++-- store/retrylayer/retrylayer.go | 4 ++-- store/sqlstore/thread_store.go | 9 ++------- store/store.go | 2 +- store/storetest/mocks/ThreadStore.go | 14 +++++++------- store/storetest/thread_store.go | 8 ++++---- store/timerlayer/timerlayer.go | 4 ++-- 17 files changed, 36 insertions(+), 41 deletions(-) diff --git a/api4/post_test.go b/api4/post_test.go index 8eeffa58a8..86b064191e 100644 --- a/api4/post_test.go +++ b/api4/post_test.go @@ -3033,7 +3033,7 @@ func TestSetPostUnreadWithoutCollapsedThreads(t *testing.T) { threadMembership, appErr := th.App.GetThreadMembershipForUser(th.BasicUser.Id, rootPost1.Id) require.Nil(t, appErr) - thread, appErr := th.App.GetThreadForUser(th.BasicTeam.Id, threadMembership, false) + thread, appErr := th.App.GetThreadForUser(threadMembership, false) require.Nil(t, appErr) require.Equal(t, int64(2), thread.UnreadMentions) require.Equal(t, int64(3), thread.UnreadReplies) diff --git a/api4/user.go b/api4/user.go index 4b182c6433..439660e991 100644 --- a/api4/user.go +++ b/api4/user.go @@ -3029,7 +3029,7 @@ func getThreadForUser(c *Context, w http.ResponseWriter, r *http.Request) { return } - thread, err := c.App.GetThreadForUser(c.Params.TeamId, threadMembership, extended) + thread, err := c.App.GetThreadForUser(threadMembership, extended) if err != nil { c.Err = err return diff --git a/app/app_iface.go b/app/app_iface.go index e1f1ef3795..371b9374b1 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -787,7 +787,7 @@ type AppIface interface { GetTeamsUnreadForUser(excludeTeamId string, userID string, includeCollapsedThreads bool) ([]*model.TeamUnread, *model.AppError) GetTeamsUsage() (*model.TeamsUsage, *model.AppError) GetTermsOfService(id string) (*model.TermsOfService, *model.AppError) - GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, *model.AppError) + GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, *model.AppError) GetThreadMembershipForUser(userId, threadId string) (*model.ThreadMembership, *model.AppError) GetThreadMembershipsForUser(userID, teamID string) ([]*model.ThreadMembership, error) GetThreadsForUser(userID, teamID string, options model.GetUserThreadsOpts) (*model.Threads, *model.AppError) diff --git a/app/channel.go b/app/channel.go index 164a7e4176..6bbe699fb0 100644 --- a/app/channel.go +++ b/app/channel.go @@ -2709,7 +2709,7 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st if mErr != nil { return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr) } - thread, mErr := a.Srv().Store().Thread().GetThreadForUser(channel.TeamId, threadMembership, true) + thread, mErr := a.Srv().Store().Thread().GetThreadForUser(threadMembership, true) if mErr != nil { return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr) } diff --git a/app/channel_test.go b/app/channel_test.go index 0361122027..bf21274763 100644 --- a/app/channel_test.go +++ b/app/channel_test.go @@ -2263,7 +2263,7 @@ func TestMarkChannelAsUnreadFromPostCollapsedThreadsTurnedOff(t *testing.T) { threadMembership, err := th.App.GetThreadMembershipForUser(th.BasicUser.Id, rootPost1.Id) require.Nil(t, err) - thread, err := th.App.GetThreadForUser(th.BasicTeam.Id, threadMembership, false) + thread, err := th.App.GetThreadForUser(threadMembership, false) require.Nil(t, err) require.Equal(t, int64(2), thread.UnreadMentions) require.Equal(t, int64(3), thread.UnreadReplies) diff --git a/app/notification.go b/app/notification.go index c5d36e14b8..99c1a9a9bb 100644 --- a/app/notification.go +++ b/app/notification.go @@ -596,7 +596,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea } threadMembership = tm } - userThread, err := a.Srv().Store().Thread().GetThreadForUser(channel.TeamId, threadMembership, true) + userThread, err := a.Srv().Store().Thread().GetThreadForUser(threadMembership, true) if err != nil { return nil, errors.Wrapf(err, "cannot get thread %q for user %q", post.RootId, uid) } diff --git a/app/notification_test.go b/app/notification_test.go index 26903e3e48..1563be191d 100644 --- a/app/notification_test.go +++ b/app/notification_test.go @@ -2769,7 +2769,7 @@ func TestReplyPostNotificationsWithCRT(t *testing.T) { threadMembership, appErr := th.App.GetThreadMembershipForUser(u2.Id, rpost.Id) require.Nil(t, appErr) - thread, appErr := th.App.GetThreadForUser(c1.TeamId, threadMembership, false) + thread, appErr := th.App.GetThreadForUser(threadMembership, false) require.Nil(t, appErr) // Then: with notifications set to "all" we should // not see a mention badge diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index 7dd996acad..0a2f216e89 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -9799,7 +9799,7 @@ func (a *OpenTracingAppLayer) GetTermsOfService(id string) (*model.TermsOfServic return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, *model.AppError) { +func (a *OpenTracingAppLayer) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetThreadForUser") @@ -9811,7 +9811,7 @@ func (a *OpenTracingAppLayer) GetThreadForUser(teamID string, threadMembership * }() defer span.Finish() - resultVar0, resultVar1 := a.app.GetThreadForUser(teamID, threadMembership, extended) + resultVar0, resultVar1 := a.app.GetThreadForUser(threadMembership, extended) if resultVar1 != nil { span.LogFields(spanlog.Error(resultVar1)) diff --git a/app/post_test.go b/app/post_test.go index 96ca119187..2ed0092a6c 100644 --- a/app/post_test.go +++ b/app/post_test.go @@ -2327,7 +2327,7 @@ func TestFollowThreadSkipsParticipants(t *testing.T) { threadMembership, err := th.App.GetThreadMembershipForUser(user.Id, p1.Id) require.Nil(t, err) - thread, err := th.App.GetThreadForUser(th.BasicTeam.Id, threadMembership, false) + thread, err := th.App.GetThreadForUser(threadMembership, false) require.Nil(t, err) require.Len(t, thread.Participants, 1) // length should be 1, the original poster, since sysadmin was just mentioned but didn't post @@ -2336,7 +2336,7 @@ func TestFollowThreadSkipsParticipants(t *testing.T) { threadMembership, err = th.App.GetThreadMembershipForUser(user.Id, p1.Id) require.Nil(t, err) - thread, err = th.App.GetThreadForUser(th.BasicTeam.Id, threadMembership, false) + thread, err = th.App.GetThreadForUser(threadMembership, false) require.Nil(t, err) require.Len(t, thread.Participants, 2) // length should be 2, the original poster and sysadmin, since sysadmin participated now @@ -2345,7 +2345,7 @@ func TestFollowThreadSkipsParticipants(t *testing.T) { threadMembership, err = th.App.GetThreadMembershipForUser(user2.Id, p1.Id) require.Nil(t, err) - thread, err = th.App.GetThreadForUser(th.BasicTeam.Id, threadMembership, false) + thread, err = th.App.GetThreadForUser(threadMembership, false) require.Nil(t, err) require.Len(t, thread.Participants, 2) // length should be 2, since follow shouldn't update participant list, only user1 and sysadmin are participants for _, p := range thread.Participants { diff --git a/app/user.go b/app/user.go index 9b0840eea6..0c3f998c9c 100644 --- a/app/user.go +++ b/app/user.go @@ -2468,8 +2468,8 @@ func (a *App) GetThreadMembershipForUser(userId, threadId string) (*model.Thread return threadMembership, nil } -func (a *App) GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, *model.AppError) { - thread, err := a.Srv().Store().Thread().GetThreadForUser(teamID, threadMembership, extended) +func (a *App) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, *model.AppError) { + thread, err := a.Srv().Store().Thread().GetThreadForUser(threadMembership, extended) if err != nil { return nil, model.NewAppError("GetThreadForUser", "app.user.get_threads_for_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } @@ -2551,7 +2551,7 @@ func (a *App) UpdateThreadFollowForUserFromChannelAdd(c request.CTX, userID, tea } message := model.NewWebSocketEvent(model.WebsocketEventThreadUpdated, teamID, "", userID, nil, "") - userThread, err := a.Srv().Store().Thread().GetThreadForUser(teamID, tm, true) + userThread, err := a.Srv().Store().Thread().GetThreadForUser(tm, true) if err != nil { var errNotFound *store.ErrNotFound @@ -2633,7 +2633,7 @@ func (a *App) UpdateThreadReadForUser(c request.CTX, currentSessionId, userID, t if nErr != nil { return nil, model.NewAppError("UpdateThreadReadForUser", "app.user.update_thread_read_for_user.app_error", nil, "", http.StatusInternalServerError).Wrap(nErr) } - thread, err := a.GetThreadForUser(teamID, membership, false) + thread, err := a.GetThreadForUser(membership, false) if err != nil { return nil, err } diff --git a/store/opentracinglayer/opentracinglayer.go b/store/opentracinglayer/opentracinglayer.go index 4f44190b77..614a3933fe 100644 --- a/store/opentracinglayer/opentracinglayer.go +++ b/store/opentracinglayer/opentracinglayer.go @@ -9890,7 +9890,7 @@ func (s *OpenTracingLayerThreadStore) GetThreadFollowers(threadID string, fetchO return result, err } -func (s *OpenTracingLayerThreadStore) GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { +func (s *OpenTracingLayerThreadStore) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ThreadStore.GetThreadForUser") s.Root.Store.SetContext(newCtx) @@ -9899,7 +9899,7 @@ func (s *OpenTracingLayerThreadStore) GetThreadForUser(teamID string, threadMemb }() defer span.Finish() - result, err := s.ThreadStore.GetThreadForUser(teamID, threadMembership, extended) + result, err := s.ThreadStore.GetThreadForUser(threadMembership, extended) if err != nil { span.LogFields(spanlog.Error(err)) ext.Error.Set(span, true) diff --git a/store/retrylayer/retrylayer.go b/store/retrylayer/retrylayer.go index 5afcf7fd9d..03043d870e 100644 --- a/store/retrylayer/retrylayer.go +++ b/store/retrylayer/retrylayer.go @@ -11307,11 +11307,11 @@ func (s *RetryLayerThreadStore) GetThreadFollowers(threadID string, fetchOnlyAct } -func (s *RetryLayerThreadStore) GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { +func (s *RetryLayerThreadStore) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { tries := 0 for { - result, err := s.ThreadStore.GetThreadForUser(teamID, threadMembership, extended) + result, err := s.ThreadStore.GetThreadForUser(threadMembership, extended) if err == nil { return result, nil } diff --git a/store/sqlstore/thread_store.go b/store/sqlstore/thread_store.go index 2e94d1eb3c..195e1b535a 100644 --- a/store/sqlstore/thread_store.go +++ b/store/sqlstore/thread_store.go @@ -436,7 +436,7 @@ func (s *SqlThreadStore) GetThreadFollowers(threadID string, fetchOnlyActive boo return users, nil } -func (s *SqlThreadStore) GetThreadForUser(teamId string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { +func (s *SqlThreadStore) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { if !threadMembership.Following { return nil, nil // in case the thread is not followed anymore - return nil error to be interpreted as 404 } @@ -450,11 +450,6 @@ func (s *SqlThreadStore) GetThreadForUser(teamId string, threadMembership *model sq.Eq{"Posts.DeleteAt": 0}, }) - fetchConditions := sq.And{ - sq.Or{sq.Eq{"Threads.ThreadTeamId": teamId}, sq.Eq{"Threads.ThreadTeamId": ""}}, - sq.Eq{"Threads.PostId": threadMembership.PostId}, - } - query := s.threadsAndPostsSelectQuery for _, c := range postSliceColumns() { @@ -465,7 +460,7 @@ func (s *SqlThreadStore) GetThreadForUser(teamId string, threadMembership *model query = query. Column(sq.Alias(unreadRepliesQuery, "UnreadReplies")). LeftJoin("Posts ON Posts.Id = Threads.PostId"). - Where(fetchConditions) + Where(sq.Eq{"Threads.PostId": threadMembership.PostId}) err := s.GetReplicaX().GetBuilder(&thread, query) if err != nil { diff --git a/store/store.go b/store/store.go index 95979e7c30..805c972e27 100644 --- a/store/store.go +++ b/store/store.go @@ -323,7 +323,7 @@ type ThreadStore interface { GetTotalThreads(userId, teamID string, opts model.GetUserThreadsOpts) (int64, error) GetTotalUnreadMentions(userId, teamID string, opts model.GetUserThreadsOpts) (int64, error) GetThreadsForUser(userId, teamID string, opts model.GetUserThreadsOpts) ([]*model.ThreadResponse, error) - GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) + GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) GetTeamsUnreadForUser(userID string, teamIDs []string) (map[string]*model.TeamUnread, error) GetPosts(threadID string, since int64) ([]*model.Post, error) diff --git a/store/storetest/mocks/ThreadStore.go b/store/storetest/mocks/ThreadStore.go index 0830bf73ff..bfacea3709 100644 --- a/store/storetest/mocks/ThreadStore.go +++ b/store/storetest/mocks/ThreadStore.go @@ -188,13 +188,13 @@ func (_m *ThreadStore) GetThreadFollowers(threadID string, fetchOnlyActive bool) return r0, r1 } -// GetThreadForUser provides a mock function with given fields: teamID, threadMembership, extended -func (_m *ThreadStore) GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { - ret := _m.Called(teamID, threadMembership, extended) +// GetThreadForUser provides a mock function with given fields: threadMembership, extended +func (_m *ThreadStore) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { + ret := _m.Called(threadMembership, extended) var r0 *model.ThreadResponse - if rf, ok := ret.Get(0).(func(string, *model.ThreadMembership, bool) *model.ThreadResponse); ok { - r0 = rf(teamID, threadMembership, extended) + if rf, ok := ret.Get(0).(func(*model.ThreadMembership, bool) *model.ThreadResponse); ok { + r0 = rf(threadMembership, extended) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*model.ThreadResponse) @@ -202,8 +202,8 @@ func (_m *ThreadStore) GetThreadForUser(teamID string, threadMembership *model.T } var r1 error - if rf, ok := ret.Get(1).(func(string, *model.ThreadMembership, bool) error); ok { - r1 = rf(teamID, threadMembership, extended) + if rf, ok := ret.Get(1).(func(*model.ThreadMembership, bool) error); ok { + r1 = rf(threadMembership, extended) } else { r1 = ret.Error(1) } diff --git a/store/storetest/thread_store.go b/store/storetest/thread_store.go index 885a48c1a4..463c4396aa 100644 --- a/store/storetest/thread_store.go +++ b/store/storetest/thread_store.go @@ -365,14 +365,14 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) { } m, err := ss.Thread().MaintainMembership(newPosts[0].UserId, newPosts[0].Id, opts) require.NoError(t, err) - th, err := ss.Thread().GetThreadForUser("", m, false) + th, err := ss.Thread().GetThreadForUser(m, false) require.NoError(t, err) require.Equal(t, int64(2), th.UnreadReplies) m.LastViewed = newPosts[2].UpdateAt + 1 _, err = ss.Thread().UpdateMembership(m) require.NoError(t, err) - th, err = ss.Thread().GetThreadForUser("", m, false) + th, err = ss.Thread().GetThreadForUser(m, false) require.NoError(t, err) require.Equal(t, int64(0), th.UnreadReplies) @@ -381,7 +381,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) { _, err = ss.Post().Update(editedPost, newPosts[2]) require.NoError(t, err) - th, err = ss.Thread().GetThreadForUser("", m, false) + th, err = ss.Thread().GetThreadForUser(m, false) require.NoError(t, err) require.Equal(t, int64(0), th.UnreadReplies) }) @@ -398,7 +398,7 @@ func testThreadStorePopulation(t *testing.T, ss store.Store) { m, err := ss.Thread().MaintainMembership("", newPosts[0].Id, opts) require.NoError(t, err) m.UserId = newPosts[0].UserId - th, err := ss.Thread().GetThreadForUser("", m, true) + th, err := ss.Thread().GetThreadForUser(m, true) require.NoError(t, err) for _, user := range th.Participants { require.NotNil(t, user) diff --git a/store/timerlayer/timerlayer.go b/store/timerlayer/timerlayer.go index 9e7e804646..deb0dbc224 100644 --- a/store/timerlayer/timerlayer.go +++ b/store/timerlayer/timerlayer.go @@ -8897,10 +8897,10 @@ func (s *TimerLayerThreadStore) GetThreadFollowers(threadID string, fetchOnlyAct return result, err } -func (s *TimerLayerThreadStore) GetThreadForUser(teamID string, threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { +func (s *TimerLayerThreadStore) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) { start := time.Now() - result, err := s.ThreadStore.GetThreadForUser(teamID, threadMembership, extended) + result, err := s.ThreadStore.GetThreadForUser(threadMembership, extended) elapsed := float64(time.Since(start)) / float64(time.Second) if s.Root.Metrics != nil { From e1fd39431089e6bf7528332292981cb659e6b4ae Mon Sep 17 00:00:00 2001 From: Kaya Zeren Date: Wed, 9 Nov 2022 09:16:31 +0100 Subject: [PATCH 02/32] Translated using Weblate (Turkish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/tr/ Translated using Weblate (Turkish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/tr/ Translated using Weblate (Turkish) Currently translated at 100.0% (2387 of 2387 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/tr/ --- i18n/tr.json | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/i18n/tr.json b/i18n/tr.json index 744b9a2ea0..680520e2fd 100644 --- a/i18n/tr.json +++ b/i18n/tr.json @@ -9316,7 +9316,7 @@ }, { "id": "api.templates.delinquency_90.subtitle2", - "translation": "ek olarak, Cloud Starter tarifesinin sınırlamaları nedeniyle verileriniz arşive kaldırılabilir." + "translation": "ek olarak, Cloud Free tarifesinin sınırlamaları nedeniyle verileriniz arşive kaldırılabilir." }, { "id": "api.templates.delinquency_90.subtitle1", @@ -9340,11 +9340,11 @@ }, { "id": "api.templates.delinquency_75.subtitle3", - "translation": "Hemen ödeme bilgilerinizi güncelleyebilir ya da Cloud Starter alt tarifesine geçebilirsiniz." + "translation": "Hemen ödeme bilgilerinizi güncelleyebilir ya da Cloud Free alt tarifesine geçebilirsiniz." }, { "id": "api.templates.delinquency_75.subtitle2", - "translation": "Çalışma alanınız Cloud Starter alt tarifesine geçirilecek. Ödemeyi yapana kadar {{.Plan}} tarifenizin özellikleri kilitlenecek. Ayrıca çalışma alanınızın bazı verileri arşive kaldırılabilir." + "translation": "Çalışma alanınız Cloud Free alt tarifesine geçirilecek. Ödemeyi yapana kadar {{.Plan}} tarifenizin özellikleri kilitlenecek. Ayrıca çalışma alanınızın bazı verileri arşive kaldırılabilir." }, { "id": "api.templates.delinquency_75.subtitle1", @@ -9360,7 +9360,7 @@ }, { "id": "api.templates.delinquency_75.downgrade_to_free", - "translation": "Cloud Starter alt tarifesine geç" + "translation": "Cloud Free alt tarifesine geç" }, { "id": "api.templates.delinquency_75.button", @@ -9384,7 +9384,7 @@ }, { "id": "api.templates.delinquency_60.subtitle3", - "translation": "Hemen ödeme bilgilerinizi güncelleyebilir ya da aşağıdan Cloud Starter alt tarifesine geçebilirsiniz." + "translation": "Hemen ödeme bilgilerinizi güncelleyebilir ya da aşağıdan Cloud Free alt tarifesine geçebilirsiniz." }, { "id": "api.templates.delinquency_60.subtitle2", @@ -9416,7 +9416,7 @@ }, { "id": "api.templates.delinquency_14.subtitle1", - "translation": "Bizde kayıtlı kredi kartı bilgilerinizi kullanarak ödeme alamadık. Çalışma alanınızın Cloud Starter alt tarifesine geçirilme riski var." + "translation": "Bizde kayıtlı kredi kartı bilgilerinizi kullanarak ödeme alamadık. Çalışma alanınızın Cloud Free alt tarifesine geçirilme riski var." }, { "id": "api.templates.delinquency_60.subtitle1", @@ -9428,7 +9428,7 @@ }, { "id": "api.templates.delinquency_60.downgrade_to_free", - "translation": "Cloud Starter alt tarifesine geç" + "translation": "Cloud Free alt tarifesine geç" }, { "id": "api.templates.delinquency_60.button", @@ -9557,5 +9557,17 @@ { "id": "api.team.invite_guests_to_channels.disabled.error", "translation": "Konuk hesapları devre dışı bırakılmış" + }, + { + "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", + "translation": "Zaman aralığı geçersiz." + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Konu türü zaten var." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Derleme türü zaten var." } ] From 0a53518fdf0112fe84ef500db4c831007483f33a Mon Sep 17 00:00:00 2001 From: MArtin Johnson Date: Wed, 9 Nov 2022 09:16:32 +0100 Subject: [PATCH 03/32] Translated using Weblate (Swedish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/sv/ Translated using Weblate (Swedish) Currently translated at 100.0% (2387 of 2387 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/sv/ --- i18n/sv.json | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/i18n/sv.json b/i18n/sv.json index 81ca870fdb..04d40500d7 100644 --- a/i18n/sv.json +++ b/i18n/sv.json @@ -77,11 +77,11 @@ }, { "id": "web.error.unsupported_browser.min_browser_version.edge", - "translation": "Version 44+" + "translation": "Version 95+" }, { "id": "web.error.unsupported_browser.min_browser_version.chrome", - "translation": "Version 100+" + "translation": "Version 106+" }, { "id": "web.error.unsupported_browser.learn_more", @@ -9553,5 +9553,21 @@ { "id": "api.team.invite_guests_to_channels.disabled.error", "translation": "Gäståtkomst har inaktiverats" + }, + { + "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", + "translation": "Ogiltigt tidsintervall." + }, + { + "id": "app.plugin.product_mode.app_error", + "translation": "Plugin {{.Name}} kan inte aktiveras i produktionsläge." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Samlingstypen finns redan." + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Ämnestypen finns redan." } ] From 8dd1aed4fdb914831f8434364a11a7415c9397a2 Mon Sep 17 00:00:00 2001 From: aeomin Date: Wed, 9 Nov 2022 09:16:32 +0100 Subject: [PATCH 04/32] Translated using Weblate (Chinese (Simplified)) Currently translated at 97.3% (2323 of 2387 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/zh_Hans/ --- i18n/zh-CN.json | 50 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/i18n/zh-CN.json b/i18n/zh-CN.json index cecf6c9252..9d3b1ef5fe 100644 --- a/i18n/zh-CN.json +++ b/i18n/zh-CN.json @@ -619,7 +619,7 @@ }, { "id": "api.command_help.desc", - "translation": "打开 Mattermost 帮助页面" + "translation": "显示 Mattermost 帮助信息" }, { "id": "api.command_help.name", @@ -1773,7 +1773,7 @@ }, { "id": "api.templates.email_change_verify_body.title", - "translation": "您已更新电子邮件地址" + "translation": "您已成功更新您的电子邮件" }, { "id": "api.templates.email_change_verify_subject", @@ -4565,7 +4565,7 @@ }, { "id": "oauth.gitlab.tos.error", - "translation": "GitLab 的使用条款已更新。请到 gitlab.com 接受新的使用条款后再尝试登入 Mattermost。" + "translation": "GitLab 的使用条款已更新。请到 {{.URL}} 接受新的使用条款后再尝试登入 Mattermost。" }, { "id": "plugin.api.update_user_status.bad_status", @@ -5829,11 +5829,11 @@ }, { "id": "web.error.unsupported_browser.min_browser_version.edge", - "translation": "版本 44+" + "translation": "版本 95+" }, { "id": "web.error.unsupported_browser.min_browser_version.chrome", - "translation": "版本 100+" + "translation": "版本 106+" }, { "id": "web.error.unsupported_browser.learn_more", @@ -7593,15 +7593,15 @@ }, { "id": "api.templates.payment_failed.title", - "translation": "付款失败" + "translation": "付款不成功" }, { "id": "api.templates.payment_failed.subject", - "translation": "需要采取的措施:Mattermost Cloud 付款失败" + "translation": "需要采取的措施:Mattermost {{.Plan}} 付款失败" }, { "id": "api.templates.payment_failed.info3", - "translation": "为确保不间断地订阅 Mattermost Cloud,请与您的金融机构联系以解决潜在问题或更新您的付款信息。付款信息更新后,Mattermost 将尝试结清任何未结余额。" + "translation": "为确保不间断地使用 Mattermost {{.Plan}},请与您的金融机构联系以解决潜在问题或更新您的付款信息。付款信息更新后,Mattermost 将尝试结清任何未结余额。" }, { "id": "api.templates.payment_failed.info2", @@ -8965,7 +8965,7 @@ }, { "id": "model.config.is_valid.bleve_search.bulk_indexing_batch_size.app_error", - "translation": "Bleve Bulk索引的的大小不能小于{{.BatchSize}}." + "translation": "Bleve Bulk索引的的大小不能小于{{.BatchSize}}." }, { "id": "model.channel.is_valid.1_or_more.app_error", @@ -9270,5 +9270,37 @@ { "id": "app.last_accessible_post.app_error", "translation": "获取最后可访问的帖子时出错" + }, + { + "id": "api.templates.delinquency_14.button", + "translation": "更新付款" + }, + { + "id": "api.team.invite_guests_to_channels.license.error", + "translation": "您的许可证不支持访客帐号" + }, + { + "id": "api.command_help.success", + "translation": "Mattermost 是一个开源平台,用于跨工具和团队的安全通信、协作和工作编排。\nMattermost 包含三个关键工具:\n\n**频道** - 通过 1:1 和群组消息与您的团队保持联系。\n**[Playbooks](/playbooks)** - 构建和配置可重复的流程以实现特定且可预测的结果。\n**[Boards](/boards)** - 在看板结构中管理项目和任务,以帮助您的团队实现关键里程碑。\n\n[查看文档和指南]({{.HelpLink}})" + }, + { + "id": "api.cloud.delinquency_email.missing_email_to_trigger", + "translation": "缺少发送拖欠电子邮件的必填字段。" + }, + { + "id": "api.templates.delinquency_14.subject", + "translation": "您的 Mattermost {{.Plan}} 付款已逾期。" + }, + { + "id": "api.team.invite_guests_to_channels.disabled.error", + "translation": "访客帐户已禁用" + }, + { + "id": "api.command_marketplace.name", + "translation": "商城" + }, + { + "id": "api.command_marketplace.desc", + "translation": "打开商城" } ] From 049d4e640709b0f4021986dc4c2cf49d860bdf3e Mon Sep 17 00:00:00 2001 From: jprusch Date: Wed, 9 Nov 2022 09:16:32 +0100 Subject: [PATCH 05/32] Translated using Weblate (German) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/de/ Translated using Weblate (German) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/de/ --- i18n/de.json | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/i18n/de.json b/i18n/de.json index 1c1107592d..4c409f0669 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -9304,11 +9304,11 @@ }, { "id": "api.templates.delinquency_75.subtitle3", - "translation": "Aktualisiere jetzt deine Zahlungsinformationen oder wechsele zu Cloud Starter." + "translation": "Aktualisiere jetzt deine Zahlungsinformationen oder wechsele zu Cloud Free." }, { "id": "api.templates.delinquency_75.subtitle2", - "translation": "Dein Arbeitsbereich wird auf Cloud Starter herabgestuft. Deins {{.Plan}}-Funktionen werden gesperrt und einige deiner Arbeitsbereichsdaten können archiviert werden, bis dein ausstehender Betrag vollständig beglichen ist." + "translation": "Dein Arbeitsbereich wird auf Cloud Free herabgestuft. Deins {{.Plan}}-Funktionen werden gesperrt und einige deiner Arbeitsbereichsdaten können archiviert werden, bis dein ausstehender Betrag vollständig beglichen ist." }, { "id": "api.templates.delinquency_75.subtitle1", @@ -9348,7 +9348,7 @@ }, { "id": "api.templates.delinquency_60.subtitle3", - "translation": "Aktualisiere jetzt deine Zahlungsinformationen oder wechsele unten zu Cloud Starter." + "translation": "Aktualisiere jetzt deine Zahlungsinformationen oder wechsele unten zu Cloud Free." }, { "id": "api.templates.delinquency_60.subtitle2", @@ -9444,7 +9444,7 @@ }, { "id": "api.templates.delinquency_14.subtitle1", - "translation": "Wir konnten die hinterlegte Kreditkarte nicht belasten. Das bedeutet, dass ein Risiko besteht auf Cloud Starter zurückgestuft zu werden." + "translation": "Wir konnten die hinterlegte Kreditkarte nicht belasten. Das bedeutet, dass ein Risiko besteht auf Cloud Free zurückgestuft zu werden." }, { "id": "api.templates.delinquency_14.subject", @@ -9488,7 +9488,7 @@ }, { "id": "api.templates.delinquency_90.subtitle2", - "translation": "Außerdem kann es sein, dass deine Daten aufgrund der Beschränkungen von Cloud Starter archiviert wurden." + "translation": "Außerdem kann es sein, dass deine Daten aufgrund der Beschränkungen von Cloud Free archiviert wurden." }, { "id": "api.templates.delinquency_90.subtitle1", @@ -9561,5 +9561,13 @@ { "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", "translation": "Ungültiger Zeitbereich." + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Thementyp existiert schon." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Collection Typ existiert schon." } ] From 7c09924ede0397bd9ac5de8d61a06005f3276ed0 Mon Sep 17 00:00:00 2001 From: master7 Date: Wed, 9 Nov 2022 09:16:33 +0100 Subject: [PATCH 06/32] Translated using Weblate (Polish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/pl/ Translated using Weblate (Polish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/pl/ --- i18n/pl.json | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/i18n/pl.json b/i18n/pl.json index cad231cde7..64c2419ae0 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -9321,7 +9321,7 @@ }, { "id": "api.templates.delinquency_14.subtitle1", - "translation": "Nie byliśmy w stanie obciążyć karty kredytowej, którą mamy w pliku. Oznacza to, że Twój obszar roboczy może zostać zdegradowany do wersji Cloud Starter." + "translation": "Nie byliśmy w stanie obciążyć karty kredytowej, którą mamy w pliku. Oznacza to, że Twój obszar roboczy może zostać zdegradowany do wersji Cloud Free." }, { "id": "api.templates.delinquency_14.subject", @@ -9337,7 +9337,7 @@ }, { "id": "api.templates.delinquency_75.subtitle2", - "translation": "Twój obszar roboczy zostanie zdegradowany do Cloud Starter. Funkcje Twojego {{.Plan}} zostaną zablokowane, a niektóre dane z Twojego obszaru roboczego mogą zostać zarchiwizowane do czasu uregulowania całego zaległego salda." + "translation": "Twój obszar roboczy zostanie zdegradowany do Cloud Free. Funkcje Twojego {{.Plan}} zostaną zablokowane, a niektóre dane z Twojego obszaru roboczego mogą zostać zarchiwizowane do czasu uregulowania całego zaległego salda." }, { "id": "api.templates.delinquency_75.subtitle1", @@ -9377,7 +9377,7 @@ }, { "id": "api.templates.delinquency_60.subtitle3", - "translation": "Zaktualizuj swoje informacje o płatnościach teraz lub przejdź do wersji Cloud Starter poniżej." + "translation": "Zaktualizuj swoje informacje o płatnościach teraz lub przejdź do wersji Cloud Free poniżej." }, { "id": "api.templates.delinquency_60.subtitle2", @@ -9449,7 +9449,7 @@ }, { "id": "api.templates.delinquency_90.subtitle2", - "translation": "Ponadto Twoje dane mogły zostać zarchiwizowane z powodu ograniczeń Cloud Starter." + "translation": "Ponadto Twoje dane mogły zostać zarchiwizowane z powodu ograniczeń Cloud Free." }, { "id": "api.templates.delinquency_90.subtitle1", @@ -9473,7 +9473,7 @@ }, { "id": "api.templates.delinquency_75.subtitle3", - "translation": "Zaktualizuj teraz swoje informacje o płatnościach lub przejdź do wersji Cloud Starter." + "translation": "Zaktualizuj teraz swoje informacje o płatnościach lub przejdź do wersji Cloud Free." }, { "id": "api.templates.delinquency_30.limits_documentation", @@ -9562,5 +9562,13 @@ { "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", "translation": "Nieprawidłowy zakres czasu." + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Typ tematu już istnieje." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Typ kolekcji już istnieje." } ] From 36cd2a84b33aeaec8d7020957849090113c27e57 Mon Sep 17 00:00:00 2001 From: Tom De Moor Date: Wed, 9 Nov 2022 09:16:33 +0100 Subject: [PATCH 07/32] Translated using Weblate (Dutch) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/nl/ --- i18n/nl.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/i18n/nl.json b/i18n/nl.json index ece09c658f..dedae87b78 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -9561,5 +9561,13 @@ { "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", "translation": "Ongeldig tijdsbereik." + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Topictype bestaat al." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Collectietype bestaat al." } ] From 61e94ddbd08131267d278192f8b41d59c29229a5 Mon Sep 17 00:00:00 2001 From: Angel Mendez Cano Date: Wed, 9 Nov 2022 09:16:34 +0100 Subject: [PATCH 08/32] Translated using Weblate (Spanish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/es/ Translated using Weblate (Spanish) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/es/ --- i18n/es.json | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/i18n/es.json b/i18n/es.json index b150176aa1..65593d7226 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -9289,7 +9289,7 @@ }, { "id": "api.templates.delinquency_90.subtitle2", - "translation": "Además, tus datos pueden haber sido archivados debido a las limitaciones de Cloud Starter." + "translation": "Además, tus datos pueden haber sido archivados debido a las limitaciones de Cloud Free." }, { "id": "api.templates.delinquency_90.subtitle1", @@ -9313,11 +9313,11 @@ }, { "id": "api.templates.delinquency_75.subtitle3", - "translation": "Actualiza ahora tu información de pago, o degrada a Cloud Starter." + "translation": "Actualiza ahora tu información de pago, o degrada a Cloud Free." }, { "id": "api.templates.delinquency_75.subtitle2", - "translation": "Tu workspace será degradado a Cloud Starter. Las características de tu {{.Plan}} serán bloqueadas y algunos de los datos de tu workspace podrían ser archivados hasta que liquides completamente tu saldo pendiente." + "translation": "Tu espacio de trabajo será degradado a Cloud Free. Las características de tu {{.Plan}} serán bloqueadas y algunos de los datos de tu espacio de trabajo podrían ser archivados hasta que liquides completamente tu saldo pendiente." }, { "id": "api.templates.delinquency_75.subtitle1", @@ -9357,7 +9357,7 @@ }, { "id": "api.templates.delinquency_60.subtitle3", - "translation": "Actualiza tu información de pago ahora o degrada a Cloud Starter abajo." + "translation": "Actualiza tu información de pago ahora o degrada a Cloud Free abajo." }, { "id": "api.templates.delinquency_60.subtitle2", @@ -9453,7 +9453,7 @@ }, { "id": "api.templates.delinquency_14.subtitle1", - "translation": "No pudimos realizar el cargo a la tarjeta de crédito que tenemos registrada. Por lo cual tu workspace está en riesgo de ser degradado a Cloud Starter." + "translation": "No pudimos realizar el cargo a la tarjeta de crédito que tenemos registrada. Por lo cual tu espacio de trabajo está en riesgo de ser degradado a Cloud Free." }, { "id": "api.templates.delinquency_14.subject", @@ -9562,5 +9562,13 @@ { "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", "translation": "Intervalo de tiempo inválido." + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "El tipo de tema ya existe." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "El tipo de colección ya existe." } ] From bcd0094cb7468051b837a38ed21d1350a540f84f Mon Sep 17 00:00:00 2001 From: Matthew Williams Date: Wed, 9 Nov 2022 09:16:34 +0100 Subject: [PATCH 09/32] Translated using Weblate (English (Australia)) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/en_AU/ --- i18n/en_AU.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/i18n/en_AU.json b/i18n/en_AU.json index e0d8f4d09a..64ea23c44d 100644 --- a/i18n/en_AU.json +++ b/i18n/en_AU.json @@ -9561,5 +9561,13 @@ { "id": "api.team.invite_guests_to_channels.disabled.error", "translation": "Guest accounts are disabled" + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Topic type already exists." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Collection type already exists." } ] From 8951779aa80ad6c82352ef29b12ad7c2b9b6998a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 9 Nov 2022 09:16:34 +0100 Subject: [PATCH 10/32] Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ --- i18n/ru.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/i18n/ru.json b/i18n/ru.json index de1332a77a..71f94ac8bb 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -9447,10 +9447,6 @@ "id": "api.templates.delinquency_75.subject", "translation": "Ваш Mattermost {{.Plan}} будет понижен через 15 дней" }, - { - "id": "api.templates.delinquency_75.downgrade_to_starter", - "translation": "Понижение статуса до Cloud Starter" - }, { "id": "api.templates.delinquency_75.button", "translation": "Обновить платёж" @@ -9491,10 +9487,6 @@ "id": "api.templates.delinquency_60.subject", "translation": "Необходимые действия: Рабочее пространство будет понижено в течение 30 дней" }, - { - "id": "api.templates.delinquency_60.downgrade_to_starter", - "translation": "Понижение статуса до Cloud Starter" - }, { "id": "api.templates.delinquency_60.button", "translation": "Обновить платёж" From 6f5d3fef30ca144359fd141a2547d301bc3d687a Mon Sep 17 00:00:00 2001 From: Konstantin Date: Wed, 9 Nov 2022 09:16:35 +0100 Subject: [PATCH 11/32] Translated using Weblate (Russian) Currently translated at 100.0% (2389 of 2389 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ru/ --- i18n/ru.json | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/i18n/ru.json b/i18n/ru.json index 71f94ac8bb..a04c03a356 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -9193,7 +9193,7 @@ }, { "id": "api.templates.delinquency_14.subtitle1", - "translation": "Мы не смогли снять деньги с имеющейся у нас кредитной карты. Это означает, что ваше рабочее пространство может быть переведено в категорию Cloud Starter." + "translation": "Мы не смогли снять деньги с имеющейся у нас кредитной карты. Это означает, что ваше рабочее пространство может быть переведено в категорию Cloud Free." }, { "id": "api.templates.delinquency_14.subject", @@ -9409,7 +9409,7 @@ }, { "id": "api.templates.delinquency_90.subtitle2", - "translation": "Кроме того, ваши данные могут быть заархивированы из-за ограничений Cloud Starter." + "translation": "Кроме того, ваши данные могут быть заархивированы из-за ограничений Cloud Free." }, { "id": "api.templates.delinquency_90.subtitle1", @@ -9433,11 +9433,11 @@ }, { "id": "api.templates.delinquency_75.subtitle3", - "translation": "Обновите свою платёжную информацию сейчас или перейдите на Cloud Starter." + "translation": "Обновите свою платёжную информацию сейчас или перейдите на Cloud Free." }, { "id": "api.templates.delinquency_75.subtitle2", - "translation": "Ваше рабочее пространство будет понижено до уровня Cloud Starter. Ваши функции {{.Plan}} будут заблокированы, а некоторые данные рабочего пространства могут быть заархивированы до полного погашения задолженности." + "translation": "Ваше рабочее пространство будет понижено до уровня Cloud Free. Ваши функции {{.Plan}} будут заблокированы, а некоторые данные рабочего пространства могут быть заархивированы до полного погашения задолженности." }, { "id": "api.templates.delinquency_75.subtitle1", @@ -9473,7 +9473,7 @@ }, { "id": "api.templates.delinquency_60.subtitle3", - "translation": "Обновите свою платёжную информацию сейчас или перейдите на Cloud Starter ниже." + "translation": "Обновите свою платёжную информацию сейчас или перейдите на Cloud Free ниже." }, { "id": "api.templates.delinquency_60.subtitle2", @@ -9554,5 +9554,21 @@ { "id": "api.templates.delinquency_30.bullet.cards", "translation": "Карточки с Ваших Boards" + }, + { + "id": "app.collection.add_topic.exists.app_error", + "translation": "Тип темы уже существует." + }, + { + "id": "app.collection.add_collection.exists.app_error", + "translation": "Тип коллекции уже существует." + }, + { + "id": "api.templates.delinquency_75.downgrade_to_free", + "translation": "Понижение статуса до Cloud Free" + }, + { + "id": "api.templates.delinquency_60.downgrade_to_free", + "translation": "Понижение статуса до Cloud Free" } ] From 19c57ade003531fae4681f5c446a5ba203707179 Mon Sep 17 00:00:00 2001 From: Scott Bishel Date: Wed, 9 Nov 2022 09:39:31 -0700 Subject: [PATCH 12/32] update pre-package boards to v7.5.0 (#21623) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d792c30126..8ecf84cea2 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ PLUGIN_PACKAGES += mattermost-plugin-jira-v2.4.0 PLUGIN_PACKAGES += mattermost-plugin-nps-v1.3.0 PLUGIN_PACKAGES += mattermost-plugin-welcomebot-v1.2.0 PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.6.0 -PLUGIN_PACKAGES += focalboard-v7.4.3 +PLUGIN_PACKAGES += focalboard-v7.5.0 PLUGIN_PACKAGES += mattermost-plugin-apps-v1.1.0 # Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target From 597bf9fcad1a874a03ff5646429871ff841fd710 Mon Sep 17 00:00:00 2001 From: Christopher Poile Date: Wed, 9 Nov 2022 12:42:18 -0500 Subject: [PATCH 13/32] Calls v0.9.0 -> v0.10.0 (#21622) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8ecf84cea2..c5f0d17e5a 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,7 @@ TEMPLATES_DIR=templates PLUGIN_PACKAGES ?= mattermost-plugin-antivirus-v0.1.2 PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.2.2 PLUGIN_PACKAGES += mattermost-plugin-aws-SNS-v1.2.0 -PLUGIN_PACKAGES += mattermost-plugin-calls-v0.9.0 +PLUGIN_PACKAGES += mattermost-plugin-calls-v0.10.0 PLUGIN_PACKAGES += mattermost-plugin-channel-export-v1.0.0 PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.3.0 PLUGIN_PACKAGES += mattermost-plugin-github-v2.0.1 From 5a0a3e6d13e63a03f22facd84446609a15732dce Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Wed, 9 Nov 2022 14:00:07 -0400 Subject: [PATCH 14/32] Inline ThreadStore.MarkAllAsUnreadByTeam (#20958) * Add teamId to Threads table * Get rid of multiple teamId reads * Fix failed test * Inline ThreadStore.MarkAllAsUnreadByTeam The query to `MarkAllAsUnreadByTeam` first fetched all thread memberships, then fed just the ids back to a second query to ensure all are marked as unread. Optimize this by simply doing a single `UPDATE` query with the necessary joins. Co-authored-by: iomodo --- store/sqlstore/post_store.go | 6 +- store/sqlstore/thread_store.go | 29 ++-- store/storetest/thread_store.go | 228 +++++++++++++++++++++++++++++++- 3 files changed, 245 insertions(+), 18 deletions(-) diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go index 141565c816..a11a3ee347 100644 --- a/store/sqlstore/post_store.go +++ b/store/sqlstore/post_store.go @@ -1670,7 +1670,7 @@ func (s *SqlPostStore) getParentsPosts(channelId string, offset int, limit int, FROM Posts WHERE - ChannelId = ? ` + deleteAtCondition + ` + ChannelId = ? ` + deleteAtCondition + ` ORDER BY CreateAt DESC LIMIT ? OFFSET ?) q WHERE q.RootId != ''` @@ -1757,13 +1757,13 @@ func (s *SqlPostStore) getParentsPostsPostgreSQL(channelId string, offset int, l FROM Posts WHERE - Posts.ChannelId = ? `+deleteAtSubQueryCondition+` + Posts.ChannelId = ? `+deleteAtSubQueryCondition+` ORDER BY Posts.CreateAt DESC LIMIT ? OFFSET ?) q3 WHERE q3.RootId != '') q1 ON `+onStatement+` WHERE - q2.ChannelId = ? `+deleteAtQueryCondition+` + q2.ChannelId = ? `+deleteAtQueryCondition+` ORDER BY q2.CreateAt`, channelId, limit, offset, channelId) if err != nil { return nil, errors.Wrapf(err, "failed to find Posts with channelId=%s", channelId) diff --git a/store/sqlstore/thread_store.go b/store/sqlstore/thread_store.go index 195e1b535a..9e4e47835f 100644 --- a/store/sqlstore/thread_store.go +++ b/store/sqlstore/thread_store.go @@ -549,27 +549,28 @@ func (s *SqlThreadStore) MarkAllAsRead(userId string, threadIds []string) error // MarkAllAsReadByTeam marks all threads for the given user in the given team as read from the // current time. func (s *SqlThreadStore) MarkAllAsReadByTeam(userId, teamId string) error { - memberships, err := s.GetMembershipsForUser(userId, teamId) - if err != nil { - return err - } - membershipIds := []string{} - for _, m := range memberships { - membershipIds = append(membershipIds, m.PostId) - } timestamp := model.GetMillis() - query := s.getQueryBuilder(). - Update("ThreadMemberships"). - Where(sq.Eq{"PostId": membershipIds}). - Where(sq.Eq{"UserId": userId}). + + var query sq.UpdateBuilder + if s.DriverName() == model.DatabaseDriverPostgres { + query = s.getQueryBuilder().Update("ThreadMemberships").From("Threads") + } else { + query = s.getQueryBuilder().Update("ThreadMemberships", "Threads") + } + + query = query. + Where("Threads.PostId = ThreadMemberships.PostId"). + Where(sq.Eq{"ThreadMemberships.UserId": userId}). + Where(sq.Or{sq.Eq{"Threads.TeamId": teamId}, sq.Eq{"Threads.TeamId": ""}}). Set("LastViewed", timestamp). Set("UnreadMentions", 0). - Set("LastUpdated", model.GetMillis()) + Set("LastUpdated", timestamp) - _, err = s.GetMasterX().ExecBuilder(query) + _, err := s.GetMasterX().ExecBuilder(query) if err != nil { return errors.Wrapf(err, "failed to update thread read state for user id=%s", userId) } + return nil } diff --git a/store/storetest/thread_store.go b/store/storetest/thread_store.go index 463c4396aa..e90e9f7d89 100644 --- a/store/storetest/thread_store.go +++ b/store/storetest/thread_store.go @@ -28,6 +28,7 @@ func TestThreadStore(t *testing.T, ss store.Store, s SqlStore) { t.Run("GetVarious", func(t *testing.T) { testVarious(t, ss) }) t.Run("MarkAllAsReadByChannels", func(t *testing.T) { testMarkAllAsReadByChannels(t, ss) }) t.Run("GetTopThreads", func(t *testing.T) { testGetTopThreads(t, ss) }) + t.Run("MarkAllAsReadByTeam", func(t *testing.T) { testMarkAllAsReadByTeam(t, ss) }) } func testThreadStorePopulation(t *testing.T, ss store.Store) { @@ -1603,5 +1604,230 @@ func testGetTopThreads(t *testing.T, ss store.Store) { // require first element to be post1 with 2 replyCount=2 require.Equal(t, topThreadsInTeamOlder.Items[1].PostId, post2.Id) }) - +} + +func testMarkAllAsReadByTeam(t *testing.T, ss store.Store) { + createThreadMembership := func(userID, postID string) { + t.Helper() + opts := store.ThreadMembershipOpts{ + Following: true, + IncrementMentions: false, + UpdateFollowing: true, + UpdateViewedTimestamp: false, + UpdateParticipants: false, + } + _, err := ss.Thread().MaintainMembership(userID, postID, opts) + require.NoError(t, err) + } + + assertThreadReplyCount := func(t *testing.T, userID, teamID string, count int64, message string) { + t.Helper() + + teamsUnread, err := ss.Thread().GetTeamsUnreadForUser(userID, []string{teamID}) + require.NoError(t, err) + require.Lenf(t, teamsUnread, 1, "unexpected unread teams count: %s", message) + assert.Equalf(t, count, teamsUnread[teamID].ThreadCount, "unexpected thread count: %s", message) + } + + postingUserId := model.NewId() + userAID := model.NewId() + userBID := model.NewId() + + team1, err := ss.Team().Save(&model.Team{ + DisplayName: "Team1", + Name: "team1" + model.NewId(), + Email: MakeEmail(), + Type: model.TeamOpen, + }) + require.NoError(t, err) + + team1channel1, err := ss.Channel().Save(&model.Channel{ + TeamId: team1.Id, + DisplayName: "Team1: Channel1", + Name: "team1channel1" + model.NewId(), + Type: model.ChannelTypeOpen, + }, -1) + require.NoError(t, err) + + team1channel2, err := ss.Channel().Save(&model.Channel{ + TeamId: team1.Id, + DisplayName: "Team1: Channel2", + Name: "team1channel2" + model.NewId(), + Type: model.ChannelTypeOpen, + }, -1) + require.NoError(t, err) + + team2, err := ss.Team().Save(&model.Team{ + DisplayName: "Team2", + Name: "team2" + model.NewId(), + Email: MakeEmail(), + Type: model.TeamOpen, + }) + require.NoError(t, err) + + team2channel1, err := ss.Channel().Save(&model.Channel{ + TeamId: team2.Id, + DisplayName: "Team2: Channel1", + Name: "team2channel1" + model.NewId(), + Type: model.ChannelTypeOpen, + }, -1) + require.NoError(t, err) + + team2channel2, err := ss.Channel().Save(&model.Channel{ + TeamId: team2.Id, + DisplayName: "Team2: Channel2", + Name: "team2channel2" + model.NewId(), + Type: model.ChannelTypeOpen, + }, -1) + require.NoError(t, err) + + team1channel1post1, err := ss.Post().Save(&model.Post{ + ChannelId: team1channel1.Id, + UserId: postingUserId, + Message: "Root", + }) + require.NoError(t, err) + + _, err = ss.Post().Save(&model.Post{ + ChannelId: team1channel1.Id, + UserId: postingUserId, + RootId: team1channel1post1.Id, + Message: "Reply", + }) + require.NoError(t, err) + + team1channel2post1, err := ss.Post().Save(&model.Post{ + ChannelId: team1channel2.Id, + UserId: postingUserId, + Message: "Root", + }) + require.NoError(t, err) + + _, err = ss.Post().Save(&model.Post{ + ChannelId: team1channel1.Id, + UserId: postingUserId, + RootId: team1channel2post1.Id, + Message: "Reply", + }) + require.NoError(t, err) + + team2channel1post1, err := ss.Post().Save(&model.Post{ + ChannelId: team2channel1.Id, + UserId: postingUserId, + Message: "Root", + }) + require.NoError(t, err) + + _, err = ss.Post().Save(&model.Post{ + ChannelId: team2channel1.Id, + UserId: postingUserId, + RootId: team2channel1post1.Id, + Message: "Reply", + }) + require.NoError(t, err) + + team2channel2post1, err := ss.Post().Save(&model.Post{ + ChannelId: team2channel2.Id, + UserId: postingUserId, + Message: "Root", + }) + require.NoError(t, err) + + _, err = ss.Post().Save(&model.Post{ + ChannelId: team2channel1.Id, + UserId: postingUserId, + RootId: team2channel2post1.Id, + Message: "Reply", + }) + require.NoError(t, err) + + gm1, err := ss.Channel().Save(&model.Channel{ + DisplayName: "GM1", + Name: "gm1" + model.NewId(), + Type: model.ChannelTypeGroup, + }, -1) + require.NoError(t, err) + + gm1post1, err := ss.Post().Save(&model.Post{ + ChannelId: gm1.Id, + UserId: postingUserId, + Message: "Root", + }) + require.NoError(t, err) + + _, err = ss.Post().Save(&model.Post{ + ChannelId: gm1.Id, + UserId: postingUserId, + RootId: gm1post1.Id, + Message: "Reply", + }) + require.NoError(t, err) + + gm2, err := ss.Channel().Save(&model.Channel{ + DisplayName: "GM1", + Name: "gm1" + model.NewId(), + Type: model.ChannelTypeGroup, + }, -1) + require.NoError(t, err) + + gm2post1, err := ss.Post().Save(&model.Post{ + ChannelId: gm2.Id, + UserId: postingUserId, + Message: "Root", + }) + require.NoError(t, err) + + _, err = ss.Post().Save(&model.Post{ + ChannelId: gm2.Id, + UserId: postingUserId, + RootId: gm2post1.Id, + Message: "Reply", + }) + require.NoError(t, err) + + t.Run("empty team", func(t *testing.T) { + err = ss.Thread().MarkAllAsReadByTeam(model.NewId(), "") + require.NoError(t, err) + }) + + t.Run("unknown team", func(t *testing.T) { + err = ss.Thread().MarkAllAsReadByTeam(model.NewId(), model.NewId()) + require.NoError(t, err) + }) + + t.Run("team1", func(t *testing.T) { + createThreadMembership(userAID, team1channel1post1.Id) + createThreadMembership(userBID, team1channel1post1.Id) + createThreadMembership(userAID, team1channel2post1.Id) + createThreadMembership(userBID, team1channel2post1.Id) + createThreadMembership(userAID, team2channel1post1.Id) + createThreadMembership(userBID, team2channel1post1.Id) + + // Note that GMs (and similarly, DMs) don't count towards this API. + createThreadMembership(userAID, gm1.Id) + createThreadMembership(userBID, gm1.Id) + createThreadMembership(userAID, gm2.Id) + createThreadMembership(userBID, gm2.Id) + + assertThreadReplyCount(t, userAID, team1.Id, 2, "expected 2 unread messages in team1 for userA") + assertThreadReplyCount(t, userBID, team1.Id, 2, "expected 2 unread messages in team1 for userB") + assertThreadReplyCount(t, userAID, team2.Id, 1, "expected 1 unread message in team2 for userA") + assertThreadReplyCount(t, userBID, team2.Id, 1, "expected 1 unread message in team2 for userB") + + err = ss.Thread().MarkAllAsReadByTeam(userAID, team1.Id) + require.NoError(t, err) + + assertThreadReplyCount(t, userAID, team1.Id, 0, "expected 0 unread messages in team1 for userA") + assertThreadReplyCount(t, userBID, team1.Id, 2, "expected 2 unread messages in team1 for userB") + assertThreadReplyCount(t, userAID, team2.Id, 1, "expected 1 unread message in team2 for userA") + assertThreadReplyCount(t, userBID, team2.Id, 1, "expected 1 unread message in team2 for userB") + + err = ss.Thread().MarkAllAsReadByTeam(userBID, team1.Id) + require.NoError(t, err) + + assertThreadReplyCount(t, userAID, team1.Id, 0, "expected 0 unread messages in team1 for userA") + assertThreadReplyCount(t, userBID, team1.Id, 0, "expected 0 unread messages in team1 for userB") + assertThreadReplyCount(t, userAID, team2.Id, 1, "expected 1 unread message in team2 for userA") + assertThreadReplyCount(t, userBID, team2.Id, 1, "expected 1 unread message in team2 for userB") + }) } From e5828b6da01047217f78c12bd8e65aecf8c3d0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Andr=C3=A9s=20V=C3=A9lez=20Vidal?= Date: Wed, 9 Nov 2022 20:06:52 +0100 Subject: [PATCH 15/32] MM-47865 - remove guided channel ff (#21599) --- model/feature_flags.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/model/feature_flags.go b/model/feature_flags.go index 38d6214254..83272a9a88 100644 --- a/model/feature_flags.go +++ b/model/feature_flags.go @@ -42,9 +42,6 @@ type FeatureFlags struct { // A dash separated list for feature flags to turn on for Boards BoardsFeatureFlags string - // Enable Create First Channel - GuidedChannelCreation bool - // A/B test for whether radio buttons or toggle button is more effective in in-screen invite to team modal ("none", "toggle") InviteToTeam string @@ -98,7 +95,6 @@ func (f *FeatureFlags) SetDefaults() { f.PermalinkPreviews = true f.CallsMobile = false f.BoardsFeatureFlags = "" - f.GuidedChannelCreation = false f.InviteToTeam = "none" f.CustomGroups = true f.BoardsDataRetention = false From 44dd185506eeddf5b14d0b5b18a2678d18095054 Mon Sep 17 00:00:00 2001 From: Shota Gvinepadze Date: Thu, 10 Nov 2022 11:30:49 +0400 Subject: [PATCH 16/32] Fix bad merge (#21632) --- store/sqlstore/thread_store.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/store/sqlstore/thread_store.go b/store/sqlstore/thread_store.go index 9e4e47835f..502be5e354 100644 --- a/store/sqlstore/thread_store.go +++ b/store/sqlstore/thread_store.go @@ -561,7 +561,7 @@ func (s *SqlThreadStore) MarkAllAsReadByTeam(userId, teamId string) error { query = query. Where("Threads.PostId = ThreadMemberships.PostId"). Where(sq.Eq{"ThreadMemberships.UserId": userId}). - Where(sq.Or{sq.Eq{"Threads.TeamId": teamId}, sq.Eq{"Threads.TeamId": ""}}). + Where(sq.Or{sq.Eq{"Threads.ThreadTeamId": teamId}, sq.Eq{"Threads.ThreadTeamId": ""}}). Set("LastViewed", timestamp). Set("UnreadMentions", 0). Set("LastUpdated", timestamp) From f07de38cc5217d332d354e4eb747e4ea3f4df1fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Andr=C3=A9s=20V=C3=A9lez=20Vidal?= Date: Thu, 10 Nov 2022 10:59:11 +0100 Subject: [PATCH 17/32] MM-47866 - remove deprecated inviteToTeam FF (#21600) --- model/feature_flags.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/model/feature_flags.go b/model/feature_flags.go index 83272a9a88..29d4c015fd 100644 --- a/model/feature_flags.go +++ b/model/feature_flags.go @@ -42,9 +42,6 @@ type FeatureFlags struct { // A dash separated list for feature flags to turn on for Boards BoardsFeatureFlags string - // A/B test for whether radio buttons or toggle button is more effective in in-screen invite to team modal ("none", "toggle") - InviteToTeam string - CustomGroups bool // Enable DataRetention for Boards @@ -95,7 +92,6 @@ func (f *FeatureFlags) SetDefaults() { f.PermalinkPreviews = true f.CallsMobile = false f.BoardsFeatureFlags = "" - f.InviteToTeam = "none" f.CustomGroups = true f.BoardsDataRetention = false f.NormalizeLdapDNs = false From 91f7eb095769d4b3c41470fa40d9b5114a254132 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Fri, 11 Nov 2022 13:03:28 +0530 Subject: [PATCH 18/32] Filter by templated schema name for postgres queries (#21635) There were certain queries which did not filter by the current schema, but hardcoded public schema. Apart from that, we always filter with the current schema which allows connection proxies to run multiple MM within a single DB. ```release-note NONE ``` --- db/migrations/postgres/000001_create_teams.up.sql | 4 ++++ .../postgres/000013_create_incoming_webhooks.up.sql | 1 + .../postgres/000014_create_outgoing_webhooks.up.sql | 6 ++++-- db/migrations/postgres/000020_create_posts.up.sql | 1 + db/migrations/postgres/000026_create_preferences.up.sql | 2 ++ db/migrations/postgres/000028_create_tokens.up.sql | 2 ++ .../postgres/000033_create_sidebar_channels.down.sql | 1 + .../postgres/000033_create_sidebar_channels.up.sql | 1 + db/migrations/postgres/000034_create_oauthauthdata.up.sql | 2 ++ .../postgres/000040_create_sidebar_categories.down.sql | 1 + .../postgres/000040_create_sidebar_categories.up.sql | 1 + .../postgres/000045_create_plugin_key_value_store.down.sql | 2 +- .../postgres/000045_create_plugin_key_value_store.up.sql | 2 +- db/migrations/postgres/000046_create_users.up.sql | 1 + db/migrations/postgres/000049_create_channels.down.sql | 2 ++ db/migrations/postgres/000049_create_channels.up.sql | 2 ++ db/migrations/postgres/000051_create_msg_root_count.up.sql | 2 ++ .../postgres/000057_upgrade_command_webhooks_v6.0.up.sql | 1 + db/migrations/postgres/000066_upgrade_posts_v6.0.up.sql | 3 +++ .../postgres/000067_upgrade_channelmembers_v6.1.down.sql | 1 + .../postgres/000067_upgrade_channelmembers_v6.1.up.sql | 1 + .../postgres/000068_upgrade_teammembers_v6.1.down.sql | 1 + .../postgres/000068_upgrade_teammembers_v6.1.up.sql | 1 + db/migrations/postgres/000070_upgrade_cte_v6.1.up.sql | 1 + .../postgres/000071_upgrade_sessions_v6.1.down.sql | 1 + db/migrations/postgres/000071_upgrade_sessions_v6.1.up.sql | 1 + .../000073_upgrade_plugin_key_value_store_v6.3.down.sql | 1 + .../000073_upgrade_plugin_key_value_store_v6.3.up.sql | 1 + db/migrations/postgres/000076_upgrade_lastrootpostat.up.sql | 2 +- .../000082_upgrade_oauth_mattermost_app_id.down.sql | 1 + .../postgres/000082_upgrade_oauth_mattermost_app_id.up.sql | 1 + db/migrations/postgres/000088_remaining_migrations.up.sql | 1 + 32 files changed, 46 insertions(+), 5 deletions(-) diff --git a/db/migrations/postgres/000001_create_teams.up.sql b/db/migrations/postgres/000001_create_teams.up.sql index 31b2f781c9..9afd4b7114 100644 --- a/db/migrations/postgres/000001_create_teams.up.sql +++ b/db/migrations/postgres/000001_create_teams.up.sql @@ -35,6 +35,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'teams' + AND table_schema = current_schema() AND column_name = 'alloweddomains' AND NOT data_type = 'varchar(1000)'; IF column_exist THEN @@ -49,6 +50,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'teams' + AND table_schema = current_schema() AND column_name = 'groupconstrained' AND NOT data_type = 'boolean'; IF column_exist THEN @@ -63,6 +65,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'teams' + AND table_schema = current_schema() AND column_name = 'type' AND NOT data_type = 'varchar(255)'; IF column_exist THEN @@ -77,6 +80,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'teams' + AND table_schema = current_schema() AND column_name = 'schemeid' AND NOT data_type = 'varchar(26)'; IF column_exist THEN diff --git a/db/migrations/postgres/000013_create_incoming_webhooks.up.sql b/db/migrations/postgres/000013_create_incoming_webhooks.up.sql index f001f828eb..4f2cd6a70d 100644 --- a/db/migrations/postgres/000013_create_incoming_webhooks.up.sql +++ b/db/migrations/postgres/000013_create_incoming_webhooks.up.sql @@ -63,6 +63,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'incomingwebhooks' + AND table_schema = current_schema() AND column_name = 'description' AND NOT data_type = 'VARCHAR(500)'; IF column_exist THEN diff --git a/db/migrations/postgres/000014_create_outgoing_webhooks.up.sql b/db/migrations/postgres/000014_create_outgoing_webhooks.up.sql index b0d16b5929..699edec9d3 100644 --- a/db/migrations/postgres/000014_create_outgoing_webhooks.up.sql +++ b/db/migrations/postgres/000014_create_outgoing_webhooks.up.sql @@ -30,6 +30,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'outgoingwebhooks' + AND table_schema = current_schema() AND column_name = 'description' AND NOT data_type = 'VARCHAR(500)'; IF column_exist THEN @@ -44,6 +45,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'outgoingwebhooks' + AND table_schema = current_schema() AND column_name = 'iconurl' AND NOT data_type = 'VARCHAR(1024)'; IF column_exist THEN @@ -56,7 +58,7 @@ BEGIN IF ( SELECT column_default::bigint FROM information_schema.columns - WHERE table_schema='public' + WHERE table_schema=current_schema() AND table_name='outgoingwebhooks' AND column_name='username' ) = 0 THEN @@ -69,7 +71,7 @@ BEGIN IF ( SELECT column_default::bigint FROM information_schema.columns - WHERE table_schema='public' + WHERE table_schema=current_schema() AND table_name='outgoingwebhooks' AND column_name='iconurl' ) = 0 THEN diff --git a/db/migrations/postgres/000020_create_posts.up.sql b/db/migrations/postgres/000020_create_posts.up.sql index c3968372f4..fa347c73e4 100644 --- a/db/migrations/postgres/000020_create_posts.up.sql +++ b/db/migrations/postgres/000020_create_posts.up.sql @@ -42,6 +42,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'posts' + AND table_schema = current_schema() AND column_name = 'fileids' AND NOT data_type = 'varchar(300)'; IF column_exist THEN diff --git a/db/migrations/postgres/000026_create_preferences.up.sql b/db/migrations/postgres/000026_create_preferences.up.sql index a46991f3b4..7ce8a4259f 100644 --- a/db/migrations/postgres/000026_create_preferences.up.sql +++ b/db/migrations/postgres/000026_create_preferences.up.sql @@ -18,11 +18,13 @@ BEGIN SELECT count(*) != 0 INTO col_exists FROM information_schema.columns WHERE table_name = 'preferences' + AND table_schema = current_schema() AND column_name = 'value'; SELECT count(*) != 0 INTO type_exists FROM information_schema.columns WHERE table_name = 'preferences' + AND table_schema = current_schema() AND column_name = 'value' AND data_type = 'character varying' AND character_maximum_length = 2000; diff --git a/db/migrations/postgres/000028_create_tokens.up.sql b/db/migrations/postgres/000028_create_tokens.up.sql index 71e12c0c85..c160b79da2 100644 --- a/db/migrations/postgres/000028_create_tokens.up.sql +++ b/db/migrations/postgres/000028_create_tokens.up.sql @@ -16,11 +16,13 @@ BEGIN SELECT count(*) != 0 INTO col_exists FROM information_schema.columns WHERE table_name = 'tokens' + AND table_schema = current_schema() AND column_name = 'extra'; SELECT count(*) != 0 INTO type_exists FROM information_schema.columns WHERE table_name = 'tokens' + AND table_schema = current_schema() AND column_name = 'extra' AND data_type = 'character varying' AND character_maximum_length = 2048; diff --git a/db/migrations/postgres/000033_create_sidebar_channels.down.sql b/db/migrations/postgres/000033_create_sidebar_channels.down.sql index c48c68451c..7a839aef0f 100644 --- a/db/migrations/postgres/000033_create_sidebar_channels.down.sql +++ b/db/migrations/postgres/000033_create_sidebar_channels.down.sql @@ -6,6 +6,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'sidebarchannels' + AND table_schema = current_schema() AND column_name = 'categoryid' AND data_type = 'character varying' AND NOT character_maximum_length = 26; diff --git a/db/migrations/postgres/000033_create_sidebar_channels.up.sql b/db/migrations/postgres/000033_create_sidebar_channels.up.sql index ebdddc1267..ba48ecc617 100644 --- a/db/migrations/postgres/000033_create_sidebar_channels.up.sql +++ b/db/migrations/postgres/000033_create_sidebar_channels.up.sql @@ -14,6 +14,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'sidebarchannels' + AND table_schema = current_schema() AND column_name = 'categoryid' AND data_type = 'character varying' AND NOT character_maximum_length = 128; diff --git a/db/migrations/postgres/000034_create_oauthauthdata.up.sql b/db/migrations/postgres/000034_create_oauthauthdata.up.sql index ad36fe9198..b83c1349cf 100644 --- a/db/migrations/postgres/000034_create_oauthauthdata.up.sql +++ b/db/migrations/postgres/000034_create_oauthauthdata.up.sql @@ -19,11 +19,13 @@ BEGIN SELECT count(*) != 0 INTO col_exists FROM information_schema.columns WHERE table_name = 'oauthauthdata' + AND table_schema = current_schema() AND column_name = 'state'; SELECT count(*) != 0 INTO type_exists FROM information_schema.columns WHERE table_name = 'oauthauthdata' + AND table_schema = current_schema() AND column_name = 'state' AND data_type = 'character varying' AND character_maximum_length = 1024; diff --git a/db/migrations/postgres/000040_create_sidebar_categories.down.sql b/db/migrations/postgres/000040_create_sidebar_categories.down.sql index 0e4813b60a..dd026b59b4 100644 --- a/db/migrations/postgres/000040_create_sidebar_categories.down.sql +++ b/db/migrations/postgres/000040_create_sidebar_categories.down.sql @@ -9,6 +9,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'sidebarcategories' + AND table_schema = current_schema() AND column_name = 'id' AND data_type = 'character varying' AND NOT character_maximum_length = 26; diff --git a/db/migrations/postgres/000040_create_sidebar_categories.up.sql b/db/migrations/postgres/000040_create_sidebar_categories.up.sql index 29fd9ea657..ad2d71d938 100644 --- a/db/migrations/postgres/000040_create_sidebar_categories.up.sql +++ b/db/migrations/postgres/000040_create_sidebar_categories.up.sql @@ -17,6 +17,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'sidebarcategories' + AND table_schema = current_schema() AND column_name = 'id' AND data_type = 'character varying' AND NOT character_maximum_length = 128; diff --git a/db/migrations/postgres/000045_create_plugin_key_value_store.down.sql b/db/migrations/postgres/000045_create_plugin_key_value_store.down.sql index c5ead89d03..dcf3cd8ff9 100644 --- a/db/migrations/postgres/000045_create_plugin_key_value_store.down.sql +++ b/db/migrations/postgres/000045_create_plugin_key_value_store.down.sql @@ -2,7 +2,7 @@ DO $$BEGIN IF ( SELECT column_default::bigint FROM information_schema.columns - WHERE table_schema='public' + WHERE table_schema=current_schema() AND table_name='pluginkeyvaluestore' AND column_name='expireat' ) IS NULL THEN diff --git a/db/migrations/postgres/000045_create_plugin_key_value_store.up.sql b/db/migrations/postgres/000045_create_plugin_key_value_store.up.sql index f7001f2d79..59e8da0690 100644 --- a/db/migrations/postgres/000045_create_plugin_key_value_store.up.sql +++ b/db/migrations/postgres/000045_create_plugin_key_value_store.up.sql @@ -11,7 +11,7 @@ DO $$BEGIN IF ( SELECT column_default::bigint FROM information_schema.columns - WHERE table_schema='public' + WHERE table_schema=current_schema() AND table_name='pluginkeyvaluestore' AND column_name='expireat' ) = 0 THEN diff --git a/db/migrations/postgres/000046_create_users.up.sql b/db/migrations/postgres/000046_create_users.up.sql index 9a0d70d878..ef88ea0581 100644 --- a/db/migrations/postgres/000046_create_users.up.sql +++ b/db/migrations/postgres/000046_create_users.up.sql @@ -54,6 +54,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'users' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(256)'; IF column_exist THEN diff --git a/db/migrations/postgres/000049_create_channels.down.sql b/db/migrations/postgres/000049_create_channels.down.sql index 59524ef76f..4d14bc8f6a 100644 --- a/db/migrations/postgres/000049_create_channels.down.sql +++ b/db/migrations/postgres/000049_create_channels.down.sql @@ -12,6 +12,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'channels' + AND table_schema = current_schema() AND column_name = 'groupconstrained' AND NOT data_type = 'boolean'; @@ -36,6 +37,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'channels' + AND table_schema = current_schema() AND column_name = 'purpose' AND data_type = 'character varying' AND NOT character_maximum_length = 64; diff --git a/db/migrations/postgres/000049_create_channels.up.sql b/db/migrations/postgres/000049_create_channels.up.sql index 9fc5e3d3ed..cbd4ea97be 100644 --- a/db/migrations/postgres/000049_create_channels.up.sql +++ b/db/migrations/postgres/000049_create_channels.up.sql @@ -35,6 +35,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'channels' + AND table_schema = current_schema() AND column_name = 'purpose' AND data_type = 'character varying' AND NOT character_maximum_length = 250; @@ -60,6 +61,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist_and_type_different FROM information_schema.columns WHERE table_name = 'channels' + AND table_schema = current_schema() AND column_name = 'groupconstrained' AND NOT data_type = 'boolean'; diff --git a/db/migrations/postgres/000051_create_msg_root_count.up.sql b/db/migrations/postgres/000051_create_msg_root_count.up.sql index ee9113d2ca..5acb8466cd 100644 --- a/db/migrations/postgres/000051_create_msg_root_count.up.sql +++ b/db/migrations/postgres/000051_create_msg_root_count.up.sql @@ -10,11 +10,13 @@ BEGIN SELECT count(*) != 0 INTO msg_count_root_exist FROM information_schema.columns WHERE table_name = 'channels' + AND table_schema = current_schema() AND column_name = 'totalmsgcountroot'; SELECT count(*) != 0 INTO mention_count_root_exist FROM information_schema.columns WHERE table_name = 'channelmembers' + AND table_schema = current_schema() AND column_name = 'mentioncountroot'; IF mention_count_root_exist THEN diff --git a/db/migrations/postgres/000057_upgrade_command_webhooks_v6.0.up.sql b/db/migrations/postgres/000057_upgrade_command_webhooks_v6.0.up.sql index fc7b49f213..d85393fd5d 100644 --- a/db/migrations/postgres/000057_upgrade_command_webhooks_v6.0.up.sql +++ b/db/migrations/postgres/000057_upgrade_command_webhooks_v6.0.up.sql @@ -6,6 +6,7 @@ BEGIN SELECT count(*) != 0 INTO parentid_exist FROM information_schema.columns WHERE table_name = 'commandwebhooks' + AND table_schema = current_schema() AND column_name = 'parentid'; IF parentid_exist THEN UPDATE commandwebhooks SET rootid = parentid WHERE rootid = '' AND rootid != parentid; diff --git a/db/migrations/postgres/000066_upgrade_posts_v6.0.up.sql b/db/migrations/postgres/000066_upgrade_posts_v6.0.up.sql index 277aba8ec7..4840163021 100644 --- a/db/migrations/postgres/000066_upgrade_posts_v6.0.up.sql +++ b/db/migrations/postgres/000066_upgrade_posts_v6.0.up.sql @@ -8,16 +8,19 @@ BEGIN SELECT count(*) != 0 INTO parentid_exist FROM information_schema.columns WHERE table_name = 'posts' + AND table_schema = current_schema() AND column_name = 'parentid'; SELECT count(*) != 0 INTO alter_fileids FROM information_schema.columns WHERE table_name = 'posts' + AND table_schema = current_schema() AND column_name = 'fileids' AND data_type = 'character varying' AND character_maximum_length != 300; SELECT count(*) != 0 INTO alter_props FROM information_schema.columns WHERE table_name = 'posts' + AND table_schema = current_schema() AND column_name = 'props' AND data_type != 'jsonb'; IF alter_fileids OR alter_props THEN diff --git a/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.down.sql b/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.down.sql index 2a280730e4..422c9a9ae3 100644 --- a/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.down.sql +++ b/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.down.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'channelmembers' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(64)'; IF column_exist THEN diff --git a/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.up.sql b/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.up.sql index 09947201f7..596f352715 100644 --- a/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.up.sql +++ b/db/migrations/postgres/000067_upgrade_channelmembers_v6.1.up.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'channelmembers' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(256)'; IF column_exist THEN diff --git a/db/migrations/postgres/000068_upgrade_teammembers_v6.1.down.sql b/db/migrations/postgres/000068_upgrade_teammembers_v6.1.down.sql index 0e86aeac83..ba2ef2efa0 100644 --- a/db/migrations/postgres/000068_upgrade_teammembers_v6.1.down.sql +++ b/db/migrations/postgres/000068_upgrade_teammembers_v6.1.down.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'teammembers' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(64)'; IF column_exist THEN diff --git a/db/migrations/postgres/000068_upgrade_teammembers_v6.1.up.sql b/db/migrations/postgres/000068_upgrade_teammembers_v6.1.up.sql index d8992f9063..dd04d44961 100644 --- a/db/migrations/postgres/000068_upgrade_teammembers_v6.1.up.sql +++ b/db/migrations/postgres/000068_upgrade_teammembers_v6.1.up.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'teammembers' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(256)'; IF column_exist THEN diff --git a/db/migrations/postgres/000070_upgrade_cte_v6.1.up.sql b/db/migrations/postgres/000070_upgrade_cte_v6.1.up.sql index 25a2275165..8c1b0b4773 100644 --- a/db/migrations/postgres/000070_upgrade_cte_v6.1.up.sql +++ b/db/migrations/postgres/000070_upgrade_cte_v6.1.up.sql @@ -9,6 +9,7 @@ BEGIN information_schema.columns WHERE table_name = 'channels' + AND table_schema = current_schema() AND column_name = 'lastrootpostat'; IF NOT column_exist THEN ALTER TABLE channels ADD COLUMN lastrootpostat bigint DEFAULT '0'::bigint; diff --git a/db/migrations/postgres/000071_upgrade_sessions_v6.1.down.sql b/db/migrations/postgres/000071_upgrade_sessions_v6.1.down.sql index bef3815cc0..7a6e0034e3 100644 --- a/db/migrations/postgres/000071_upgrade_sessions_v6.1.down.sql +++ b/db/migrations/postgres/000071_upgrade_sessions_v6.1.down.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'sessions' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(64)'; IF column_exist THEN diff --git a/db/migrations/postgres/000071_upgrade_sessions_v6.1.up.sql b/db/migrations/postgres/000071_upgrade_sessions_v6.1.up.sql index d599c59759..ba995bb6a8 100644 --- a/db/migrations/postgres/000071_upgrade_sessions_v6.1.up.sql +++ b/db/migrations/postgres/000071_upgrade_sessions_v6.1.up.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'sessions' + AND table_schema = current_schema() AND column_name = 'roles' AND NOT data_type = 'varchar(256)'; IF column_exist THEN diff --git a/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.down.sql b/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.down.sql index dbb7c91f0d..f90fb6a7c8 100644 --- a/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.down.sql +++ b/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.down.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'pluginkeyvaluestore' + AND table_schema = current_schema() AND column_name = 'pkey' AND NOT data_type = 'varchar(50)'; IF column_exist THEN diff --git a/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.up.sql b/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.up.sql index 9b196d2ce5..950a9e13bb 100644 --- a/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.up.sql +++ b/db/migrations/postgres/000073_upgrade_plugin_key_value_store_v6.3.up.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'pluginkeyvaluestore' + AND table_schema = current_schema() AND column_name = 'pkey' AND NOT data_type = 'varchar(150)'; IF column_exist THEN diff --git a/db/migrations/postgres/000076_upgrade_lastrootpostat.up.sql b/db/migrations/postgres/000076_upgrade_lastrootpostat.up.sql index 4d8a542f52..6378a08db3 100644 --- a/db/migrations/postgres/000076_upgrade_lastrootpostat.up.sql +++ b/db/migrations/postgres/000076_upgrade_lastrootpostat.up.sql @@ -3,7 +3,7 @@ BEGIN IF ( SELECT count(*) FROM information_schema.columns - WHERE table_schema='public' + WHERE table_schema=current_schema() AND table_name='channels' AND column_name='lastrootpostat' AND (column_default IS NULL OR column_default != '''0''::bigint') diff --git a/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.down.sql b/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.down.sql index 163eb60aff..59faa51046 100644 --- a/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.down.sql +++ b/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.down.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'oauthapps' + AND table_schema = current_schema() AND column_name = 'mattermostappid'; IF column_exist THEN ALTER TABLE OAuthApps ALTER COLUMN MattermostAppID DROP NOT NULL; diff --git a/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.up.sql b/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.up.sql index 7192a87385..45837769fa 100644 --- a/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.up.sql +++ b/db/migrations/postgres/000082_upgrade_oauth_mattermost_app_id.up.sql @@ -5,6 +5,7 @@ BEGIN SELECT count(*) != 0 INTO column_exist FROM information_schema.columns WHERE table_name = 'oauthapps' + AND table_schema = current_schema() AND column_name = 'mattermostappid'; IF column_exist THEN UPDATE OAuthApps SET MattermostAppID = '' WHERE MattermostAppID IS NULL; diff --git a/db/migrations/postgres/000088_remaining_migrations.up.sql b/db/migrations/postgres/000088_remaining_migrations.up.sql index 9a2e4652bb..246a408920 100644 --- a/db/migrations/postgres/000088_remaining_migrations.up.sql +++ b/db/migrations/postgres/000088_remaining_migrations.up.sql @@ -10,6 +10,7 @@ BEGIN SELECT count(*) != 0 INTO col_exist FROM information_schema.columns WHERE table_name = 'users' + AND table_schema = current_schema() AND column_name = 'themeprops'; IF col_exist THEN From 2171ad8abf655445af50f4bfdabf74b41677287f Mon Sep 17 00:00:00 2001 From: Shivashis Padhi Date: Mon, 14 Nov 2022 10:27:47 +0530 Subject: [PATCH 19/32] [MM-46216] P3 Bugfix - Oauth redirectURI with query parameters generates malformed redirect URL (#20854) * Parse and reconstruct URI, instead of using string concatenation * Rename parse error, add test Co-authored-by: Mattermod --- app/oauth.go | 19 +++++++++++++++---- web/oauth_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/app/oauth.go b/app/oauth.go index c0ca0484b4..7b5b37723d 100644 --- a/app/oauth.go +++ b/app/oauth.go @@ -165,11 +165,22 @@ func (a *App) GetOAuthCodeRedirect(userID string, authRequest *model.AuthorizeRe authData := &model.AuthData{UserId: userID, ClientId: authRequest.ClientId, CreateAt: model.GetMillis(), RedirectUri: authRequest.RedirectURI, State: authRequest.State, Scope: authRequest.Scope} authData.Code = model.NewId() + model.NewId() - if _, err := a.Srv().Store().OAuth().SaveAuthData(authData); err != nil { - return authRequest.RedirectURI + "?error=server_error&state=" + authRequest.State, nil + // parse authRequest.RedirectURI to handle query parameters see: https://mattermost.atlassian.net/browse/MM-46216 + uri, err := url.Parse(authRequest.RedirectURI) + if err != nil { + return authRequest.RedirectURI + "?error=redirect_uri_parse_error&state=" + authRequest.State, nil } - - return authRequest.RedirectURI + "?code=" + url.QueryEscape(authData.Code) + "&state=" + url.QueryEscape(authData.State), nil + queryParams := uri.Query() + if _, err := a.Srv().Store().OAuth().SaveAuthData(authData); err != nil { + queryParams.Set("error", "server_error") + queryParams.Set("state", authRequest.State) + uri.RawQuery = queryParams.Encode() + return uri.String(), nil + } + queryParams.Set("code", url.QueryEscape(authData.Code)) + queryParams.Set("state", url.QueryEscape(authData.State)) + uri.RawQuery = queryParams.Encode() + return uri.String(), nil } func (a *App) AllowOAuthAppAccessToUser(userID string, authRequest *model.AuthorizeRequest) (string, *model.AppError) { diff --git a/web/oauth_test.go b/web/oauth_test.go index 6531290300..026807dcda 100644 --- a/web/oauth_test.go +++ b/web/oauth_test.go @@ -137,6 +137,35 @@ func TestAuthorizeOAuthApp(t *testing.T) { _, resp, err = apiClient.AuthorizeOAuthApp(authRequest) require.Error(t, err) CheckNotFoundStatus(t, resp) + + // test callback URI doesn't have malformed query parameters + oappWithQueryParamInCallback := &model.OAuthApp{ + Name: GenerateTestAppName(), + Homepage: "https://nowhere.com", + Description: "test", + CallbackUrls: []string{"https://nowhere.com?simply=lovely"}, + CreatorId: th.SystemAdminUser.Id, + } + + rapp, appErr = th.App.CreateOAuthApp(oappWithQueryParamInCallback) + require.Nil(t, appErr) + + authRequest = &model.AuthorizeRequest{ + ResponseType: model.AuthCodeResponseType, + ClientId: rapp.Id, + RedirectURI: rapp.CallbackUrls[0], + Scope: "", + State: "123", + } + uriResponse, _, err := apiClient.AuthorizeOAuthApp(authRequest) + require.NoError(t, err) + ru, _ = url.Parse(uriResponse) + require.NotEmpty(t, uriResponse, "redirect url should be set") + require.NotNil(t, ru, "redirect url unparseable") + // require no query parameter to have "?" + require.False(t, strings.Contains(ru.RawQuery, "?"), "should not malform query parameters") + require.NotEmpty(t, ru.Query().Get("code"), "authorization code not returned") + require.Equal(t, ru.Query().Get("state"), authRequest.State, "returned state doesn't match") } func TestDeauthorizeOAuthApp(t *testing.T) { From 9f9e19e05dc0a6466fd333228d7cdc45f5711994 Mon Sep 17 00:00:00 2001 From: Shota Gvinepadze Date: Tue, 15 Nov 2022 00:57:04 +0400 Subject: [PATCH 20/32] [MM-48161] Change data types for collections and topics (#21634) * Change data types for collections and topics * Address suggestions Co-authored-by: Mattermod --- app/channels.go | 12 ++++++------ app/collection.go | 26 ++++++++------------------ app/plugin.go | 15 ++++++++++++--- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/app/channels.go b/app/channels.go index ea84b478fe..2c9f1cee51 100644 --- a/app/channels.go +++ b/app/channels.go @@ -78,10 +78,10 @@ type Channels struct { postReminderMut sync.Mutex postReminderTask *model.ScheduledTask - // collectionTypes maps collection types array to the registering plugin - collectionTypes map[string][]string - // topicTypes maps topic types array to collection types - topicTypes map[string][]string + // collectionTypes maps from collection types to the registering plugin id + collectionTypes map[string]string + // topicTypes maps from topic types to collection types + topicTypes map[string]string collectionAndTopicTypesMut sync.Mutex } @@ -103,8 +103,8 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) { srv: s, imageProxy: imageproxy.MakeImageProxy(s.platform, s.httpService, s.Log()), uploadLockMap: map[string]bool{}, - collectionTypes: map[string][]string{}, - topicTypes: map[string][]string{}, + collectionTypes: map[string]string{}, + topicTypes: map[string]string{}, } // To get another service: diff --git a/app/collection.go b/app/collection.go index 73fb5ce866..9b895e3bc0 100644 --- a/app/collection.go +++ b/app/collection.go @@ -8,7 +8,6 @@ import ( "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/shared/mlog" - "github.com/mattermost/mattermost-server/v6/utils" ) func (a *App) registerCollectionAndTopic(pluginID, collectionType, topicType string) error { @@ -17,29 +16,20 @@ func (a *App) registerCollectionAndTopic(pluginID, collectionType, topicType str defer a.ch.collectionAndTopicTypesMut.Unlock() // check if collectionType was already registered by other plugin - for existingPluginID, existingCollectionTypes := range a.ch.collectionTypes { - if existingPluginID != pluginID && utils.StringInSlice(collectionType, existingCollectionTypes) { - return model.NewAppError("registerCollectionAndTopic", "app.collection.add_collection.exists.app_error", nil, "", http.StatusBadRequest) - } + existingPluginID, ok := a.ch.collectionTypes[collectionType] + if ok && existingPluginID != pluginID { + return model.NewAppError("registerCollectionAndTopic", "app.collection.add_collection.exists.app_error", nil, "", http.StatusBadRequest) } // check if topicType was already registered to other collection - for existingCollectionType, existingTopicTypes := range a.ch.topicTypes { - if existingCollectionType != collectionType && utils.StringInSlice(topicType, existingTopicTypes) { - return model.NewAppError("registerCollectionAndTopic", "app.collection.add_topic.exists.app_error", nil, "", http.StatusBadRequest) - } + existingCollectionType, ok := a.ch.topicTypes[topicType] + if ok && existingCollectionType != collectionType { + return model.NewAppError("registerCollectionAndTopic", "app.collection.add_topic.exists.app_error", nil, "", http.StatusBadRequest) } - a.ch.collectionTypes[pluginID] = appendIfUnique(a.ch.collectionTypes[pluginID], collectionType) - a.ch.topicTypes[collectionType] = appendIfUnique(a.ch.topicTypes[collectionType], topicType) + a.ch.collectionTypes[collectionType] = pluginID + a.ch.topicTypes[topicType] = collectionType a.ch.srv.Log().Info("registered collection and topic type", mlog.String("plugin_id", pluginID), mlog.String("collection_type", collectionType), mlog.String("topic_type", topicType)) return nil } - -func appendIfUnique(slice []string, a string) []string { - if utils.StringInSlice(a, slice) { - return slice - } - return append(slice, a) -} diff --git a/app/plugin.go b/app/plugin.go index 3942ba7014..b9042330bf 100644 --- a/app/plugin.go +++ b/app/plugin.go @@ -486,10 +486,19 @@ func (a *App) DisablePlugin(id string) *model.AppError { } func (ch *Channels) disablePlugin(id string) *model.AppError { - for _, collectionType := range ch.collectionTypes[id] { - delete(ch.topicTypes, collectionType) + // find all collectionTypes registered by plugin + for collectionTypeToRemove, existingPluginId := range ch.collectionTypes { + if existingPluginId != id { + continue + } + // find all topicTypes for existing collectionType + for topicTypeToRemove, existingCollectionType := range ch.topicTypes { + if existingCollectionType == collectionTypeToRemove { + delete(ch.topicTypes, topicTypeToRemove) + } + } + delete(ch.collectionTypes, collectionTypeToRemove) } - delete(ch.collectionTypes, id) pluginsEnvironment := ch.GetPluginsEnvironment() if pluginsEnvironment == nil { From 10bdea85a5cd09c45521ae01b027881ea09f5d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Garc=C3=ADa=20Montoro?= Date: Tue, 15 Nov 2022 10:52:54 +0100 Subject: [PATCH 21/32] Skip flaky test in TestRequestTrialLicense (#21665) Co-authored-by: Mattermod --- api4/license_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/api4/license_test.go b/api4/license_test.go index dbf0e62bfc..d11fe1b150 100644 --- a/api4/license_test.go +++ b/api4/license_test.go @@ -242,6 +242,7 @@ func TestRequestTrialLicense(t *testing.T) { }) t.Run("trial license user count less than current users", func(t *testing.T) { + t.Skip("MM-48416") nUsers := 1 license := model.NewTestLicense() license.Features.Users = model.NewInt(nUsers) From ab5137395cea997f78498caec9bbbe8af224125a Mon Sep 17 00:00:00 2001 From: Mattermod Date: Tue, 15 Nov 2022 20:28:52 +0200 Subject: [PATCH 22/32] Update minor version to 7.6.0 (#21664) Automatic Merge --- model/version.go | 1 + 1 file changed, 1 insertion(+) diff --git a/model/version.go b/model/version.go index 4bfc461767..b2a37dcda6 100644 --- a/model/version.go +++ b/model/version.go @@ -13,6 +13,7 @@ import ( // It should be maintained in chronological order with most current // release at the front of the list. var versions = []string{ + "7.6.0", "7.5.0", "7.4.0", "7.3.0", From 98e685f07cc49182b1450170975684bda14e32de Mon Sep 17 00:00:00 2001 From: Shota Gvinepadze Date: Wed, 16 Nov 2022 13:42:26 +0400 Subject: [PATCH 23/32] Move Thread.GetPosts to PostStore.GetPostsByThread (#21633) Co-authored-by: Mattermod --- app/post.go | 2 +- store/opentracinglayer/opentracinglayer.go | 36 +++++++++---------- store/retrylayer/retrylayer.go | 42 +++++++++++----------- store/sqlstore/post_store.go | 17 +++++++++ store/sqlstore/thread_store.go | 17 --------- store/store.go | 2 +- store/storetest/mocks/PostStore.go | 23 ++++++++++++ store/storetest/mocks/ThreadStore.go | 23 ------------ store/timerlayer/timerlayer.go | 32 ++++++++--------- 9 files changed, 97 insertions(+), 97 deletions(-) diff --git a/app/post.go b/app/post.go index ff6cab3397..78d14b16ef 100644 --- a/app/post.go +++ b/app/post.go @@ -1685,7 +1685,7 @@ func (a *App) countThreadMentions(c request.CTX, user *model.User, post *model.P true, // Assume channel mentions are always allowed for simplicity ) - posts, nErr := a.Srv().Store().Thread().GetPosts(post.Id, timestamp) + posts, nErr := a.Srv().Store().Post().GetPostsByThread(post.Id, timestamp) if nErr != nil { return 0, model.NewAppError("countMentionsFromPost", "app.channel.count_posts_since.app_error", nil, "", http.StatusInternalServerError).Wrap(nErr) } diff --git a/store/opentracinglayer/opentracinglayer.go b/store/opentracinglayer/opentracinglayer.go index 614a3933fe..b500b0cb53 100644 --- a/store/opentracinglayer/opentracinglayer.go +++ b/store/opentracinglayer/opentracinglayer.go @@ -6089,6 +6089,24 @@ func (s *OpenTracingLayerPostStore) GetPostsByIds(postIds []string) ([]*model.Po return result, err } +func (s *OpenTracingLayerPostStore) GetPostsByThread(threadID string, since int64) ([]*model.Post, error) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetPostsByThread") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + result, err := s.PostStore.GetPostsByThread(threadID, since) + if err != nil { + span.LogFields(spanlog.Error(err)) + ext.Error.Set(span, true) + } + + return result, err +} + func (s *OpenTracingLayerPostStore) GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetPostsCreatedAt") @@ -9836,24 +9854,6 @@ func (s *OpenTracingLayerThreadStore) GetMembershipsForUser(userId string, teamI return result, err } -func (s *OpenTracingLayerThreadStore) GetPosts(threadID string, since int64) ([]*model.Post, error) { - origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ThreadStore.GetPosts") - s.Root.Store.SetContext(newCtx) - defer func() { - s.Root.Store.SetContext(origCtx) - }() - - defer span.Finish() - result, err := s.ThreadStore.GetPosts(threadID, since) - if err != nil { - span.LogFields(spanlog.Error(err)) - ext.Error.Set(span, true) - } - - return result, err -} - func (s *OpenTracingLayerThreadStore) GetTeamsUnreadForUser(userID string, teamIDs []string) (map[string]*model.TeamUnread, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ThreadStore.GetTeamsUnreadForUser") diff --git a/store/retrylayer/retrylayer.go b/store/retrylayer/retrylayer.go index 03043d870e..3e6fcb0b31 100644 --- a/store/retrylayer/retrylayer.go +++ b/store/retrylayer/retrylayer.go @@ -6900,6 +6900,27 @@ func (s *RetryLayerPostStore) GetPostsByIds(postIds []string) ([]*model.Post, er } +func (s *RetryLayerPostStore) GetPostsByThread(threadID string, since int64) ([]*model.Post, error) { + + tries := 0 + for { + result, err := s.PostStore.GetPostsByThread(threadID, since) + if err == nil { + return result, nil + } + if !isRepeatableError(err) { + return result, err + } + tries++ + if tries >= 3 { + err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") + return result, err + } + timepkg.Sleep(100 * timepkg.Millisecond) + } + +} + func (s *RetryLayerPostStore) GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error) { tries := 0 @@ -11244,27 +11265,6 @@ func (s *RetryLayerThreadStore) GetMembershipsForUser(userId string, teamID stri } -func (s *RetryLayerThreadStore) GetPosts(threadID string, since int64) ([]*model.Post, error) { - - tries := 0 - for { - result, err := s.ThreadStore.GetPosts(threadID, since) - if err == nil { - return result, nil - } - if !isRepeatableError(err) { - return result, err - } - tries++ - if tries >= 3 { - err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") - return result, err - } - timepkg.Sleep(100 * timepkg.Millisecond) - } - -} - func (s *RetryLayerThreadStore) GetTeamsUnreadForUser(userID string, teamIDs []string) (map[string]*model.TeamUnread, error) { tries := 0 diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go index a11a3ee347..127e566861 100644 --- a/store/sqlstore/post_store.go +++ b/store/sqlstore/post_store.go @@ -1400,6 +1400,23 @@ func (s *SqlPostStore) GetPostsAfter(options model.GetPostsOptions, sanitizeOpti return s.getPostsAround(false, options, sanitizeOptions) } +func (s *SqlPostStore) GetPostsByThread(threadId string, since int64) ([]*model.Post, error) { + query := s.getQueryBuilder(). + Select("*"). + From("Posts"). + Where(sq.Eq{"RootId": threadId}). + Where(sq.Eq{"DeleteAt": 0}). + Where(sq.GtOrEq{"CreateAt": since}) + + result := []*model.Post{} + err := s.GetReplicaX().SelectBuilder(&result, query) + if err != nil { + return nil, errors.Wrap(err, "failed to fetch thread posts") + } + + return result, nil +} + func (s *SqlPostStore) getPostsAround(before bool, options model.GetPostsOptions, sanitizeOptions map[string]bool) (*model.PostList, error) { if options.Page < 0 { return nil, store.NewErrInvalidInput("Post", "", options.Page) diff --git a/store/sqlstore/thread_store.go b/store/sqlstore/thread_store.go index 502be5e354..e314e82093 100644 --- a/store/sqlstore/thread_store.go +++ b/store/sqlstore/thread_store.go @@ -779,23 +779,6 @@ func (s *SqlThreadStore) MaintainMembership(userId, postId string, opts store.Th return membership, err } -func (s *SqlThreadStore) GetPosts(threadId string, since int64) ([]*model.Post, error) { - query := s.getQueryBuilder(). - Select("*"). - From("Posts"). - Where(sq.Eq{"RootId": threadId}). - Where(sq.Eq{"DeleteAt": 0}). - Where(sq.GtOrEq{"CreateAt": since}) - - result := []*model.Post{} - err := s.GetReplicaX().SelectBuilder(&result, query) - if err != nil { - return nil, errors.Wrap(err, "failed to fetch thread posts") - } - - return result, nil -} - // PermanentDeleteBatchForRetentionPolicies deletes a batch of records which are affected by // the global or a granular retention policy. // See `genericPermanentDeleteBatchForRetentionPolicies` for details. diff --git a/store/store.go b/store/store.go index 805c972e27..77092a2aed 100644 --- a/store/store.go +++ b/store/store.go @@ -325,7 +325,6 @@ type ThreadStore interface { GetThreadsForUser(userId, teamID string, opts model.GetUserThreadsOpts) ([]*model.ThreadResponse, error) GetThreadForUser(threadMembership *model.ThreadMembership, extended bool) (*model.ThreadResponse, error) GetTeamsUnreadForUser(userID string, teamIDs []string) (map[string]*model.TeamUnread, error) - GetPosts(threadID string, since int64) ([]*model.Post, error) MarkAllAsRead(userID string, threadIds []string) error MarkAllAsReadByTeam(userID, teamID string) error @@ -364,6 +363,7 @@ type PostStore interface { GetPostsBefore(options model.GetPostsOptions, sanitizeOptions map[string]bool) (*model.PostList, error) GetPostsAfter(options model.GetPostsOptions, sanitizeOptions map[string]bool) (*model.PostList, error) GetPostsSince(options model.GetPostsSinceOptions, allowFromCache bool, sanitizeOptions map[string]bool) (*model.PostList, error) + GetPostsByThread(threadID string, since int64) ([]*model.Post, error) GetPostAfterTime(channelID string, timestamp int64, collapsedThreads bool) (*model.Post, error) GetPostIdAfterTime(channelID string, timestamp int64, collapsedThreads bool) (string, error) GetPostIdBeforeTime(channelID string, timestamp int64, collapsedThreads bool) (string, error) diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go index ef455c82b3..91e39efb45 100644 --- a/store/storetest/mocks/PostStore.go +++ b/store/storetest/mocks/PostStore.go @@ -603,6 +603,29 @@ func (_m *PostStore) GetPostsByIds(postIds []string) ([]*model.Post, error) { return r0, r1 } +// GetPostsByThread provides a mock function with given fields: threadID, since +func (_m *PostStore) GetPostsByThread(threadID string, since int64) ([]*model.Post, error) { + ret := _m.Called(threadID, since) + + var r0 []*model.Post + if rf, ok := ret.Get(0).(func(string, int64) []*model.Post); ok { + r0 = rf(threadID, since) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Post) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string, int64) error); ok { + r1 = rf(threadID, since) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetPostsCreatedAt provides a mock function with given fields: channelID, timestamp func (_m *PostStore) GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error) { ret := _m.Called(channelID, timestamp) diff --git a/store/storetest/mocks/ThreadStore.go b/store/storetest/mocks/ThreadStore.go index bfacea3709..19d82db686 100644 --- a/store/storetest/mocks/ThreadStore.go +++ b/store/storetest/mocks/ThreadStore.go @@ -119,29 +119,6 @@ func (_m *ThreadStore) GetMembershipsForUser(userId string, teamID string) ([]*m return r0, r1 } -// GetPosts provides a mock function with given fields: threadID, since -func (_m *ThreadStore) GetPosts(threadID string, since int64) ([]*model.Post, error) { - ret := _m.Called(threadID, since) - - var r0 []*model.Post - if rf, ok := ret.Get(0).(func(string, int64) []*model.Post); ok { - r0 = rf(threadID, since) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*model.Post) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, int64) error); ok { - r1 = rf(threadID, since) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetTeamsUnreadForUser provides a mock function with given fields: userID, teamIDs func (_m *ThreadStore) GetTeamsUnreadForUser(userID string, teamIDs []string) (map[string]*model.TeamUnread, error) { ret := _m.Called(userID, teamIDs) diff --git a/store/timerlayer/timerlayer.go b/store/timerlayer/timerlayer.go index deb0dbc224..16f6044d24 100644 --- a/store/timerlayer/timerlayer.go +++ b/store/timerlayer/timerlayer.go @@ -5508,6 +5508,22 @@ func (s *TimerLayerPostStore) GetPostsByIds(postIds []string) ([]*model.Post, er return result, err } +func (s *TimerLayerPostStore) GetPostsByThread(threadID string, since int64) ([]*model.Post, error) { + start := time.Now() + + result, err := s.PostStore.GetPostsByThread(threadID, since) + + elapsed := float64(time.Since(start)) / float64(time.Second) + if s.Root.Metrics != nil { + success := "false" + if err == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("PostStore.GetPostsByThread", success, elapsed) + } + return result, err +} + func (s *TimerLayerPostStore) GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error) { start := time.Now() @@ -8849,22 +8865,6 @@ func (s *TimerLayerThreadStore) GetMembershipsForUser(userId string, teamID stri return result, err } -func (s *TimerLayerThreadStore) GetPosts(threadID string, since int64) ([]*model.Post, error) { - start := time.Now() - - result, err := s.ThreadStore.GetPosts(threadID, since) - - elapsed := float64(time.Since(start)) / float64(time.Second) - if s.Root.Metrics != nil { - success := "false" - if err == nil { - success = "true" - } - s.Root.Metrics.ObserveStoreMethodDuration("ThreadStore.GetPosts", success, elapsed) - } - return result, err -} - func (s *TimerLayerThreadStore) GetTeamsUnreadForUser(userID string, teamIDs []string) (map[string]*model.TeamUnread, error) { start := time.Now() From be46be4985c1bc0a42003df58a2e10abe701e632 Mon Sep 17 00:00:00 2001 From: Miguel de la Cruz Date: Wed, 16 Nov 2022 19:54:15 +0100 Subject: [PATCH 24/32] Prepackage boards v7.5.1 (#21681) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c5f0d17e5a..85e41e0564 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ PLUGIN_PACKAGES += mattermost-plugin-jira-v2.4.0 PLUGIN_PACKAGES += mattermost-plugin-nps-v1.3.0 PLUGIN_PACKAGES += mattermost-plugin-welcomebot-v1.2.0 PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.6.0 -PLUGIN_PACKAGES += focalboard-v7.5.0 +PLUGIN_PACKAGES += focalboard-v7.5.1 PLUGIN_PACKAGES += mattermost-plugin-apps-v1.1.0 # Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target From 17332035fa0c545cd1c88cd1b2a9b9f820204bce Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 17 Nov 2022 09:27:08 +0530 Subject: [PATCH 25/32] MM-47034: Update dependencies (#21676) https://mattermost.atlassian.net/browse/MM-47034 ```release-note NONE ``` --- Makefile | 9 +++ go.mod | 94 +++++++++++------------ go.sum | 228 ++++++++++++++++++++++++++++--------------------------- 3 files changed, 174 insertions(+), 157 deletions(-) diff --git a/Makefile b/Makefile index 85e41e0564..01bfbbc6da 100644 --- a/Makefile +++ b/Makefile @@ -725,6 +725,11 @@ ifeq ($(BUILD_ENTERPRISE_READY),true) rm -f imports/imports.go endif +ifeq ($(BUILD_BOARDS),true) + @echo Boards repository detected, temporarily removing boards_imports.go + rm -f imports/boards_imports.go +endif + # Update all dependencies (does not update across major versions) $(GO) get -u ./... @@ -735,6 +740,10 @@ ifeq ($(BUILD_ENTERPRISE_READY),true) cp $(BUILD_ENTERPRISE_DIR)/imports/imports.go imports/ endif +ifeq ($(BUILD_BOARDS),true) + cp $(BUILD_BOARDS_DIR)/mattermost-plugin/product/imports/boards_imports.go imports/ +endif + vet: ## Run mattermost go vet specific checks $(GO) install github.com/mattermost/mattermost-govet/v2@new @VET_CMD="-license -structuredLogging -inconsistentReceiverName -inconsistentReceiverName.ignore=session_serial_gen.go,team_member_serial_gen.go,user_serial_gen.go -emptyStrCmp -tFatal -configtelemetry -errorAssertions"; \ diff --git a/go.mod b/go.mod index 7c32d4b045..f3b7d99808 100644 --- a/go.mod +++ b/go.mod @@ -3,20 +3,20 @@ module github.com/mattermost/mattermost-server/v6 go 1.18 require ( - code.sajari.com/docconv v1.2.1 + code.sajari.com/docconv v1.3.5 github.com/Masterminds/semver/v3 v3.1.1 github.com/avct/uasurfer v0.0.0-20191028135549-26b5daa857f1 - github.com/aws/aws-sdk-go v1.44.79 + github.com/aws/aws-sdk-go v1.44.138 github.com/blang/semver v3.5.1+incompatible - github.com/blevesearch/bleve/v2 v2.3.4-0.20220810122446-d89c6c0a6873 + github.com/blevesearch/bleve/v2 v2.3.6-0.20221111171245-56dc9b25507e github.com/cespare/xxhash/v2 v2.1.2 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3 github.com/disintegration/imaging v1.6.2 github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a github.com/francoispqt/gojay v1.2.13 - github.com/fsnotify/fsnotify v1.5.4 - github.com/getsentry/sentry-go v0.13.0 + github.com/fsnotify/fsnotify v1.6.0 + github.com/getsentry/sentry-go v0.15.0 github.com/go-sql-driver/mysql v1.6.0 github.com/golang-migrate/migrate/v4 v4.15.2 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 @@ -27,33 +27,33 @@ require ( github.com/graph-gophers/dataloader/v6 v6.0.0 github.com/graph-gophers/graphql-go v1.4.0 github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c - github.com/hashicorp/go-hclog v1.2.2 - github.com/hashicorp/go-plugin v1.4.4 + github.com/hashicorp/go-hclog v1.3.1 + github.com/hashicorp/go-plugin v1.4.6 github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba github.com/jmoiron/sqlx v1.3.5 github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 - github.com/lib/pq v1.10.6 + github.com/lib/pq v1.10.7 github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 github.com/mattermost/gziphandler v0.0.1 github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d github.com/mattermost/logr/v2 v2.0.15 - github.com/mattermost/morph v0.0.0-20220804124441-62627668af80 + github.com/mattermost/morph v1.0.4 github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0 github.com/mattermost/squirrel v0.2.0 github.com/mholt/archiver/v3 v3.5.1 - github.com/microcosm-cc/bluemonday v1.0.19 - github.com/minio/minio-go/v7 v7.0.34 + github.com/microcosm-cc/bluemonday v1.0.21 + github.com/minio/minio-go/v7 v7.0.43 github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb github.com/opentracing/opentracing-go v1.2.0 github.com/pborman/uuid v1.2.1 github.com/pkg/errors v0.9.1 github.com/reflog/dateconstraints v0.2.1 github.com/rs/cors v1.8.2 - github.com/rudderlabs/analytics-go v3.3.2+incompatible + github.com/rudderlabs/analytics-go v3.3.3+incompatible github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd - github.com/spf13/cobra v1.5.0 - github.com/splitio/go-client/v6 v6.1.7 - github.com/stretchr/testify v1.8.0 + github.com/spf13/cobra v1.6.1 + github.com/splitio/go-client/v6 v6.2.1 + github.com/stretchr/testify v1.8.1 github.com/throttled/throttled v2.2.5+incompatible github.com/tinylib/msgp v1.1.6 github.com/uber/jaeger-client-go v2.30.0+incompatible @@ -61,20 +61,20 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.5 github.com/wiggin77/merror v1.0.4 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c - github.com/yuin/goldmark v1.4.13 - golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 - golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 - golang.org/x/net v0.0.0-20220812174116-3211cb980234 - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 - golang.org/x/text v0.3.7 - golang.org/x/tools v0.1.12 + github.com/yuin/goldmark v1.5.3 + golang.org/x/crypto v0.2.0 + golang.org/x/image v0.1.0 + golang.org/x/net v0.2.0 + golang.org/x/sync v0.1.0 + golang.org/x/text v0.4.0 + golang.org/x/tools v0.3.0 gopkg.in/mail.v2 v2.3.1 gopkg.in/yaml.v2 v2.4.0 ) require ( github.com/HdrHistogram/hdrhistogram-go v0.9.0 // indirect - github.com/JalfResi/justext v0.0.0-20170829062021-c0282dea7198 // indirect + github.com/JalfResi/justext v0.0.0-20221106200834-be571e3e3052 // indirect github.com/PuerkitoBio/goquery v1.8.0 // indirect github.com/RoaringBitmap/roaring v1.2.1 // indirect github.com/advancedlogic/GoOse v0.0.0-20210820140952-9d5822d4a625 // indirect @@ -82,22 +82,23 @@ require ( github.com/andybalholm/cascadia v1.3.1 // indirect github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/bits-and-blooms/bitset v1.3.0 // indirect - github.com/blevesearch/bleve_index_api v1.0.3 // indirect - github.com/blevesearch/geo v0.1.14 // indirect + github.com/bits-and-blooms/bitset v1.3.3 // indirect + github.com/bits-and-blooms/bloom/v3 v3.3.1 // indirect + github.com/blevesearch/bleve_index_api v1.0.5 // indirect + github.com/blevesearch/geo v0.1.15 // indirect github.com/blevesearch/go-porterstemmer v1.0.3 // indirect github.com/blevesearch/gtreap v0.1.1 // indirect github.com/blevesearch/mmap-go v1.0.4 // indirect - github.com/blevesearch/scorch_segment_api/v2 v2.1.2 // indirect + github.com/blevesearch/scorch_segment_api/v2 v2.1.4 // indirect github.com/blevesearch/segment v0.9.0 // indirect github.com/blevesearch/snowballstem v0.9.0 // indirect github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect - github.com/blevesearch/vellum v1.0.8 // indirect - github.com/blevesearch/zapx/v11 v11.3.5 // indirect - github.com/blevesearch/zapx/v12 v12.3.5 // indirect - github.com/blevesearch/zapx/v13 v13.3.5 // indirect - github.com/blevesearch/zapx/v14 v14.3.5 // indirect - github.com/blevesearch/zapx/v15 v15.3.5-0.20220805051919-e14ad3bf63e7 // indirect + github.com/blevesearch/vellum v1.0.9 // indirect + github.com/blevesearch/zapx/v11 v11.3.7 // indirect + github.com/blevesearch/zapx/v12 v12.3.7 // indirect + github.com/blevesearch/zapx/v13 v13.3.7 // indirect + github.com/blevesearch/zapx/v14 v14.3.7 // indirect + github.com/blevesearch/zapx/v15 v15.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect @@ -121,8 +122,8 @@ require ( github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.15.9 // indirect - github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.1 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect @@ -130,7 +131,7 @@ require ( github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -144,34 +145,33 @@ require ( github.com/otiai10/gosseract/v2 v2.4.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/philhofer/fwd v1.1.1 // indirect - github.com/pierrec/lz4/v4 v4.1.15 // indirect + github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect - github.com/rivo/uniseg v0.3.4 // indirect + github.com/rivo/uniseg v0.4.3 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/rs/xid v1.4.0 // indirect github.com/segmentio/backo-go v1.0.1 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/splitio/go-split-commons/v4 v4.1.3 // indirect - github.com/splitio/go-toolkit/v5 v5.2.1 // indirect + github.com/splitio/go-split-commons/v4 v4.2.2 // indirect + github.com/splitio/go-toolkit/v5 v5.2.2 // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect - github.com/stretchr/objx v0.4.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/tidwall/gjson v1.14.3 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/wiggin77/srslog v1.0.1 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.uber.org/atomic v1.10.0 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 // indirect - golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect - google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1 // indirect - google.golang.org/grpc v1.48.0 // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/sys v0.2.0 // indirect + google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1 // indirect + google.golang.org/grpc v1.50.1 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index f3ca8955dc..b19dedc445 100644 --- a/go.sum +++ b/go.sum @@ -31,14 +31,17 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/errorreporting v0.2.0/go.mod h1:QkYzg92wgpJ0ChLdcO5LhtCEyYwq0tIa+jLrj6Nh5ME= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= @@ -50,8 +53,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.sajari.com/docconv v1.2.1 h1:0gU0YSdlh2ngE3oMEtf8BKtHs2wfnHyazaz4WipN2pc= -code.sajari.com/docconv v1.2.1/go.mod h1:h8cFte+0yTd88Bje+clz1qdw5x2wIZaTJgj4MH+/ViE= +code.sajari.com/docconv v1.3.5 h1:RBBs6aT3/5gHHWzAaxBj85e3ozsu05s2kAslhW7i+Ag= +code.sajari.com/docconv v1.3.5/go.mod h1:EDkTrwa2yO2O9EbVpD3dlHXDVcxbfKDWnDNE/8vbbP8= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= @@ -80,14 +83,15 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/HdrHistogram/hdrhistogram-go v0.9.0 h1:dpujRju0R4M/QZzcnR1LH1qm+TVG3UzkWdp5tH1WMcg= github.com/HdrHistogram/hdrhistogram-go v0.9.0/go.mod h1:nxrse8/Tzg2tg3DZcZjm6qEclQKK70g0KxO61gFFZD4= -github.com/JalfResi/justext v0.0.0-20170829062021-c0282dea7198 h1:8P+AjBhGByCuCX2zTkAf6UY+dj0JczX+t6cSdCSyvfw= github.com/JalfResi/justext v0.0.0-20170829062021-c0282dea7198/go.mod h1:0SURuH1rsE8aVWvutuMZghRNrNrYEUzibzJfhEYR8L0= +github.com/JalfResi/justext v0.0.0-20221106200834-be571e3e3052 h1:8T2zMbhLBbH9514PIQVHdsGhypMrsB4CxwbldKA9sBA= +github.com/JalfResi/justext v0.0.0-20221106200834-be571e3e3052/go.mod h1:0SURuH1rsE8aVWvutuMZghRNrNrYEUzibzJfhEYR8L0= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -124,7 +128,6 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A= github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -164,8 +167,8 @@ github.com/avct/uasurfer v0.0.0-20191028135549-26b5daa857f1 h1:9h8f71kuF1pqovnn9 github.com/avct/uasurfer v0.0.0-20191028135549-26b5daa857f1/go.mod h1:noBAuukeYOXa0aXGqxr24tADqkwDO2KRD15FsuaZ5a8= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.44.79 h1:IZCtfBq9VlJ1Eu34I+2Y76q+XkvTtZYbEwaoVM1gzoA= -github.com/aws/aws-sdk-go v1.44.79/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.138 h1:9aoHAowstvD0s4cktYwT4Ok3oFLl3Hfbap8iFLamsdc= +github.com/aws/aws-sdk-go v1.44.138/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU= @@ -203,50 +206,49 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.3.0 h1:h7mv5q31cthBTd7V4kLAZaIThj1e8vPGcSqpPue9KVI= -github.com/bits-and-blooms/bitset v1.3.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.3.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg= +github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bloom/v3 v3.3.1 h1:K2+A19bXT8gJR5mU7y+1yW6hsKfNCjcP2uNfLFKncjQ= +github.com/bits-and-blooms/bloom/v3 v3.3.1/go.mod h1:bhUUknWd5khVbTe4UgMCSiOOVJzr3tMoijSK3WwvW90= github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blevesearch/bleve/v2 v2.3.4-0.20220810122446-d89c6c0a6873 h1:vMFWJMnUUNLy0WyxusEwDENGsG1j1Hd4BqnoJUsXqCY= -github.com/blevesearch/bleve/v2 v2.3.4-0.20220810122446-d89c6c0a6873/go.mod h1:GCej882S59hhEiiNV6KmW+kQYf+XUj01nnqHcKMbhVI= -github.com/blevesearch/bleve_index_api v1.0.3 h1:DDSWaPXOZZJ2BB73ZTWjKxydAugjwywcqU+91AAqcAg= +github.com/blevesearch/bleve/v2 v2.3.6-0.20221111171245-56dc9b25507e h1:r/cWPLUPgAM3SWWniQ6j0Hzb++h+uEycDD9UOUuC1Vk= +github.com/blevesearch/bleve/v2 v2.3.6-0.20221111171245-56dc9b25507e/go.mod h1:mfCWvuwg/XnPVZHEejATm5TyFqyeLmm8p9Y3xDvwz4k= github.com/blevesearch/bleve_index_api v1.0.3/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= -github.com/blevesearch/geo v0.1.13/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc= -github.com/blevesearch/geo v0.1.14 h1:TTDpJN6l9ck/cUYbXSn4aCElNls0Whe44rcQKsB7EfU= -github.com/blevesearch/geo v0.1.14/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc= -github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A= +github.com/blevesearch/bleve_index_api v1.0.5 h1:Lc986kpC4Z0/n1g3gg8ul7H+lxgOQPcXb9SxvQGu+tw= +github.com/blevesearch/bleve_index_api v1.0.5/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms= +github.com/blevesearch/geo v0.1.15 h1:0NybEduqE5fduFRYiUKF0uqybAIFKXYjkBdXKYn7oA4= +github.com/blevesearch/geo v0.1.15/go.mod h1:cRIvqCdk3cgMhGeHNNe6yPzb+w56otxbfo1FBJfR2Pc= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= -github.com/blevesearch/goleveldb v1.0.1/go.mod h1:WrU8ltZbIp0wAoig/MHbrPCXSOLpe79nz5lv5nqfYrQ= github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y= github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk= -github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA= github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= -github.com/blevesearch/scorch_segment_api/v2 v2.1.2 h1:TAte9VZLWda5WAVlZTTZ+GCzEHqGJb4iB2aiZSA6Iv8= -github.com/blevesearch/scorch_segment_api/v2 v2.1.2/go.mod h1:rvoQXZGq8drq7vXbNeyiRzdEOwZkjkiYGf1822i6CRA= +github.com/blevesearch/scorch_segment_api/v2 v2.1.4 h1:LmGmo5twU3gV+natJbKmOktS9eMhokPGKWuR+jX84vk= +github.com/blevesearch/scorch_segment_api/v2 v2.1.4/go.mod h1:PgVnbbg/t1UkgezPDu8EHLi1BHQ17xUwsFdU6NnOYS0= github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac= github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= -github.com/blevesearch/snowball v0.6.1/go.mod h1:ZF0IBg5vgpeoUhnMza2v0A/z8m1cWPlwhke08LpNusg= github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s= github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15amfX2pXlYbFOnF8zNU= github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q= -github.com/blevesearch/vellum v1.0.8 h1:iMGh4lfxza4BnWO/UJTMPlI3HsK9YawjPv+TteVa9ck= -github.com/blevesearch/vellum v1.0.8/go.mod h1:+cpRi/tqq49xUYSQN2P7A5zNSNrS+MscLeeaZ3J46UA= -github.com/blevesearch/zapx/v11 v11.3.5 h1:eBQWQ7huA+mzm0sAGnZDwgGGli7S45EO+N+ObFWssbI= -github.com/blevesearch/zapx/v11 v11.3.5/go.mod h1:5UdIa/HRMdeRCiLQOyFESsnqBGiip7vQmYReA9toevU= -github.com/blevesearch/zapx/v12 v12.3.5 h1:5pX2hU+R1aZihT7ac1dNWh1n4wqkIM9pZzWp0ANED9s= -github.com/blevesearch/zapx/v12 v12.3.5/go.mod h1:ANcthYRZQycpbRut/6ArF5gP5HxQyJqiFcuJCBju/ss= -github.com/blevesearch/zapx/v13 v13.3.5 h1:eJ3gbD+Nu8p36/O6lhfdvWQ4pxsGYSuTOBrLLPVWJ74= -github.com/blevesearch/zapx/v13 v13.3.5/go.mod h1:FV+dRnScFgKnRDIp08RQL4JhVXt1x2HE3AOzqYa6fjo= -github.com/blevesearch/zapx/v14 v14.3.5 h1:hEvVjZaagFCvOUJrlFQ6/Z6Jjy0opM3g7TMEo58TwP4= -github.com/blevesearch/zapx/v14 v14.3.5/go.mod h1:954A/eKFb+pg/ncIYWLWCKY+mIjReM9FGTGIO2Wu1cU= -github.com/blevesearch/zapx/v15 v15.3.5-0.20220805051919-e14ad3bf63e7 h1:cJlMJ9pW2iFRw9lx4289u0OO0wT6KKx/SDXhpebIlys= -github.com/blevesearch/zapx/v15 v15.3.5-0.20220805051919-e14ad3bf63e7/go.mod h1:QMUh2hXCaYIWFKPYGavq/Iga2zbHWZ9DZAa9uFbWyvg= +github.com/blevesearch/vellum v1.0.9 h1:PL+NWVk3dDGPCV0hoDu9XLLJgqU4E5s/dOeEJByQ2uQ= +github.com/blevesearch/vellum v1.0.9/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k= +github.com/blevesearch/zapx/v11 v11.3.7 h1:Y6yIAF/DVPiqZUA/jNgSLXmqewfzwHzuwfKyfdG+Xaw= +github.com/blevesearch/zapx/v11 v11.3.7/go.mod h1:Xk9Z69AoAWIOvWudNDMlxJDqSYGf90LS0EfnaAIvXCA= +github.com/blevesearch/zapx/v12 v12.3.7 h1:DfQ6rsmZfEK4PzzJJRXjiM6AObG02+HWvprlXQ1Y7eI= +github.com/blevesearch/zapx/v12 v12.3.7/go.mod h1:SgEtYIBGvM0mgIBn2/tQE/5SdrPXaJUaT/kVqpAPxm0= +github.com/blevesearch/zapx/v13 v13.3.7 h1:igIQg5eKmjw168I7av0Vtwedf7kHnQro/M+ubM4d2l8= +github.com/blevesearch/zapx/v13 v13.3.7/go.mod h1:yyrB4kJ0OT75UPZwT/zS+Ru0/jYKorCOOSY5dBzAy+s= +github.com/blevesearch/zapx/v14 v14.3.7 h1:gfe+fbWslDWP/evHLtp/GOvmNM3sw1BbqD7LhycBX20= +github.com/blevesearch/zapx/v14 v14.3.7/go.mod h1:9J/RbOkqZ1KSjmkOes03AkETX7hrXT0sFMpWH4ewC4w= +github.com/blevesearch/zapx/v15 v15.3.7 h1:r8ZcNrlcMj2TmLlbNH16wZiL9reU0s7C2rAQKjFDtuE= +github.com/blevesearch/zapx/v15 v15.3.7/go.mod h1:m7Y6m8soYUvS7MjN9eKlz1xrLCcmqfFadmu7GhWIrLY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -397,7 +399,6 @@ github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= @@ -414,9 +415,6 @@ github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k= -github.com/couchbase/moss v0.2.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -486,7 +484,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -511,16 +508,16 @@ github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiD github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/gabriel-vasile/mimetype v1.3.1/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= -github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= +github.com/getsentry/sentry-go v0.15.0 h1:CP9bmA7pralrVUedYZsmIHWpq/pBtXTSew7xvVpfLaA= +github.com/getsentry/sentry-go v0.15.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573 h1:u8AQ9bPa9oC+8/A/jlWouakhIvkFfuxgIIRjiy8av7I= @@ -529,8 +526,8 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev github.com/go-asn1-ber/asn1-ber v1.3.2-0.20191121212151-29be175fc3a3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= @@ -669,7 +666,6 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -693,8 +689,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE= @@ -782,16 +778,16 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v1.2.2 h1:ihRI7YFwcZdiSD7SIenIhHfQH3OuDvWerAUBZbeQS3M= -github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= +github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= -github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/go-plugin v1.4.6 h1:MDV3UrKQBM3du3G7MApDGvOsMYy3JQJ4exhSoKBAeVA= +github.com/hashicorp/go-plugin v1.4.6/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -924,13 +920,13 @@ github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdY github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= +github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -965,8 +961,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= -github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= @@ -990,8 +986,8 @@ github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d h1:/RJ/UV7M5c7L2TQ github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ= github.com/mattermost/logr/v2 v2.0.15 h1:+WNbGcsc3dBao65eXlceB6dTILNJRIrvubnsTl3zBew= github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXpNh0k/y8Hmwg= -github.com/mattermost/morph v0.0.0-20220804124441-62627668af80 h1:Sip/imqvGBi2XZiN/bfHjQ6T/UEvaRwqjFzy4PX9lQk= -github.com/mattermost/morph v0.0.0-20220804124441-62627668af80/go.mod h1:xo0ljDknTpPxEdhhrUdwhLCexIsYyDKS6b41HqG8wGU= +github.com/mattermost/morph v1.0.4 h1:isy1ryN9Re3MJKEyHwjRkFeM2a6cSJ76Pl6g4rCkLQY= +github.com/mattermost/morph v1.0.4/go.mod h1:xo0ljDknTpPxEdhhrUdwhLCexIsYyDKS6b41HqG8wGU= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0 h1:G9tL6JXRBMzjuD1kkBtcnd42kUiT6QDwxfFYu7adM6o= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs= github.com/mattermost/squirrel v0.2.0 h1:8ZWeyf+MWQ2cL7hu9REZgLtz2IJi51qqZEovI3T3TT8= @@ -1021,8 +1017,8 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= @@ -1038,14 +1034,14 @@ github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88J github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= -github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= +github.com/microcosm-cc/bluemonday v1.0.21 h1:dNH3e4PSyE4vNX+KlRGHT5KrSvjeUkoNPwEORjffHJg= +github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.34 h1:JMfS5fudx1mN6V2MMNyCJ7UMrjEzZzIvMgfkWc1Vnjk= -github.com/minio/minio-go/v7 v7.0.34/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= +github.com/minio/minio-go/v7 v7.0.43 h1:14Q4lwblqTdlAmba05oq5xL0VBLHi06zS4yLnIkz6hI= +github.com/minio/minio-go/v7 v7.0.43/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -1113,7 +1109,6 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1128,7 +1123,6 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042 github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -1198,8 +1192,8 @@ github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc= +github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= @@ -1262,8 +1256,8 @@ github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= -github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1279,8 +1273,8 @@ github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rudderlabs/analytics-go v3.3.2+incompatible h1:bDajEJTYhfHjNYxbQFMA/2dHlOjyeSgxS7GPIdMZ52Q= -github.com/rudderlabs/analytics-go v3.3.2+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30= +github.com/rudderlabs/analytics-go v3.3.3+incompatible h1:OG0XlKoXfr539e2t1dXtTB+Gr89uFW+OUNQBVhHIIBY= +github.com/rudderlabs/analytics-go v3.3.3+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1354,11 +1348,10 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1366,15 +1359,15 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/splitio/go-client/v6 v6.1.7 h1:/R8erLMywYGYVUosv+fa50owLWVxaYZ0cuzulFbo8Lc= -github.com/splitio/go-client/v6 v6.1.7/go.mod h1:3eQ1DcDaA+Y8DmZVBrAx1UC4Agar3c7IidriLeOFykk= -github.com/splitio/go-split-commons/v4 v4.1.3 h1:Aal1SF4GvmSP25P29oSLL6N9UMUhvFN/LURIxX2rACk= -github.com/splitio/go-split-commons/v4 v4.1.3/go.mod h1:E6yZiXwcjOdV5B7pHrBDbCsl4ju1YgYokRISZ9bYjgY= -github.com/splitio/go-toolkit/v5 v5.2.1 h1:WiAu7DD4Rl+Ly7Yz/8IDjhqAIySnlXlH6d7cG9KgoOY= -github.com/splitio/go-toolkit/v5 v5.2.1/go.mod h1:SYi/svhhtEgdMSb5tNcDcMjOSUH/7XVkvjp5dPL+nBE= +github.com/splitio/go-client/v6 v6.2.1 h1:EH3xYH7fr2c0I0ZtYvsyn7DjC9ZmoNAFLoKoT3BmQFU= +github.com/splitio/go-client/v6 v6.2.1/go.mod h1:+HnGMevmSUk56va2egs9W2s9mJ7LW9IXiDPB1ExOi+k= +github.com/splitio/go-split-commons/v4 v4.2.0/go.mod h1:mzanM00PV8t1FL6IHc2UXepIH2z79d49ArZ2LoJHGrY= +github.com/splitio/go-split-commons/v4 v4.2.2 h1:p4Gq4+Wxto+f+7g4AoxmMON1jkOU8abqAIV1pb8ke9M= +github.com/splitio/go-split-commons/v4 v4.2.2/go.mod h1:mzanM00PV8t1FL6IHc2UXepIH2z79d49ArZ2LoJHGrY= +github.com/splitio/go-toolkit/v5 v5.2.2 h1:VHSJoIH9tsRt2cCzGKN4WG3BoGCr0tCPZIl8APtJ4bw= +github.com/splitio/go-toolkit/v5 v5.2.2/go.mod h1:SYi/svhhtEgdMSb5tNcDcMjOSUH/7XVkvjp5dPL+nBE= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= @@ -1383,8 +1376,9 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1394,8 +1388,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1409,20 +1404,22 @@ github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vl github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= +github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= +github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= @@ -1471,8 +1468,9 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.5.3 h1:3HUJmBFbQW9fhQOzMgseU134xfi6hU+mjWywx5Ty+/M= +github.com/yuin/goldmark v1.5.3/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1546,7 +1544,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1568,8 +1565,8 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= +golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1594,8 +1591,8 @@ golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+o golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 h1:/eM0PCrQI2xd471rI+snWuu251/+/jpBpZqir2mPdnU= -golang.org/x/image v0.0.0-20220722155232-062f8c9fd539/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY= +golang.org/x/image v0.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk= +golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -1621,8 +1618,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1666,7 +1664,6 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -1694,11 +1691,12 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1732,8 +1730,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1743,8 +1742,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1857,22 +1854,27 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 h1:fqTvyMIIj+HRzMmnzr9NtpHP6uVpvB5fkHcgPDC4nu8= -golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1881,8 +1883,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1973,16 +1976,15 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= @@ -2024,6 +2026,8 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2107,10 +2111,13 @@ google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1 h1:C2UVWqrgLYKrT5nh5oU6hLRm1AeEklCK5eloQA1NtFY= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1 h1:jCw9YRd2s40X9Vxi4zKsPRvSPlHWNqadVkpbMsCPzPQ= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= @@ -2146,9 +2153,10 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From 5be85572475c9fd1871d2ca851fdae27ae09bee3 Mon Sep 17 00:00:00 2001 From: Shivashis Padhi Date: Thu, 17 Nov 2022 14:53:54 +0530 Subject: [PATCH 26/32] [MM-44168] Add feature to restore archived user groups (#20369) * Add undelete feature, add mocks, tests * Rename undelete->restore * make store-layers * make app-layers * Store -> Store() * Lint fixes Co-authored-by: Mattermod --- api4/group.go | 53 +++++++++++++++++++++ api4/group_test.go | 27 +++++++++++ app/app_iface.go | 1 + app/group.go | 15 ++++++ app/group_test.go | 18 ++++++++ app/opentracing/opentracing_layer.go | 22 +++++++++ model/client4.go | 13 ++++++ store/opentracinglayer/opentracinglayer.go | 18 ++++++++ store/retrylayer/retrylayer.go | 21 +++++++++ store/sqlstore/group_store.go | 19 ++++++++ store/store.go | 1 + store/storetest/group_store.go | 54 ++++++++++++++++++++++ store/storetest/mocks/GroupStore.go | 23 +++++++++ store/timerlayer/timerlayer.go | 16 +++++++ 14 files changed, 301 insertions(+) diff --git a/api4/group.go b/api4/group.go index da17d31ce3..343db5ee7e 100644 --- a/api4/group.go +++ b/api4/group.go @@ -84,6 +84,10 @@ func (api *API) InitGroup() { api.BaseRoutes.Groups.Handle("/{group_id:[A-Za-z0-9]+}", api.APISessionRequired(deleteGroup)).Methods("DELETE") + // GET /api/v4/groups/:group_id + api.BaseRoutes.Groups.Handle("/{group_id:[A-Za-z0-9]+}/restore", + api.APISessionRequired(restoreGroup)).Methods("POST") + // POST /api/v4/groups/:group_id/members api.BaseRoutes.Groups.Handle("/{group_id:[A-Za-z0-9]+}/members", api.APISessionRequired(addGroupMembers)).Methods("POST") @@ -1125,6 +1129,55 @@ func deleteGroup(c *Context, w http.ResponseWriter, r *http.Request) { ReturnStatusOK(w) } +func restoreGroup(c *Context, w http.ResponseWriter, r *http.Request) { + permissionErr := requireLicense(c) + if permissionErr != nil { + c.Err = permissionErr + return + } + + c.RequireGroupId() + if c.Err != nil { + return + } + + group, err := c.App.GetGroup(c.Params.GroupId, nil, nil) + if err != nil { + c.Err = err + return + } + + if group.Source != model.GroupSourceCustom { + c.Err = model.NewAppError("Api4.restoreGroup", "app.group.crud_permission", nil, "", http.StatusNotImplemented) + return + } + + if lcErr := licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom); lcErr != nil { + lcErr.Where = "Api4.restoreGroup" + c.Err = lcErr + return + } + + if !c.App.SessionHasPermissionToGroup(*c.AppContext.Session(), c.Params.GroupId, model.PermissionDeleteCustomGroup) { + c.SetPermissionError(model.PermissionDeleteCustomGroup) + return + } + + auditRec := c.MakeAuditRecord("restoreGroup", audit.Fail) + defer c.LogAuditRec(auditRec) + auditRec.AddMeta("group_id", c.Params.GroupId) + + _, err = c.App.RestoreGroup(c.Params.GroupId) + if err != nil { + c.Err = err + return + } + + auditRec.Success() + + ReturnStatusOK(w) +} + func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { permissionErr := requireLicense(c) if permissionErr != nil { diff --git a/api4/group_test.go b/api4/group_test.go index bbe4fa33c4..468e043d4e 100644 --- a/api4/group_test.go +++ b/api4/group_test.go @@ -214,6 +214,33 @@ func TestDeleteGroup(t *testing.T) { require.NoError(t, err) CheckOKStatus(t, response) } + +func TestUndeleteGroup(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)) + + validGroup, appErr := th.App.CreateGroup(&model.Group{ + DisplayName: "dn_" + model.NewId(), + Name: model.NewString("name" + model.NewId()), + Source: model.GroupSourceCustom, + }) + assert.Nil(t, appErr) + + _, response, err := th.Client.DeleteGroup(validGroup.Id) + require.NoError(t, err) + CheckOKStatus(t, response) + + _, response, err = th.Client.RestoreGroup(validGroup.Id, "") + require.NoError(t, err) + CheckOKStatus(t, response) + + _, response, err = th.Client.RestoreGroup(validGroup.Id, "") + require.Error(t, err) + CheckNotFoundStatus(t, response) +} + func TestPatchGroup(t *testing.T) { th := Setup(t) defer th.TearDown() diff --git a/app/app_iface.go b/app/app_iface.go index 371b9374b1..57b6f6fde1 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -968,6 +968,7 @@ type AppIface interface { ResetPermissionsSystem() *model.AppError ResetSamlAuthDataToEmail(includeDeleted bool, dryRun bool, userIDs []string) (numAffected int, appErr *model.AppError) RestoreChannel(c request.CTX, channel *model.Channel, userID string) (*model.Channel, *model.AppError) + RestoreGroup(groupID string) (*model.Group, *model.AppError) RestoreTeam(teamID string) *model.AppError RestrictUsersGetByPermissions(userID string, options *model.UserGetOptions) (*model.UserGetOptions, *model.AppError) RestrictUsersSearchByPermissions(userID string, options *model.UserSearchOptions) (*model.UserSearchOptions, *model.AppError) diff --git a/app/group.go b/app/group.go index 209c9e28c4..6db059b33f 100644 --- a/app/group.go +++ b/app/group.go @@ -217,6 +217,21 @@ func (a *App) DeleteGroup(groupID string) (*model.Group, *model.AppError) { return deletedGroup, nil } +func (a *App) RestoreGroup(groupID string) (*model.Group, *model.AppError) { + restoredGroup, err := a.Srv().Store().Group().Restore(groupID) + if err != nil { + var nfErr *store.ErrNotFound + switch { + case errors.As(err, &nfErr): + return nil, model.NewAppError("RestoreGroup", "app.group.no_rows", nil, nfErr.Error(), http.StatusNotFound) + default: + return nil, model.NewAppError("RestoreGroup", "app.update_error", nil, err.Error(), http.StatusInternalServerError) + } + } + + return restoredGroup, nil +} + func (a *App) GetGroupMemberCount(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, *model.AppError) { count, err := a.Srv().Store().Group().GetMemberCountWithRestrictions(groupID, viewRestrictions) if err != nil { diff --git a/app/group_test.go b/app/group_test.go index 3225d881b7..4419eff777 100644 --- a/app/group_test.go +++ b/app/group_test.go @@ -127,6 +127,24 @@ func TestDeleteGroup(t *testing.T) { require.Nil(t, g) } +func TestUndeleteGroup(t *testing.T) { + th := Setup(t) + defer th.TearDown() + group := th.CreateGroup() + + g, err := th.App.DeleteGroup(group.Id) + require.Nil(t, err) + require.NotNil(t, g) + + g, err = th.App.RestoreGroup(group.Id) + require.Nil(t, err) + require.NotNil(t, g) + + g, err = th.App.RestoreGroup(group.Id) + require.NotNil(t, err) + require.Nil(t, g) +} + func TestCreateOrRestoreGroupMember(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index 0a2f216e89..b10458ce0d 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -13945,6 +13945,28 @@ func (a *OpenTracingAppLayer) RestoreChannel(c request.CTX, channel *model.Chann return resultVar0, resultVar1 } +func (a *OpenTracingAppLayer) RestoreGroup(groupID string) (*model.Group, *model.AppError) { + origCtx := a.ctx + span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RestoreGroup") + + a.ctx = newCtx + a.app.Srv().Store().SetContext(newCtx) + defer func() { + a.app.Srv().Store().SetContext(origCtx) + a.ctx = origCtx + }() + + defer span.Finish() + resultVar0, resultVar1 := a.app.RestoreGroup(groupID) + + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + func (a *OpenTracingAppLayer) RestoreTeam(teamID string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RestoreTeam") diff --git a/model/client4.go b/model/client4.go index b569a8fa86..6ab4ed4952 100644 --- a/model/client4.go +++ b/model/client4.go @@ -7433,6 +7433,19 @@ func (c *Client4) DeleteGroup(groupID string) (*Group, *Response, error) { return &p, BuildResponse(r), nil } +func (c *Client4) RestoreGroup(groupID string, etag string) (*Group, *Response, error) { + r, err := c.DoAPIPost(c.groupRoute(groupID)+"/restore", "") + if err != nil { + return nil, BuildResponse(r), err + } + defer closeBody(r) + var p Group + if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { + return nil, nil, NewAppError("DeleteGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + } + return &p, BuildResponse(r), nil +} + func (c *Client4) PatchGroup(groupID string, patch *GroupPatch) (*Group, *Response, error) { payload, err := json.Marshal(patch) if err != nil { diff --git a/store/opentracinglayer/opentracinglayer.go b/store/opentracinglayer/opentracinglayer.go index b500b0cb53..513749fd4b 100644 --- a/store/opentracinglayer/opentracinglayer.go +++ b/store/opentracinglayer/opentracinglayer.go @@ -4512,6 +4512,24 @@ func (s *OpenTracingLayerGroupStore) PermittedSyncableAdmins(syncableID string, return result, err } +func (s *OpenTracingLayerGroupStore) Restore(groupID string) (*model.Group, error) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.Restore") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + result, err := s.GroupStore.Restore(groupID) + if err != nil { + span.LogFields(spanlog.Error(err)) + ext.Error.Set(span, true) + } + + return result, err +} + func (s *OpenTracingLayerGroupStore) TeamMembersMinusGroupMembers(teamID string, groupIDs []string, page int, perPage int) ([]*model.UserWithGroups, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.TeamMembersMinusGroupMembers") diff --git a/store/retrylayer/retrylayer.go b/store/retrylayer/retrylayer.go index 3e6fcb0b31..fdf6b2c9e9 100644 --- a/store/retrylayer/retrylayer.go +++ b/store/retrylayer/retrylayer.go @@ -5097,6 +5097,27 @@ func (s *RetryLayerGroupStore) PermittedSyncableAdmins(syncableID string, syncab } +func (s *RetryLayerGroupStore) Restore(groupID string) (*model.Group, error) { + + tries := 0 + for { + result, err := s.GroupStore.Restore(groupID) + if err == nil { + return result, nil + } + if !isRepeatableError(err) { + return result, err + } + tries++ + if tries >= 3 { + err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") + return result, err + } + timepkg.Sleep(100 * timepkg.Millisecond) + } + +} + func (s *RetryLayerGroupStore) TeamMembersMinusGroupMembers(teamID string, groupIDs []string, page int, perPage int) ([]*model.UserWithGroups, error) { tries := 0 diff --git a/store/sqlstore/group_store.go b/store/sqlstore/group_store.go index c3341dc9d6..40866d2a7a 100644 --- a/store/sqlstore/group_store.go +++ b/store/sqlstore/group_store.go @@ -360,6 +360,25 @@ func (s *SqlGroupStore) Delete(groupID string) (*model.Group, error) { return &group, nil } +func (s *SqlGroupStore) Restore(groupID string) (*model.Group, error) { + var group model.Group + if err := s.GetReplicaX().Get(&group, "SELECT * from UserGroups WHERE Id = ? AND DeleteAt != 0", groupID); err != nil { + if err == sql.ErrNoRows { + return nil, store.NewErrNotFound("Group", groupID) + } + return nil, errors.Wrapf(err, "failed to get Group with id=%s", groupID) + } + + time := model.GetMillis() + if _, err := s.GetMasterX().Exec(`UPDATE UserGroups + SET DeleteAt=0, UpdateAt=? + WHERE Id=? AND DeleteAt!=0`, time, groupID); err != nil { + return nil, errors.Wrapf(err, "failed to update Group with id=%s", groupID) + } + + return &group, nil +} + func (s *SqlGroupStore) GetMember(groupID, userID string) (*model.GroupMember, error) { query, args, err := s.getQueryBuilder(). Select("*"). diff --git a/store/store.go b/store/store.go index 77092a2aed..055b0dfeea 100644 --- a/store/store.go +++ b/store/store.go @@ -832,6 +832,7 @@ type GroupStore interface { GetByUser(userID string) ([]*model.Group, error) Update(group *model.Group) (*model.Group, error) Delete(groupID string) (*model.Group, error) + Restore(groupID string) (*model.Group, error) GetMemberUsers(groupID string) ([]*model.User, error) GetMemberUsersPage(groupID string, page int, perPage int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) diff --git a/store/storetest/group_store.go b/store/storetest/group_store.go index dbd292f1d3..02d788765d 100644 --- a/store/storetest/group_store.go +++ b/store/storetest/group_store.go @@ -32,6 +32,7 @@ func TestGroupStore(t *testing.T, ss store.Store) { t.Run("GetByUser", func(t *testing.T) { testGroupStoreGetByUser(t, ss) }) t.Run("Update", func(t *testing.T) { testGroupStoreUpdate(t, ss) }) t.Run("Delete", func(t *testing.T) { testGroupStoreDelete(t, ss) }) + t.Run("Restore", func(t *testing.T) { testGroupStoreRestore(t, ss) }) t.Run("GetMemberUsers", func(t *testing.T) { testGroupGetMemberUsers(t, ss) }) t.Run("GetMemberUsersPage", func(t *testing.T) { testGroupGetMemberUsersPage(t, ss) }) @@ -741,6 +742,59 @@ func testGroupStoreDelete(t *testing.T, ss store.Store) { require.True(t, errors.As(err, &nfErr)) } +func testGroupStoreRestore(t *testing.T, ss store.Store) { + // Save a group + g1 := &model.Group{ + Name: model.NewString(model.NewId()), + DisplayName: model.NewId(), + Description: model.NewId(), + Source: model.GroupSourceLdap, + RemoteId: model.NewString(model.NewId()), + } + + d1, err := ss.Group().Create(g1) + require.NoError(t, err) + require.Len(t, d1.Id, 26) + + // Check the group is retrievable + _, err = ss.Group().Get(d1.Id) + require.NoError(t, err) + + // Delete the group + _, err = ss.Group().Delete(d1.Id) + require.NoError(t, err) + + // Get the before count + d7, err := ss.Group().GetAllBySource(model.GroupSourceLdap) + require.NoError(t, err) + beforeCount := len(d7) + + // restore the group + _, err = ss.Group().Restore(d1.Id) + require.NoError(t, err) + + // Check the group is restored + d4, err := ss.Group().Get(d1.Id) + require.NoError(t, err) + require.Zero(t, d4.DeleteAt) + + // Check the after count + d5, err := ss.Group().GetAllBySource(model.GroupSourceLdap) + require.NoError(t, err) + afterCount := len(d5) + require.Condition(t, func() bool { return beforeCount == afterCount-1 }) + + // Try and restore a nonexistent group + _, err = ss.Group().Delete(model.NewId()) + require.Error(t, err) + var nfErr *store.ErrNotFound + require.True(t, errors.As(err, &nfErr)) + + // Cannot restore again + _, err = ss.Group().Restore(d1.Id) + require.True(t, errors.As(err, &nfErr)) +} + func testGroupGetMemberUsers(t *testing.T, ss store.Store) { // Save a group g1 := &model.Group{ diff --git a/store/storetest/mocks/GroupStore.go b/store/storetest/mocks/GroupStore.go index 80d6fdd492..7f54c5487b 100644 --- a/store/storetest/mocks/GroupStore.go +++ b/store/storetest/mocks/GroupStore.go @@ -1012,6 +1012,29 @@ func (_m *GroupStore) PermittedSyncableAdmins(syncableID string, syncableType mo return r0, r1 } +// Restore provides a mock function with given fields: groupID +func (_m *GroupStore) Restore(groupID string) (*model.Group, error) { + ret := _m.Called(groupID) + + var r0 *model.Group + if rf, ok := ret.Get(0).(func(string) *model.Group); ok { + r0 = rf(groupID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.Group) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(groupID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // TeamMembersMinusGroupMembers provides a mock function with given fields: teamID, groupIDs, page, perPage func (_m *GroupStore) TeamMembersMinusGroupMembers(teamID string, groupIDs []string, page int, perPage int) ([]*model.UserWithGroups, error) { ret := _m.Called(teamID, groupIDs, page, perPage) diff --git a/store/timerlayer/timerlayer.go b/store/timerlayer/timerlayer.go index 16f6044d24..9e8bb2fade 100644 --- a/store/timerlayer/timerlayer.go +++ b/store/timerlayer/timerlayer.go @@ -4101,6 +4101,22 @@ func (s *TimerLayerGroupStore) PermittedSyncableAdmins(syncableID string, syncab return result, err } +func (s *TimerLayerGroupStore) Restore(groupID string) (*model.Group, error) { + start := time.Now() + + result, err := s.GroupStore.Restore(groupID) + + elapsed := float64(time.Since(start)) / float64(time.Second) + if s.Root.Metrics != nil { + success := "false" + if err == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("GroupStore.Restore", success, elapsed) + } + return result, err +} + func (s *TimerLayerGroupStore) TeamMembersMinusGroupMembers(teamID string, groupIDs []string, page int, perPage int) ([]*model.UserWithGroups, error) { start := time.Now() From 06ad69a406dc561d277ec0b0cb32112afee1ffa4 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 17 Nov 2022 20:44:18 +0530 Subject: [PATCH 27/32] MM-47465: Fix flaky TestDeleteChannel (#21686) Creating the post in a separate goroutine would create a race condition because that method also calls GetChannel. This can cause a bug if the cache was wiped before the the other goroutine would get a chance to update the cache. And if that happens, then it would populate the cache with the old value. Pseudo-code ``` func deleteChannel() { go func() { getFromCache() }() updateDB() wipeCache() // a } func getFromCache() { err := checkCache() if err == ErrNotFound { getFromDB() // x updateCache() // y } } func Test() { deleteChannel() getFromCache() } ``` If the sequence of events happen like - x - a - y Then the getFromCache() call later will get the wrong value from cache. The fix is to make the call synchronous. https://mattermost.atlassian.net/browse/MM-47465 Special thanks to @noxer for finding the root cause. ```release-note NONE ``` --- api4/channel_test.go | 1 - app/channel.go | 15 ++++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/api4/channel_test.go b/api4/channel_test.go index 1e1ea4b2e1..16e432bf0d 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -1779,7 +1779,6 @@ func TestSearchGroupChannels(t *testing.T) { } func TestDeleteChannel(t *testing.T) { - t.Skip("MM-47465") th := Setup(t).InitBasic() defer th.TearDown() c := th.Client diff --git a/app/channel.go b/app/channel.go index 6bbe699fb0..f5c864ca38 100644 --- a/app/channel.go +++ b/app/channel.go @@ -1420,13 +1420,10 @@ func (a *App) DeleteChannel(c request.CTX, channel *model.Channel, userID string c.Logger().Warn("Failed to post archive message", mlog.Err(err)) } } else { - a.Srv().Go(func() { - systemBot, err := a.GetSystemBot() - if err != nil { - c.Logger().Error("Failed to post archive message", mlog.Err(err)) - return - } - + systemBot, err := a.GetSystemBot() + if err != nil { + c.Logger().Warn("Failed to post archive message", mlog.Err(err)) + } else { post := &model.Post{ ChannelId: channel.Id, Message: fmt.Sprintf(i18n.T("api.channel.delete_channel.archived"), systemBot.Username), @@ -1438,9 +1435,9 @@ func (a *App) DeleteChannel(c request.CTX, channel *model.Channel, userID string } if _, err := a.CreatePost(c, post, channel, false, true); err != nil { - c.Logger().Error("Failed to post archive message", mlog.Err(err)) + c.Logger().Warn("Failed to post archive message", mlog.Err(err)) } - }) + } } now := model.GetMillis() From 1edbf67bb2814edfc650a7185fc9636d9707348e Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Thu, 17 Nov 2022 19:36:08 +0300 Subject: [PATCH 28/32] migrations: bump morph dependency and reflect changes (#21670) --- config/database.go | 18 +++++++----------- go.mod | 14 +++++++++++++- go.sum | 20 ++++++++++++++++++-- store/sqlstore/store.go | 13 +++---------- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/config/database.go b/config/database.go index 1c3add6bbb..e9f9328d38 100644 --- a/config/database.go +++ b/config/database.go @@ -117,11 +117,6 @@ func (ds *DatabaseStore) initializeConfigurationsTable() error { return err } - cfg := drivers.Config{ - MigrationsTable: migrationsTableName, - StatementTimeoutInSecs: migrationsTimeoutInSeconds, - } - var driver drivers.Driver switch ds.driverName { case model.DatabaseDriverMysql: @@ -141,15 +136,11 @@ func (ds *DatabaseStore) initializeConfigurationsTable() error { return errors.Wrapf(err, "failed to connect to %s database", ds.driverName) } - driver, err = ms.WithInstance(db.DB, &ms.Config{ - Config: cfg, - }) + driver, err = ms.WithInstance(db.DB) defer db.Close() case model.DatabaseDriverPostgres: - driver, err = ps.WithInstance(ds.db.DB, &ps.Config{ - Config: cfg, - }) + driver, err = ps.WithInstance(ds.db.DB) default: err = fmt.Errorf("unsupported database type %s for migration", ds.driverName) } @@ -159,6 +150,8 @@ func (ds *DatabaseStore) initializeConfigurationsTable() error { opts := []morph.EngineOption{ morph.WithLock("mm-config-lock-key"), + morph.SetMigrationTableName(migrationsTableName), + morph.SetStatementTimeoutInSeconds(migrationsTimeoutInSeconds), } engine, err := morph.New(context.Background(), driver, src, opts...) if err != nil { @@ -172,8 +165,11 @@ func (ds *DatabaseStore) initializeConfigurationsTable() error { // parseDSN splits up a connection string into a driver name and data source name. // // For example: +// // mysql://mmuser:mostest@localhost:5432/mattermost_test +// // returns +// // driverName = mysql // dataSourceName = mmuser:mostest@localhost:5432/mattermost_test // diff --git a/go.mod b/go.mod index f3b7d99808..ad8a4fbb28 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/mattermost/gziphandler v0.0.1 github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d github.com/mattermost/logr/v2 v2.0.15 - github.com/mattermost/morph v1.0.4 + github.com/mattermost/morph v1.0.5-0.20221115094356-4c18a75b1f5e github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0 github.com/mattermost/squirrel v0.2.0 github.com/mholt/archiver/v3 v3.5.1 @@ -122,6 +122,7 @@ require ( github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.15.12 // indirect github.com/klauspost/cpuid/v2 v2.2.1 // indirect github.com/klauspost/pgzip v1.2.5 // indirect @@ -147,6 +148,7 @@ require ( github.com/philhofer/fwd v1.1.1 // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect github.com/rivo/uniseg v0.4.3 // indirect @@ -177,6 +179,16 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/uint128 v1.1.1 // indirect + modernc.org/cc/v3 v3.36.0 // indirect + modernc.org/ccgo/v3 v3.16.6 // indirect + modernc.org/libc v1.16.7 // indirect + modernc.org/mathutil v1.4.1 // indirect + modernc.org/memory v1.1.1 // indirect + modernc.org/opt v0.1.1 // indirect + modernc.org/sqlite v1.18.0 // indirect + modernc.org/strutil v1.1.1 // indirect + modernc.org/token v1.0.0 // indirect ) // Hack to prevent the willf/bitset module from being upgraded to 1.2.0. diff --git a/go.sum b/go.sum index b19dedc445..5bfeee94ff 100644 --- a/go.sum +++ b/go.sum @@ -907,6 +907,7 @@ github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3t github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -986,8 +987,8 @@ github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d h1:/RJ/UV7M5c7L2TQ github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ= github.com/mattermost/logr/v2 v2.0.15 h1:+WNbGcsc3dBao65eXlceB6dTILNJRIrvubnsTl3zBew= github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXpNh0k/y8Hmwg= -github.com/mattermost/morph v1.0.4 h1:isy1ryN9Re3MJKEyHwjRkFeM2a6cSJ76Pl6g4rCkLQY= -github.com/mattermost/morph v1.0.4/go.mod h1:xo0ljDknTpPxEdhhrUdwhLCexIsYyDKS6b41HqG8wGU= +github.com/mattermost/morph v1.0.5-0.20221115094356-4c18a75b1f5e h1:VfNz+fvJ3DxOlALM22Eea8ONp5jHrybKBCcCtDPVlss= +github.com/mattermost/morph v1.0.5-0.20221115094356-4c18a75b1f5e/go.mod h1:xo0ljDknTpPxEdhhrUdwhLCexIsYyDKS6b41HqG8wGU= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0 h1:G9tL6JXRBMzjuD1kkBtcnd42kUiT6QDwxfFYu7adM6o= github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs= github.com/mattermost/squirrel v0.2.0 h1:8ZWeyf+MWQ2cL7hu9REZgLtz2IJi51qqZEovI3T3TT8= @@ -1247,6 +1248,7 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/reflog/dateconstraints v0.2.1 h1:Hz1n2Q1vEm0Rj5gciDQcCN1iPBwfFjxUJy32NknGP/s= github.com/reflog/dateconstraints v0.2.1/go.mod h1:Ax8AxTBcJc3E/oVS2hd2j7RDM/5MDtuPwuR7lIHtPLo= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= @@ -2280,20 +2282,25 @@ k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg= modernc.org/cc/v3 v3.32.4/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878= +modernc.org/cc/v3 v3.36.0 h1:0kmRkTmqNidmu3c7BNDSdVHCxXCkWLmWmCIVX4LUboo= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.9.2/go.mod h1:gnJpy6NIVqkETT+L5zPsQFj7L2kkhfPMzOghRNv/CFo= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6 h1:3l18poV+iUemQ98O3X5OMr97LOqlzis+ytivU4NqGhA= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8= modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw= modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= +modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM= modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= @@ -2301,26 +2308,35 @@ modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWC modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.7 h1:qzQtHhsZNpVPpeCu+aMIQldXeV1P0vRhSqCL0nOIJOA= modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= +modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY= modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k= modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs= +modernc.org/sqlite v1.18.0 h1:ef66qJSgKeyLyrF4kQ2RHw/Ue3V89fyFNbGL073aDjI= modernc.org/sqlite v1.18.0/go.mod h1:B9fRWZacNxJBHoCJZQr1R54zhVn3fjfl0aszflrTSxY= modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/tcl v1.5.2/go.mod h1:pmJYOLgpiys3oI4AeAafkcUfE+TKKilminxNyU/+Zlo= +modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= +modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/store/sqlstore/store.go b/store/sqlstore/store.go index 854e078b7f..71f9598ed0 100644 --- a/store/sqlstore/store.go +++ b/store/sqlstore/store.go @@ -1034,18 +1034,10 @@ func (ss *SqlStore) migrate(direction migrationDirection) error { return err } db := setupConnection("master", dataSource, ss.settings) - driver, err = ms.WithInstance(db, &ms.Config{ - Config: drivers.Config{ - StatementTimeoutInSecs: *ss.settings.MigrationsStatementTimeoutSeconds, - }, - }) + driver, err = ms.WithInstance(db) defer db.Close() case model.DatabaseDriverPostgres: - driver, err = ps.WithInstance(ss.GetMasterX().DB.DB, &ps.Config{ - Config: drivers.Config{ - StatementTimeoutInSecs: *ss.settings.MigrationsStatementTimeoutSeconds, - }, - }) + driver, err = ps.WithInstance(ss.GetMasterX().DB.DB) default: err = fmt.Errorf("unsupported database type %s for migration", ss.DriverName()) } @@ -1056,6 +1048,7 @@ func (ss *SqlStore) migrate(direction migrationDirection) error { opts := []morph.EngineOption{ morph.WithLogger(log.New(&morphWriter{}, "", log.Lshortfile)), morph.WithLock("mm-lock-key"), + morph.SetStatementTimeoutInSeconds(*ss.settings.MigrationsStatementTimeoutSeconds), } engine, err := morph.New(context.Background(), driver, src, opts...) if err != nil { From 753ca610b32d568d53d29af79d5f899925b52e8b Mon Sep 17 00:00:00 2001 From: mattermod Date: Fri, 18 Nov 2022 15:35:54 +0000 Subject: [PATCH 29/32] Update latest version to 7.5.0 --- build/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Dockerfile b/build/Dockerfile index 55183179d0..bcdf8580d7 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -8,7 +8,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"] ENV PATH="/mattermost/bin:${PATH}" ARG PUID=2000 ARG PGID=2000 -ARG MM_PACKAGE="https://releases.mattermost.com/7.4.0/mattermost-7.4.0-linux-amd64.tar.gz?src=docker" +ARG MM_PACKAGE="https://releases.mattermost.com/7.5.0/mattermost-7.5.0-linux-amd64.tar.gz?src=docker" # # Install needed packages and indirect dependencies RUN apt-get update \ From 2386571c8948481d1dbd89aa6bdc78f8922f8f0e Mon Sep 17 00:00:00 2001 From: mattermod Date: Fri, 18 Nov 2022 15:50:15 +0000 Subject: [PATCH 30/32] Update latest version to 7.5.1 --- build/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Dockerfile b/build/Dockerfile index bcdf8580d7..d373e54fdc 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -8,7 +8,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"] ENV PATH="/mattermost/bin:${PATH}" ARG PUID=2000 ARG PGID=2000 -ARG MM_PACKAGE="https://releases.mattermost.com/7.5.0/mattermost-7.5.0-linux-amd64.tar.gz?src=docker" +ARG MM_PACKAGE="https://releases.mattermost.com/7.5.1/mattermost-7.5.1-linux-amd64.tar.gz?src=docker" # # Install needed packages and indirect dependencies RUN apt-get update \ From 25bb1d0ebdeb26bfba6e5967bcc131df2df3e278 Mon Sep 17 00:00:00 2001 From: Ben Cooke Date: Fri, 18 Nov 2022 11:29:06 -0500 Subject: [PATCH 31/32] [MM-47145] My Insights license change (#21443) * tools updates * Revert "tools updates" This reverts commit 6293297b55803c5a263e200ebd80192899666ae9. * remove license checks for my insights endpoints * removing new config * remove license checks from insights test * adding some license tests for team endpoints * fixing tests Co-authored-by: Benjamin Cooke Co-authored-by: Benjamin Cooke Co-authored-by: Benjamin Cooke Co-authored-by: Benjamin Cooke Co-authored-by: Mattermod --- api4/insights.go | 45 ++++++++++-------------------------------- api4/insights_test.go | 46 +++++++++++++++++++++++++++++++++++++------ config/client.go | 6 +----- config/client_test.go | 2 +- 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/api4/insights.go b/api4/insights.go index 9d74a57c2f..c5bfa018ee 100644 --- a/api4/insights.go +++ b/api4/insights.go @@ -99,13 +99,8 @@ func getTopReactionsForTeamSince(c *Context, w http.ResponseWriter, r *http.Requ } func getTopReactionsForUserSince(c *Context, w http.ResponseWriter, r *http.Request) { - // license and guest user check - permissionErr := minimumProfessionalLicense(c) - if permissionErr != nil { - c.Err = permissionErr - return - } - permissionErr = rejectGuests(c) + // guest user check + permissionErr := rejectGuests(c) if permissionErr != nil { c.Err = permissionErr return @@ -233,13 +228,8 @@ func getTopChannelsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reque } func getTopChannelsForUserSince(c *Context, w http.ResponseWriter, r *http.Request) { - // license and guest user check - permissionErr := minimumProfessionalLicense(c) - if permissionErr != nil { - c.Err = permissionErr - return - } - permissionErr = rejectGuests(c) + // guest user check + permissionErr := rejectGuests(c) if permissionErr != nil { c.Err = permissionErr return @@ -367,13 +357,8 @@ func getTopThreadsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reques } func getTopThreadsForUserSince(c *Context, w http.ResponseWriter, r *http.Request) { - // license and guest user check - permissionErr := minimumProfessionalLicense(c) - if permissionErr != nil { - c.Err = permissionErr - return - } - permissionErr = rejectGuests(c) + // guest user check + permissionErr := rejectGuests(c) if permissionErr != nil { c.Err = permissionErr return @@ -433,13 +418,8 @@ func getTopThreadsForUserSince(c *Context, w http.ResponseWriter, r *http.Reques // Top DMs func getTopDMsForUserSince(c *Context, w http.ResponseWriter, r *http.Request) { - // license and guest user check - permissionErr := minimumProfessionalLicense(c) - if permissionErr != nil { - c.Err = permissionErr - return - } - permissionErr = rejectGuests(c) + // guest user check + permissionErr := rejectGuests(c) if permissionErr != nil { c.Err = permissionErr return @@ -540,13 +520,8 @@ func getTopInactiveChannelsForTeamSince(c *Context, w http.ResponseWriter, r *ht // top inactive channels func getTopInactiveChannelsForUserSince(c *Context, w http.ResponseWriter, r *http.Request) { - // license and guest user check - permissionErr := minimumProfessionalLicense(c) - if permissionErr != nil { - c.Err = permissionErr - return - } - permissionErr = rejectGuests(c) + // guest user check + permissionErr := rejectGuests(c) if permissionErr != nil { c.Err = permissionErr return diff --git a/api4/insights_test.go b/api4/insights_test.go index 2443c1ea26..e304a60a49 100644 --- a/api4/insights_test.go +++ b/api4/insights_test.go @@ -242,14 +242,20 @@ func TestGetTopReactionsForTeamSince(t *testing.T) { assert.Error(t, err) CheckForbiddenStatus(t, resp) }) + + t.Run("get-top-reactions-for-team-since invalid license", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicense("")) + + _, resp, err := client.GetTopReactionsForTeamSince(teamId, model.TimeRangeToday, 0, 5) + assert.Error(t, err) + CheckNotImplementedStatus(t, resp) + }) } func TestGetTopReactionsForUserSince(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)) - client := th.Client userId := th.BasicUser.Id @@ -539,14 +545,20 @@ func TestGetTopChannelsForTeamSince(t *testing.T) { assert.Error(t, err) CheckForbiddenStatus(t, resp) }) + + t.Run("get-top-channels-for-team-since invalid license", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicense("")) + + _, resp, err := client.GetTopChannelsForTeamSince(teamId, model.TimeRangeToday, 0, 5) + assert.Error(t, err) + CheckNotImplementedStatus(t, resp) + }) } func TestGetTopChannelsForUserSince(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)) - client := th.Client userId := th.BasicUser.Id @@ -708,12 +720,19 @@ func TestGetTopThreadsForTeamSince(t *testing.T) { topTeamThreadsByUser2IncludingPrivate, _, _ := client.GetTopThreadsForTeamSince(th.BasicTeam.Id, model.TimeRangeToday, 0, 10) require.Nil(t, appErr) require.Len(t, topTeamThreadsByUser2IncludingPrivate.Items, 2) + + t.Run("get-top-threads-for-team-since invalid license", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicense("")) + + _, resp, err := client.GetTopThreadsForTeamSince(th.BasicTeam.Id, model.TimeRangeToday, 0, 5) + assert.Error(t, err) + CheckNotImplementedStatus(t, resp) + }) } func TestGetTopThreadsForUserSince(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() - th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)) th.LoginBasic() client := th.Client @@ -958,6 +977,14 @@ func TestGetTopInactiveChannelsForTeamSince(t *testing.T) { assert.Equal(t, expectedTopChannels[i].ID, channel.ID) } }) + + t.Run("get-top-inactive-channels-for-team-since invalid license", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicense("")) + + _, resp, err := client.GetTopInactiveChannelsForTeamSince(teamId, model.TimeRangeToday, 0, 5) + assert.Error(t, err) + CheckNotImplementedStatus(t, resp) + }) } func TestGetTopDMsForUserSince(t *testing.T) { @@ -970,7 +997,6 @@ func TestGetTopDMsForUserSince(t *testing.T) { *c.TeamSettings.EnableUserDeactivation = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableBotAccountCreation = true }) - th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)) // basicuser1 - bu1, basicuser - bu // create dm channels for bu-bu, bu1-bu1, bu-bu1, bot-bu @@ -1169,4 +1195,12 @@ func TestNewTeamMembersSince(t *testing.T) { require.Len(t, list.Items, 1) require.False(t, list.HasNext) }) + + t.Run("get-new-team-members-since invalid license", func(t *testing.T) { + th.App.Srv().SetLicense(model.NewTestLicense("")) + + _, resp, err := th.Client.GetNewTeamMembersSince(team.Id, model.TimeRangeToday, 0, 2) + assert.Error(t, err) + CheckNotImplementedStatus(t, resp) + }) } diff --git a/config/client.go b/config/client.go index d70ad24110..1eaef48c60 100644 --- a/config/client.go +++ b/config/client.go @@ -130,7 +130,7 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li props["ExperimentalSharedChannels"] = "false" props["CollapsedThreads"] = *c.ServiceSettings.CollapsedThreads props["EnableCustomGroups"] = "false" - props["InsightsEnabled"] = "false" + props["InsightsEnabled"] = strconv.FormatBool(c.FeatureFlags.InsightsEnabled) props["PostPriority"] = strconv.FormatBool(*c.ServiceSettings.PostPriority) if license != nil { @@ -206,10 +206,6 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li if license.SkuShortName == model.LicenseShortSkuProfessional || license.SkuShortName == model.LicenseShortSkuEnterprise { props["EnableCustomGroups"] = strconv.FormatBool(*c.ServiceSettings.EnableCustomGroups) } - - if (license.SkuShortName == model.LicenseShortSkuProfessional || license.SkuShortName == model.LicenseShortSkuEnterprise) && c.FeatureFlags.InsightsEnabled { - props["InsightsEnabled"] = "true" - } } return props diff --git a/config/client_test.go b/config/client_test.go index e32834136c..4c23801424 100644 --- a/config/client_test.go +++ b/config/client_test.go @@ -195,7 +195,7 @@ func TestGetClientConfig(t *testing.T) { SkuShortName: "other", }, map[string]string{ - "InsightsEnabled": "false", + "InsightsEnabled": "true", }, }, { From fcd45de73b142b16e8710b0575eeb99cd001b978 Mon Sep 17 00:00:00 2001 From: Martin Kraft Date: Mon, 21 Nov 2022 13:36:41 -0500 Subject: [PATCH 32/32] MM-48186: Add a new API endpoint to add a user to their default GroupChannels and GroupTeams. (#21591) * MM-48186: Add a new API endpoint to add a user to their default GroupChannels and GroupTeams. * MM-48186: Removed unrelated lint fixes. * MM-48186: Removed variable from previous iteration. * MM-48186: Adds translation. * MM-48186: Not upgrading golang.org/x/text in this pr. * MM-48186: Validate user ID and auth service. * MM-48186: Use user id from struct. * MM-48186: Added basic client test. * MM-48186: Adds empty translation. * MM-48186: Added translations. Co-authored-by: Mattermod --- api4/ldap.go | 34 ++++++++ api4/ldap_test.go | 31 +++++++ app/app_iface.go | 2 +- app/opentracing/opentracing_layer.go | 4 +- app/syncables.go | 28 ++++-- app/syncables_test.go | 123 +++++++++++++++++++++++++-- i18n/en.json | 8 ++ model/client4.go | 9 ++ model/group.go | 8 ++ 9 files changed, 227 insertions(+), 20 deletions(-) diff --git a/api4/ldap.go b/api4/ldap.go index b71415c940..aabacc7599 100644 --- a/api4/ldap.go +++ b/api4/ldap.go @@ -40,6 +40,7 @@ func (api *API) InitLdap() { api.BaseRoutes.LDAP.Handle("/certificate/public", api.APISessionRequired(removeLdapPublicCertificate)).Methods("DELETE") api.BaseRoutes.LDAP.Handle("/certificate/private", api.APISessionRequired(removeLdapPrivateCertificate)).Methods("DELETE") + api.BaseRoutes.LDAP.Handle("/users/{user_id}/group_sync_memberships", api.APISessionRequired(addUserToGroupSyncables)).Methods("POST") } func syncLdap(c *Context, w http.ResponseWriter, r *http.Request) { @@ -419,3 +420,36 @@ func removeLdapPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Req auditRec.Success() ReturnStatusOK(w) } + +// addUserToGroupSyncables creates memberships—for the given user—to all of their group syncables (i.e. channels or teams). +// For each group the user is a member of, for each channel and/or team that group is associated with, the user will be added. +func addUserToGroupSyncables(c *Context, w http.ResponseWriter, r *http.Request) { + if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteUserManagementGroups) { + c.SetPermissionError(model.PermissionSysconsoleWriteUserManagementGroups) + return + } + + user, appErr := c.App.GetUser(c.Params.UserId) + if appErr != nil { + c.Err = appErr + return + } + + if user.AuthService != model.UserAuthServiceLdap { + c.Err = model.NewAppError("addUserToGroupSyncables", "api.user.add_user_to_group_syncables.not_ldap_user.app_error", nil, "", http.StatusBadRequest) + return + } + + auditRec := c.MakeAuditRecord("addUserToGroupSyncables", audit.Fail) + defer c.LogAuditRec(auditRec) + + params := model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: true, ScopedUserID: &user.Id} + err := c.App.CreateDefaultMemberships(c.AppContext, params) + if err != nil { + c.Err = model.NewAppError("addUserToGroupSyncables", "api.admin.syncables_error", nil, err.Error(), http.StatusBadRequest) + return + } + + auditRec.Success() + ReturnStatusOK(w) +} diff --git a/api4/ldap_test.go b/api4/ldap_test.go index 82e9c0b31b..d364096b57 100644 --- a/api4/ldap_test.go +++ b/api4/ldap_test.go @@ -277,3 +277,34 @@ func TestUploadPrivateCertificate(t *testing.T) { require.NoErrorf(t, err, "Should have passed. System Admin privileges %v", err) }) } + +func TestAddUserToGroupSyncables(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + resp, err := th.Client.AddUserToGroupSyncables(th.BasicUser.Id) + require.Error(t, err) + CheckForbiddenStatus(t, resp) + + resp, err = th.SystemAdminClient.AddUserToGroupSyncables("invalid-user-id") + require.Error(t, err) + CheckNotFoundStatus(t, resp) + + resp, err = th.SystemAdminClient.AddUserToGroupSyncables(th.BasicUser.Id) + require.Error(t, err) + CheckBadRequestStatus(t, resp) + + id := model.NewId() + user := &model.User{ + Email: "test@localhost", + Username: model.NewId(), + AuthData: &id, + AuthService: model.UserAuthServiceLdap, + } + user, err = th.App.Srv().Store().User().Save(user) + require.NoError(t, err) + + resp, err = th.SystemAdminClient.AddUserToGroupSyncables(user.Id) + require.NoError(t, err) + CheckOKStatus(t, resp) +} diff --git a/app/app_iface.go b/app/app_iface.go index 57b6f6fde1..ab22b9cbf9 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -93,7 +93,7 @@ type AppIface interface { // are configured to sync with teams and channels for group members on or after the given timestamp. // If includeRemovedMembers is true, then members who left or were removed from a team/channel will // be re-added; otherwise, they will not be re-added. - CreateDefaultMemberships(c *request.Context, since int64, includeRemovedMembers bool) error + CreateDefaultMemberships(c *request.Context, params model.CreateDefaultMembershipParams) error // CreateGuest creates a guest and sets several fields of the returned User struct to // their zero values. CreateGuest(c request.CTX, user *model.User) (*model.User, *model.AppError) diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index b10458ce0d..b40c1921aa 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -2007,7 +2007,7 @@ func (a *OpenTracingAppLayer) CreateCommandWebhook(commandID string, args *model return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) CreateDefaultMemberships(c *request.Context, since int64, includeRemovedMembers bool) error { +func (a *OpenTracingAppLayer) CreateDefaultMemberships(c *request.Context, params model.CreateDefaultMembershipParams) error { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateDefaultMemberships") @@ -2019,7 +2019,7 @@ func (a *OpenTracingAppLayer) CreateDefaultMemberships(c *request.Context, since }() defer span.Finish() - resultVar0 := a.app.CreateDefaultMemberships(c, since, includeRemovedMembers) + resultVar0 := a.app.CreateDefaultMemberships(c, params) if resultVar0 != nil { span.LogFields(spanlog.Error(resultVar0)) diff --git a/app/syncables.go b/app/syncables.go index cc87edc8ee..2114055b17 100644 --- a/app/syncables.go +++ b/app/syncables.go @@ -18,13 +18,16 @@ import ( // only that channel's members are created. If channelID is nil all channel memberships are created. // If includeRemovedMembers is true, then channel members who left or were removed from the channel will // be re-added; otherwise, they will not be re-added. -func (a *App) createDefaultChannelMemberships(c request.CTX, since int64, channelID *string, includeRemovedMembers bool) error { - channelMembers, appErr := a.ChannelMembersToAdd(since, channelID, includeRemovedMembers) +func (a *App) createDefaultChannelMemberships(c request.CTX, params model.CreateDefaultMembershipParams) error { + channelMembers, appErr := a.ChannelMembersToAdd(params.Since, params.ScopedChannelID, params.ReAddRemovedMembers) if appErr != nil { return appErr } for _, userChannel := range channelMembers { + if params.ScopedUserID != nil && *params.ScopedUserID != userChannel.UserID { + continue + } channel, err := a.GetChannel(c, userChannel.ChannelID) if err != nil { return err @@ -83,13 +86,16 @@ func (a *App) createDefaultChannelMemberships(c request.CTX, since int64, channe // only that team's members are created. If teamID is nil all team memberships are created. // If includeRemovedMembers is true, then team members who left or were removed from the team will // be re-added; otherwise, they will not be re-added. -func (a *App) createDefaultTeamMemberships(c request.CTX, since int64, teamID *string, includeRemovedMembers bool) error { - teamMembers, appErr := a.TeamMembersToAdd(since, teamID, includeRemovedMembers) +func (a *App) createDefaultTeamMemberships(c request.CTX, params model.CreateDefaultMembershipParams) error { + teamMembers, appErr := a.TeamMembersToAdd(params.Since, params.ScopedTeamID, params.ReAddRemovedMembers) if appErr != nil { return appErr } for _, userTeam := range teamMembers { + if params.ScopedUserID != nil && *params.ScopedUserID != userTeam.UserID { + continue + } _, err := a.AddTeamMember(c, userTeam.TeamID, userTeam.UserID) if err != nil { if err.Id == "api.team.join_user_to_team.allowed_domains.app_error" { @@ -115,13 +121,13 @@ func (a *App) createDefaultTeamMemberships(c request.CTX, since int64, teamID *s // are configured to sync with teams and channels for group members on or after the given timestamp. // If includeRemovedMembers is true, then members who left or were removed from a team/channel will // be re-added; otherwise, they will not be re-added. -func (a *App) CreateDefaultMemberships(c *request.Context, since int64, includeRemovedMembers bool) error { - err := a.createDefaultTeamMemberships(c, since, nil, includeRemovedMembers) +func (a *App) CreateDefaultMemberships(c *request.Context, params model.CreateDefaultMembershipParams) error { + err := a.createDefaultTeamMemberships(c, params) if err != nil { return err } - err = a.createDefaultChannelMemberships(c, since, nil, includeRemovedMembers) + err = a.createDefaultChannelMemberships(c, params) if err != nil { return err } @@ -242,15 +248,19 @@ func (a *App) SyncRolesAndMembership(c request.CTX, syncableID string, syncableT since = lastJob.StartAt } + params := model.CreateDefaultMembershipParams{Since: since, ReAddRemovedMembers: includeRemovedMembers} + switch syncableType { case model.GroupSyncableTypeTeam: - a.createDefaultTeamMemberships(c, since, &syncableID, includeRemovedMembers) + params.ScopedTeamID = &syncableID + a.createDefaultTeamMemberships(c, params) a.deleteGroupConstrainedTeamMemberships(c, &syncableID) if err := a.ClearTeamMembersCache(syncableID); err != nil { c.Logger().Warn("Error clearing team members cache", mlog.Err(err)) } case model.GroupSyncableTypeChannel: - a.createDefaultChannelMemberships(c, since, &syncableID, includeRemovedMembers) + params.ScopedChannelID = &syncableID + a.createDefaultChannelMemberships(c, params) a.deleteGroupConstrainedChannelMemberships(c, &syncableID) if err := a.ClearChannelMembersCache(c, syncableID); err != nil { c.Logger().Warn("Error clearing channel members cache", mlog.Err(err)) diff --git a/app/syncables_test.go b/app/syncables_test.go index d78d46f1d2..0908a859a2 100644 --- a/app/syncables_test.go +++ b/app/syncables_test.go @@ -103,7 +103,7 @@ func TestCreateDefaultMemberships(t *testing.T) { t.Errorf("test groupmember not created: %s", err.Error()) } - pErr := th.App.CreateDefaultMemberships(th.Context, 0, false) + pErr := th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("faild to populate syncables: %s", pErr.Error()) } @@ -173,7 +173,7 @@ func TestCreateDefaultMemberships(t *testing.T) { } // Sync everything after syncable was created (proving that team updates trigger re-sync) - pErr = th.App.CreateDefaultMemberships(th.Context, scientistGroupMember.CreateAt+1, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scientistGroupMember.CreateAt + 1, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("faild to populate syncables: %s", pErr.Error()) } @@ -216,7 +216,7 @@ func TestCreateDefaultMemberships(t *testing.T) { } // Sync everything after syncable was created (proving that channel updates trigger re-sync) - pErr = th.App.CreateDefaultMemberships(th.Context, scientistGroupMember.CreateAt+1, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scientistGroupMember.CreateAt + 1, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("faild to populate syncables: %s", pErr.Error()) } @@ -241,7 +241,7 @@ func TestCreateDefaultMemberships(t *testing.T) { } // Even re-syncing from the beginning doesn't re-add to channel or team - pErr = th.App.CreateDefaultMemberships(th.Context, 0, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("faild to populate syncables: %s", pErr.Error()) } @@ -282,7 +282,7 @@ func TestCreateDefaultMemberships(t *testing.T) { t.Errorf("error updating group syncable: %s", err.Error()) } - pErr = th.App.CreateDefaultMemberships(th.Context, 0, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("faild to populate syncables: %s", pErr.Error()) } @@ -305,7 +305,7 @@ func TestCreateDefaultMemberships(t *testing.T) { } require.Equal(t, int64(1), deletedCount) - pErr = th.App.CreateDefaultMemberships(th.Context, scienceChannelGroupSyncable.UpdateAt, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scienceChannelGroupSyncable.UpdateAt, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("failed to populate syncables: %s", pErr.Error()) } @@ -323,7 +323,7 @@ func TestCreateDefaultMemberships(t *testing.T) { } require.Equal(t, int64(1), deletedCount) - pErr = th.App.CreateDefaultMemberships(th.Context, scienceChannelGroupSyncable.UpdateAt, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scienceChannelGroupSyncable.UpdateAt, ReAddRemovedMembers: false}) if pErr != nil { t.Errorf("failed to populate syncables: %s", pErr.Error()) } @@ -363,7 +363,7 @@ func TestCreateDefaultMemberships(t *testing.T) { _, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(scienceGroup.Id, restrictedChannel.Id, true)) require.Nil(t, err) - pErr = th.App.CreateDefaultMemberships(th.Context, 0, false) + pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false}) require.NoError(t, pErr) // Ensure only the restricted user was added to both the team and channel @@ -375,6 +375,113 @@ func TestCreateDefaultMemberships(t *testing.T) { require.Len(t, tmembers, 1) require.Equal(t, tmembers[0].UserId, restrictedUser.Id) }) + + t.Run("scoped to a single user", func(t *testing.T) { + team1, err := th.App.CreateTeam(th.Context, &model.Team{ + DisplayName: "Team 1", + Name: "zz" + model.NewId(), + Email: "team1admin@test.com", + Type: model.TeamOpen, + }) + if err != nil { + t.Errorf("test team not created: %s", err.Error()) + } + + team1Channel1, err := th.App.CreateChannel(th.Context, &model.Channel{ + TeamId: team1.Id, + DisplayName: "Team 1 Channel 1", + Name: model.NewId(), + Type: model.ChannelTypeOpen, + }, false) + if err != nil { + t.Errorf("test channel not created: %s", err.Error()) + } + + group1, err := th.App.CreateGroup(&model.Group{ + Name: model.NewString(model.NewId()), + DisplayName: "Group 1", + RemoteId: model.NewString(model.NewId()), + Source: model.GroupSourceLdap, + }) + if err != nil { + t.Errorf("test group not created: %s", err.Error()) + } + + _, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(group1.Id, team1.Id, true)) + if err != nil { + t.Errorf("test groupchannel not created: %s", err.Error()) + } + + _, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(group1.Id, team1Channel1.Id, true)) + if err != nil { + t.Errorf("test groupchannel not created: %s", err.Error()) + } + + user1 := th.BasicUser + user2 := th.BasicUser2 + + _, err = th.App.UpsertGroupMember(group1.Id, user1.Id) + if err != nil { + t.Errorf("test groupmember not created: %s", err.Error()) + } + + _, err = th.App.UpsertGroupMember(group1.Id, user2.Id) + if err != nil { + t.Errorf("test groupmember not created: %s", err.Error()) + } + + params := model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false, ScopedUserID: &user1.Id} + pErr = th.App.CreateDefaultMemberships(th.Context, params) + if pErr != nil { + t.Errorf("failed to populate syncables: %s", pErr.Error()) + } + + // test that only user 1 is successfully added to the team and channel. + team1Members, err := th.App.GetTeamMembers(team1.Id, 0, 100, nil) + if err != nil { + t.Errorf("failed to get team members: %s", err.Error()) + } + if len(team1Members) != 1 { + t.Errorf("expected 1 team member on team1, got %d", len(team1Members)) + } + if team1Members[0].UserId != user1.Id { + t.Errorf("expected user1 to be a team member on team1, got %s", team1Members[0].UserId) + } + + team1Channel1Members, err := th.App.GetChannelMembersPage(th.Context, team1Channel1.Id, 0, 100) + if err != nil { + t.Errorf("failed to get channel members: %s", err.Error()) + } + if len(team1Channel1Members) != 1 { + t.Errorf("expected 1 channel member on team1Channel1, got %d", len(team1Channel1Members)) + } + if team1Channel1Members[0].UserId != user1.Id { + t.Errorf("expected user1 to be a channel member on team1Channel1, got %s", team1Channel1Members[0].UserId) + } + + // unscoped should add user2 to the team and channel + params = model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false} + pErr = th.App.CreateDefaultMemberships(th.Context, params) + if pErr != nil { + t.Errorf("failed to populate syncables: %s", pErr.Error()) + } + + team1Members, err = th.App.GetTeamMembers(team1.Id, 0, 100, nil) + if err != nil { + t.Errorf("failed to get team members: %s", err.Error()) + } + if len(team1Members) != 2 { + t.Errorf("expected 2 team member on team1, got %d", len(team1Members)) + } + + team1Channel1Members, err = th.App.GetChannelMembersPage(th.Context, team1Channel1.Id, 0, 100) + if err != nil { + t.Errorf("failed to get channel members: %s", err.Error()) + } + if len(team1Channel1Members) != 2 { + t.Errorf("expected 2 channel member on team1Channel1, got %d", len(team1Channel1Members)) + } + }) } func TestDeleteGroupMemberships(t *testing.T) { diff --git a/i18n/en.json b/i18n/en.json index fee81c6f65..b1c57495a7 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -147,6 +147,10 @@ "id": "api.admin.saml.set_certificate_from_metadata.missing_content_type.app_error", "translation": "Missing content type." }, + { + "id": "api.admin.syncables_error", + "translation": "failed to add user to group-teams and group-channels" + }, { "id": "api.admin.test_email.body", "translation": "It appears your Mattermost email is setup correctly!" @@ -3931,6 +3935,10 @@ "id": "api.user.add_direct_channels_and_forget.failed.error", "translation": "Failed to add direct channel preferences for user user_id={{.UserId}}, team_id={{.TeamId}}, err={{.Error}}" }, + { + "id": "api.user.add_user_to_group_syncables.not_ldap_user.app_error", + "translation": "not an ldap user" + }, { "id": "api.user.authorize_oauth_user.bad_response.app_error", "translation": "Bad response from token request." diff --git a/model/client4.go b/model/client4.go index 6ab4ed4952..24ffc859ca 100644 --- a/model/client4.go +++ b/model/client4.go @@ -8458,3 +8458,12 @@ func (c *Client4) GetNewTeamMembersSince(teamID string, timeRange string, page i } return newTeamMembersList, BuildResponse(r), nil } + +func (c *Client4) AddUserToGroupSyncables(userID string) (*Response, error) { + r, err := c.DoAPIPost(c.ldapRoute()+"/users/"+userID+"/group_sync_memberships", "") + if err != nil { + return BuildResponse(r), err + } + defer closeBody(r) + return BuildResponse(r), nil +} diff --git a/model/group.go b/model/group.go index f6ce813c38..20d9533401 100644 --- a/model/group.go +++ b/model/group.go @@ -247,3 +247,11 @@ type GroupsWithCount struct { Groups []*Group `json:"groups"` TotalCount int64 `json:"total_count"` } + +type CreateDefaultMembershipParams struct { + Since int64 + ReAddRemovedMembers bool + ScopedUserID *string + ScopedTeamID *string + ScopedChannelID *string +}