store: guests will only receive results of which channels they are in (#20295)
* store: guests will only receive results of which channels they are in * api4/channel_test: add test case for guest accounts channel autocomplete * apply to searchengine and also for AutocompleteInTeam Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
cffe921e62
Коммит
fe3816cc20
@@ -1339,6 +1339,46 @@ func TestSearchChannels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NotContains(t, channelNames, th.BasicChannel.Name)
|
require.NotContains(t, channelNames, th.BasicChannel.Name)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Guests only receive autocompletion for which accounts they are a member of", func(t *testing.T) {
|
||||||
|
th.App.Srv().SetLicense(model.NewTestLicense(""))
|
||||||
|
defer th.App.Srv().SetLicense(nil)
|
||||||
|
|
||||||
|
enableGuestAccounts := *th.App.Config().GuestAccountsSettings.Enable
|
||||||
|
defer func() {
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.GuestAccountsSettings.Enable = &enableGuestAccounts })
|
||||||
|
}()
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true })
|
||||||
|
|
||||||
|
guest := th.CreateUser()
|
||||||
|
_, appErr := th.SystemAdminClient.DemoteUserToGuest(guest.Id)
|
||||||
|
require.NoError(t, appErr)
|
||||||
|
|
||||||
|
_, resp, err := th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, guest.Id)
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckCreatedStatus(t, resp)
|
||||||
|
|
||||||
|
_, resp, err = client.Login(guest.Username, guest.Password)
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckOKStatus(t, resp)
|
||||||
|
|
||||||
|
search.Term = th.BasicChannel2.Name
|
||||||
|
channelList, _, err := client.SearchChannels(th.BasicTeam.Id, search)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Empty(t, channelList)
|
||||||
|
|
||||||
|
_, resp, err = th.SystemAdminClient.AddChannelMember(th.BasicChannel2.Id, guest.Id)
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckCreatedStatus(t, resp)
|
||||||
|
|
||||||
|
search.Term = th.BasicChannel2.Name
|
||||||
|
channelList, _, err = client.SearchChannels(th.BasicTeam.Id, search)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NotEmpty(t, channelList)
|
||||||
|
require.Equal(t, th.BasicChannel2.Id, channelList[0].Id)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSearchArchivedChannels(t *testing.T) {
|
func TestSearchArchivedChannels(t *testing.T) {
|
||||||
|
|||||||
@@ -2781,7 +2781,12 @@ func (a *App) AutocompleteChannels(userID, term string) (model.ChannelListWithTe
|
|||||||
includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels
|
includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels
|
||||||
term = strings.TrimSpace(term)
|
term = strings.TrimSpace(term)
|
||||||
|
|
||||||
channelList, err := a.Srv().Store.Channel().Autocomplete(userID, term, includeDeleted)
|
user, appErr := a.GetUser(userID)
|
||||||
|
if appErr != nil {
|
||||||
|
return nil, appErr
|
||||||
|
}
|
||||||
|
|
||||||
|
channelList, err := a.Srv().Store.Channel().Autocomplete(userID, term, includeDeleted, user.IsGuest())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("AutocompleteChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("AutocompleteChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -2793,7 +2798,12 @@ func (a *App) AutocompleteChannelsForTeam(teamID, userID, term string) (model.Ch
|
|||||||
includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels
|
includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels
|
||||||
term = strings.TrimSpace(term)
|
term = strings.TrimSpace(term)
|
||||||
|
|
||||||
channelList, err := a.Srv().Store.Channel().AutocompleteInTeam(teamID, userID, term, includeDeleted)
|
user, appErr := a.GetUser(userID)
|
||||||
|
if appErr != nil {
|
||||||
|
return nil, appErr
|
||||||
|
}
|
||||||
|
|
||||||
|
channelList, err := a.Srv().Store.Channel().AutocompleteInTeam(teamID, userID, term, includeDeleted, user.IsGuest())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("AutocompleteChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("AutocompleteChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ func (b *BleveEngine) IndexChannel(channel *model.Channel, userIDs, teamMemberID
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BleveEngine) SearchChannels(teamId, userID, term string) ([]string, *model.AppError) {
|
func (b *BleveEngine) SearchChannels(teamId, userID, term string, isGuest bool) ([]string, *model.AppError) {
|
||||||
// This query essentially boils down to (if teamID is passed):
|
// This query essentially boils down to (if teamID is passed):
|
||||||
// match teamID == <>
|
// match teamID == <>
|
||||||
// AND
|
// AND
|
||||||
@@ -329,6 +329,13 @@ func (b *BleveEngine) SearchChannels(teamId, userID, term string) ([]string, *mo
|
|||||||
// AND
|
// AND
|
||||||
// match (channelType != 'P' || (<> in userIDs && channelType == 'P'))
|
// match (channelType != 'P' || (<> in userIDs && channelType == 'P'))
|
||||||
|
|
||||||
|
// (or if isGuest is true)
|
||||||
|
// <> in teamMemberIds
|
||||||
|
// AND
|
||||||
|
// match term == <>
|
||||||
|
// AND
|
||||||
|
// match (<> in userIDs)
|
||||||
|
|
||||||
queries := []query.Query{}
|
queries := []query.Query{}
|
||||||
if teamId != "" {
|
if teamId != "" {
|
||||||
teamIdQ := bleve.NewTermQuery(teamId)
|
teamIdQ := bleve.NewTermQuery(teamId)
|
||||||
@@ -340,22 +347,29 @@ func (b *BleveEngine) SearchChannels(teamId, userID, term string) ([]string, *mo
|
|||||||
queries = append(queries, teamMemberQ)
|
queries = append(queries, teamMemberQ)
|
||||||
}
|
}
|
||||||
|
|
||||||
boolNotPrivate := bleve.NewBooleanQuery()
|
if isGuest {
|
||||||
privateQ := bleve.NewTermQuery(string(model.ChannelTypePrivate))
|
userQ := bleve.NewBooleanQuery()
|
||||||
privateQ.SetField("Type")
|
userIDQ := bleve.NewTermQuery(userID)
|
||||||
boolNotPrivate.AddMustNot(privateQ)
|
userIDQ.SetField("UserIDs")
|
||||||
|
userQ.AddMust(userIDQ)
|
||||||
|
queries = append(queries, userIDQ)
|
||||||
|
} else {
|
||||||
|
boolNotPrivate := bleve.NewBooleanQuery()
|
||||||
|
privateQ := bleve.NewTermQuery(string(model.ChannelTypePrivate))
|
||||||
|
privateQ.SetField("Type")
|
||||||
|
boolNotPrivate.AddMustNot(privateQ)
|
||||||
|
|
||||||
userQ := bleve.NewBooleanQuery()
|
userQ := bleve.NewBooleanQuery()
|
||||||
userIDQ := bleve.NewTermQuery(userID)
|
userIDQ := bleve.NewTermQuery(userID)
|
||||||
userIDQ.SetField("UserIDs")
|
userIDQ.SetField("UserIDs")
|
||||||
userQ.AddMust(userIDQ)
|
userQ.AddMust(userIDQ)
|
||||||
userQ.AddMust(privateQ)
|
userQ.AddMust(privateQ)
|
||||||
|
|
||||||
channelTypeQ := bleve.NewDisjunctionQuery()
|
channelTypeQ := bleve.NewDisjunctionQuery()
|
||||||
channelTypeQ.AddQuery(boolNotPrivate)
|
channelTypeQ.AddQuery(boolNotPrivate)
|
||||||
channelTypeQ.AddQuery(userQ) // userID && 'p'
|
channelTypeQ.AddQuery(userQ) // userID && 'p'
|
||||||
|
queries = append(queries, channelTypeQ)
|
||||||
queries = append(queries, channelTypeQ)
|
}
|
||||||
|
|
||||||
if term != "" {
|
if term != "" {
|
||||||
nameSuggestQ := bleve.NewPrefixQuery(strings.ToLower(term))
|
nameSuggestQ := bleve.NewPrefixQuery(strings.ToLower(term))
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type SearchEngineInterface interface {
|
|||||||
// IndexChannel indexes a given channel. The userIDs are only populated
|
// IndexChannel indexes a given channel. The userIDs are only populated
|
||||||
// for private channels.
|
// for private channels.
|
||||||
IndexChannel(channel *model.Channel, userIDs, teamMemberIDs []string) *model.AppError
|
IndexChannel(channel *model.Channel, userIDs, teamMemberIDs []string) *model.AppError
|
||||||
SearchChannels(teamId, userID, term string) ([]string, *model.AppError)
|
SearchChannels(teamId, userID, term string, isGuest bool) ([]string, *model.AppError)
|
||||||
DeleteChannel(channel *model.Channel) *model.AppError
|
DeleteChannel(channel *model.Channel) *model.AppError
|
||||||
IndexUser(user *model.User, teamsIds, channelsIds []string) *model.AppError
|
IndexUser(user *model.User, teamsIds, channelsIds []string) *model.AppError
|
||||||
SearchUsersInChannel(teamId, channelId string, restrictedToChannels []string, term string, options *model.UserSearchOptions) ([]string, []string, *model.AppError)
|
SearchUsersInChannel(teamId, channelId string, restrictedToChannels []string, term string, options *model.UserSearchOptions) ([]string, []string, *model.AppError)
|
||||||
|
|||||||
@@ -400,13 +400,13 @@ func (_m *SearchEngineInterface) RefreshIndexes() *model.AppError {
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchChannels provides a mock function with given fields: teamId, userID, term
|
// SearchChannels provides a mock function with given fields: teamId, userID, term, isGuest
|
||||||
func (_m *SearchEngineInterface) SearchChannels(teamId string, userID string, term string) ([]string, *model.AppError) {
|
func (_m *SearchEngineInterface) SearchChannels(teamId string, userID string, term string, isGuest bool) ([]string, *model.AppError) {
|
||||||
ret := _m.Called(teamId, userID, term)
|
ret := _m.Called(teamId, userID, term, isGuest)
|
||||||
|
|
||||||
var r0 []string
|
var r0 []string
|
||||||
if rf, ok := ret.Get(0).(func(string, string, string) []string); ok {
|
if rf, ok := ret.Get(0).(func(string, string, string, bool) []string); ok {
|
||||||
r0 = rf(teamId, userID, term)
|
r0 = rf(teamId, userID, term, isGuest)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]string)
|
r0 = ret.Get(0).([]string)
|
||||||
@@ -414,8 +414,8 @@ func (_m *SearchEngineInterface) SearchChannels(teamId string, userID string, te
|
|||||||
}
|
}
|
||||||
|
|
||||||
var r1 *model.AppError
|
var r1 *model.AppError
|
||||||
if rf, ok := ret.Get(1).(func(string, string, string) *model.AppError); ok {
|
if rf, ok := ret.Get(1).(func(string, string, string, bool) *model.AppError); ok {
|
||||||
r1 = rf(teamId, userID, term)
|
r1 = rf(teamId, userID, term, isGuest)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(1) != nil {
|
if ret.Get(1) != nil {
|
||||||
r1 = ret.Get(1).(*model.AppError)
|
r1 = ret.Get(1).(*model.AppError)
|
||||||
|
|||||||
@@ -570,7 +570,7 @@ func (s *OpenTracingLayerChannelStore) AnalyticsTypeCount(teamID string, channel
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *OpenTracingLayerChannelStore) Autocomplete(userID string, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (s *OpenTracingLayerChannelStore) Autocomplete(userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
origCtx := s.Root.Store.Context()
|
origCtx := s.Root.Store.Context()
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.Autocomplete")
|
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.Autocomplete")
|
||||||
s.Root.Store.SetContext(newCtx)
|
s.Root.Store.SetContext(newCtx)
|
||||||
@@ -579,7 +579,7 @@ func (s *OpenTracingLayerChannelStore) Autocomplete(userID string, term string,
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
result, err := s.ChannelStore.Autocomplete(userID, term, includeDeleted)
|
result, err := s.ChannelStore.Autocomplete(userID, term, includeDeleted, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.LogFields(spanlog.Error(err))
|
span.LogFields(spanlog.Error(err))
|
||||||
ext.Error.Set(span, true)
|
ext.Error.Set(span, true)
|
||||||
@@ -588,7 +588,7 @@ func (s *OpenTracingLayerChannelStore) Autocomplete(userID string, term string,
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *OpenTracingLayerChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (s *OpenTracingLayerChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelList, error) {
|
||||||
origCtx := s.Root.Store.Context()
|
origCtx := s.Root.Store.Context()
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.AutocompleteInTeam")
|
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.AutocompleteInTeam")
|
||||||
s.Root.Store.SetContext(newCtx)
|
s.Root.Store.SetContext(newCtx)
|
||||||
@@ -597,7 +597,7 @@ func (s *OpenTracingLayerChannelStore) AutocompleteInTeam(teamID string, userID
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
result, err := s.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted)
|
result, err := s.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.LogFields(spanlog.Error(err))
|
span.LogFields(spanlog.Error(err))
|
||||||
ext.Error.Set(span, true)
|
ext.Error.Set(span, true)
|
||||||
|
|||||||
@@ -619,11 +619,11 @@ func (s *RetryLayerChannelStore) AnalyticsTypeCount(teamID string, channelType m
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RetryLayerChannelStore) Autocomplete(userID string, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (s *RetryLayerChannelStore) Autocomplete(userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
|
|
||||||
tries := 0
|
tries := 0
|
||||||
for {
|
for {
|
||||||
result, err := s.ChannelStore.Autocomplete(userID, term, includeDeleted)
|
result, err := s.ChannelStore.Autocomplete(userID, term, includeDeleted, isGuest)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@@ -640,11 +640,11 @@ func (s *RetryLayerChannelStore) Autocomplete(userID string, term string, includ
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RetryLayerChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (s *RetryLayerChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelList, error) {
|
||||||
|
|
||||||
tries := 0
|
tries := 0
|
||||||
for {
|
for {
|
||||||
result, err := s.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted)
|
result, err := s.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted, isGuest)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,14 +161,14 @@ func (c *SearchChannelStore) SaveDirectChannel(directchannel *model.Channel, mem
|
|||||||
return channel, err
|
return channel, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SearchChannelStore) Autocomplete(userID, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (c *SearchChannelStore) Autocomplete(userID, term string, includeDeleted, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
var channelList model.ChannelListWithTeamData
|
var channelList model.ChannelListWithTeamData
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
allFailed := true
|
allFailed := true
|
||||||
for _, engine := range c.rootStore.searchEngine.GetActiveEngines() {
|
for _, engine := range c.rootStore.searchEngine.GetActiveEngines() {
|
||||||
if engine.IsAutocompletionEnabled() {
|
if engine.IsAutocompletionEnabled() {
|
||||||
channelList, err = c.searchAutocompleteChannelsAllTeams(engine, userID, term, includeDeleted)
|
channelList, err = c.searchAutocompleteChannelsAllTeams(engine, userID, term, includeDeleted, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mlog.Warn("Encountered error on AutocompleteChannels through SearchEngine. Falling back to default autocompletion.", mlog.String("search_engine", engine.GetName()), mlog.Err(err))
|
mlog.Warn("Encountered error on AutocompleteChannels through SearchEngine. Falling back to default autocompletion.", mlog.String("search_engine", engine.GetName()), mlog.Err(err))
|
||||||
continue
|
continue
|
||||||
@@ -181,7 +181,7 @@ func (c *SearchChannelStore) Autocomplete(userID, term string, includeDeleted bo
|
|||||||
|
|
||||||
if allFailed {
|
if allFailed {
|
||||||
mlog.Debug("Using database search because no other search engine is available")
|
mlog.Debug("Using database search because no other search engine is available")
|
||||||
channelList, err = c.ChannelStore.Autocomplete(userID, term, includeDeleted)
|
channelList, err = c.ChannelStore.Autocomplete(userID, term, includeDeleted, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Failed to autocomplete channels in team")
|
return nil, errors.Wrap(err, "Failed to autocomplete channels in team")
|
||||||
}
|
}
|
||||||
@@ -194,14 +194,14 @@ func (c *SearchChannelStore) Autocomplete(userID, term string, includeDeleted bo
|
|||||||
return channelList, nil
|
return channelList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SearchChannelStore) AutocompleteInTeam(teamID, userID, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (c *SearchChannelStore) AutocompleteInTeam(teamID, userID, term string, includeDeleted, isGuest bool) (model.ChannelList, error) {
|
||||||
var channelList model.ChannelList
|
var channelList model.ChannelList
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
allFailed := true
|
allFailed := true
|
||||||
for _, engine := range c.rootStore.searchEngine.GetActiveEngines() {
|
for _, engine := range c.rootStore.searchEngine.GetActiveEngines() {
|
||||||
if engine.IsAutocompletionEnabled() {
|
if engine.IsAutocompletionEnabled() {
|
||||||
channelList, err = c.searchAutocompleteChannels(engine, teamID, userID, term, includeDeleted)
|
channelList, err = c.searchAutocompleteChannels(engine, teamID, userID, term, includeDeleted, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mlog.Warn("Encountered error on AutocompleteChannels through SearchEngine. Falling back to default autocompletion.", mlog.String("search_engine", engine.GetName()), mlog.Err(err))
|
mlog.Warn("Encountered error on AutocompleteChannels through SearchEngine. Falling back to default autocompletion.", mlog.String("search_engine", engine.GetName()), mlog.Err(err))
|
||||||
continue
|
continue
|
||||||
@@ -214,7 +214,7 @@ func (c *SearchChannelStore) AutocompleteInTeam(teamID, userID, term string, inc
|
|||||||
|
|
||||||
if allFailed {
|
if allFailed {
|
||||||
mlog.Debug("Using database search because no other search engine is available")
|
mlog.Debug("Using database search because no other search engine is available")
|
||||||
channelList, err = c.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted)
|
channelList, err = c.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Failed to autocomplete channels in team")
|
return nil, errors.Wrap(err, "Failed to autocomplete channels in team")
|
||||||
}
|
}
|
||||||
@@ -227,8 +227,8 @@ func (c *SearchChannelStore) AutocompleteInTeam(teamID, userID, term string, inc
|
|||||||
return channelList, nil
|
return channelList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SearchChannelStore) searchAutocompleteChannels(engine searchengine.SearchEngineInterface, teamId, userID, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (c *SearchChannelStore) searchAutocompleteChannels(engine searchengine.SearchEngineInterface, teamId, userID, term string, includeDeleted, isGuest bool) (model.ChannelList, error) {
|
||||||
channelIds, err := engine.SearchChannels(teamId, userID, term)
|
channelIds, err := engine.SearchChannels(teamId, userID, term, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -245,8 +245,8 @@ func (c *SearchChannelStore) searchAutocompleteChannels(engine searchengine.Sear
|
|||||||
return channelList, nil
|
return channelList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SearchChannelStore) searchAutocompleteChannelsAllTeams(engine searchengine.SearchEngineInterface, userID, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (c *SearchChannelStore) searchAutocompleteChannelsAllTeams(engine searchengine.SearchEngineInterface, userID, term string, includeDeleted, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
channelIds, err := engine.SearchChannels("", userID, term)
|
channelIds, err := engine.SearchChannels("", userID, term, isGuest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,11 +94,11 @@ func testAutocompleteChannelByName(t *testing.T, th *SearchTestHelper) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(private)
|
defer th.deleteChannel(private)
|
||||||
|
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id}, res)
|
||||||
|
|
||||||
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channel-a", false)
|
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channel-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id, th.ChannelAnotherTeam.Id}, res2)
|
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id, th.ChannelAnotherTeam.Id}, res2)
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ func testAutocompleteChannelByNamePostgres(t *testing.T, th *SearchTestHelper) {
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "Channel Alternate", "Channel Alternate", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "Channel Alternate", "Channel Alternate", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
||||||
}
|
}
|
||||||
@@ -121,11 +121,11 @@ func testAutocompleteChannelByDisplayName(t *testing.T, th *SearchTestHelper) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(private)
|
defer th.deleteChannel(private)
|
||||||
|
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "ChannelA", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "ChannelA", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id}, res)
|
||||||
|
|
||||||
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "ChannelA", false)
|
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "ChannelA", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id, th.ChannelAnotherTeam.Id}, res2)
|
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelBasic.Id, alternate.Id, private.Id, th.ChannelAnotherTeam.Id}, res2)
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ func testAutocompleteChannelByNameSplittedWithDashChar(t *testing.T, th *SearchT
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ func testAutocompleteChannelByNameSplittedWithDashCharPostgres(t *testing.T, th
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
||||||
}
|
}
|
||||||
@@ -152,11 +152,11 @@ func testAutocompleteChannelByNameSplittedWithUnderscoreChar(t *testing.T, th *S
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel_alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel_alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel_a", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel_a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{alternate.Id}, res)
|
||||||
|
|
||||||
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channel_a", false)
|
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channel_a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatchWithTeamData(t, []string{alternate.Id}, res2)
|
th.checkChannelIdsMatchWithTeamData(t, []string{alternate.Id}, res2)
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ func testAutocompleteChannelByDisplayNameSplittedByWhitespaces(t *testing.T, th
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "Channel A", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "Channel A", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{alternate.Id}, res)
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ func testAutocompleteAllChannelsIfTermIsEmpty(t *testing.T, th *SearchTestHelper
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
defer th.deleteChannel(other)
|
defer th.deleteChannel(other)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id, other.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id, other.Id}, res)
|
||||||
}
|
}
|
||||||
@@ -186,17 +186,17 @@ func testSearchChannelsInCaseInsensitiveManner(t *testing.T, th *SearchTestHelpe
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channela", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channela", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
||||||
res, err = th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "ChAnNeL-a", false)
|
res, err = th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "ChAnNeL-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
||||||
|
|
||||||
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channela", false)
|
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channela", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelAnotherTeam.Id, th.ChannelBasic.Id, alternate.Id}, res2)
|
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelAnotherTeam.Id, th.ChannelBasic.Id, alternate.Id}, res2)
|
||||||
res2, err = th.Store.Channel().Autocomplete(th.User.Id, "ChAnNeL-a", false)
|
res2, err = th.Store.Channel().Autocomplete(th.User.Id, "ChAnNeL-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelAnotherTeam.Id, th.ChannelBasic.Id, alternate.Id}, res2)
|
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelAnotherTeam.Id, th.ChannelBasic.Id, alternate.Id}, res2)
|
||||||
}
|
}
|
||||||
@@ -205,10 +205,10 @@ func testSearchChannelsInCaseInsensitiveMannerPostgres(t *testing.T, th *SearchT
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channela", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channela", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, alternate.Id}, res)
|
||||||
res, err = th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "ChAnNeL-a", false)
|
res, err = th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "ChAnNeL-a", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
||||||
}
|
}
|
||||||
@@ -217,17 +217,17 @@ func testSearchShouldSupportHavingHyphenAsLastCharacter(t *testing.T, th *Search
|
|||||||
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
alternate, err := th.createChannel(th.Team.Id, "channel-alternate", "ChannelAlternate", "", model.ChannelTypeOpen, th.User, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer th.deleteChannel(alternate)
|
defer th.deleteChannel(alternate)
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-", false)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res)
|
||||||
|
|
||||||
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channel-", false)
|
res2, err := th.Store.Channel().Autocomplete(th.User.Id, "channel-", false, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelAnotherTeam.Id, th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res2)
|
th.checkChannelIdsMatchWithTeamData(t, []string{th.ChannelAnotherTeam.Id, th.ChannelBasic.Id, th.ChannelPrivate.Id, alternate.Id}, res2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSearchShouldSupportAutocompleteWithArchivedChannels(t *testing.T, th *SearchTestHelper) {
|
func testSearchShouldSupportAutocompleteWithArchivedChannels(t *testing.T, th *SearchTestHelper) {
|
||||||
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-", true)
|
res, err := th.Store.Channel().AutocompleteInTeam(th.Team.Id, th.User.Id, "channel-", true, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, th.ChannelDeleted.Id}, res)
|
th.checkChannelIdsMatch(t, []string{th.ChannelBasic.Id, th.ChannelPrivate.Id, th.ChannelDeleted.Id}, res)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2921,7 +2921,7 @@ func (s SqlChannelStore) GetTeamMembersForChannel(channelID string) ([]string, e
|
|||||||
return teamMemberIDs, nil
|
return teamMemberIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) Autocomplete(userID, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (s SqlChannelStore) Autocomplete(userID, term string, includeDeleted, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
query := s.getQueryBuilder().Select("c.*",
|
query := s.getQueryBuilder().Select("c.*",
|
||||||
"t.DisplayName AS TeamDisplayName",
|
"t.DisplayName AS TeamDisplayName",
|
||||||
"t.Name AS TeamName",
|
"t.Name AS TeamName",
|
||||||
@@ -2931,15 +2931,6 @@ func (s SqlChannelStore) Autocomplete(userID, term string, includeDeleted bool)
|
|||||||
sq.Expr("c.TeamId = t.id"),
|
sq.Expr("c.TeamId = t.id"),
|
||||||
sq.Expr("t.id = tm.TeamId"),
|
sq.Expr("t.id = tm.TeamId"),
|
||||||
sq.Eq{"tm.UserId": userID},
|
sq.Eq{"tm.UserId": userID},
|
||||||
sq.Or{
|
|
||||||
sq.NotEq{"c.Type": model.ChannelTypePrivate},
|
|
||||||
sq.And{
|
|
||||||
sq.Eq{"c.Type": model.ChannelTypePrivate},
|
|
||||||
sq.Expr("c.Id IN (?)", sq.Select("ChannelId").
|
|
||||||
From("ChannelMembers").
|
|
||||||
Where(sq.Eq{"UserId": userID})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).
|
}).
|
||||||
OrderBy("c.DisplayName")
|
OrderBy("c.DisplayName")
|
||||||
|
|
||||||
@@ -2949,6 +2940,23 @@ func (s SqlChannelStore) Autocomplete(userID, term string, includeDeleted bool)
|
|||||||
sq.Eq{"tm.DeleteAt": 0},
|
sq.Eq{"tm.DeleteAt": 0},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isGuest {
|
||||||
|
query = query.Where(sq.Expr("c.Id IN (?)", sq.Select("ChannelId").
|
||||||
|
From("ChannelMembers").
|
||||||
|
Where(sq.Eq{"UserId": userID})))
|
||||||
|
} else {
|
||||||
|
query = query.Where(sq.Or{
|
||||||
|
sq.NotEq{"c.Type": model.ChannelTypePrivate},
|
||||||
|
sq.And{
|
||||||
|
sq.Eq{"c.Type": model.ChannelTypePrivate},
|
||||||
|
sq.Expr("c.Id IN (?)", sq.Select("ChannelId").
|
||||||
|
From("ChannelMembers").
|
||||||
|
Where(sq.Eq{"UserId": userID})),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
searchClause := s.searchClause(term)
|
searchClause := s.searchClause(term)
|
||||||
if searchClause != nil {
|
if searchClause != nil {
|
||||||
query = query.Where(searchClause)
|
query = query.Where(searchClause)
|
||||||
@@ -2967,21 +2975,10 @@ func (s SqlChannelStore) Autocomplete(userID, term string, includeDeleted bool)
|
|||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) AutocompleteInTeam(teamID, userID, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (s SqlChannelStore) AutocompleteInTeam(teamID, userID, term string, includeDeleted, isGuest bool) (model.ChannelList, error) {
|
||||||
query := s.getQueryBuilder().Select("*").
|
query := s.getQueryBuilder().Select("*").
|
||||||
From("Channels c").
|
From("Channels c").
|
||||||
Where(sq.And{
|
Where(sq.Eq{"c.TeamId": teamID}).
|
||||||
sq.Eq{"c.TeamId": teamID},
|
|
||||||
sq.Or{
|
|
||||||
sq.NotEq{"c.Type": model.ChannelTypePrivate},
|
|
||||||
sq.And{
|
|
||||||
sq.Eq{"c.Type": model.ChannelTypePrivate},
|
|
||||||
sq.Expr("c.Id IN (?)", sq.Select("ChannelId").
|
|
||||||
From("ChannelMembers").
|
|
||||||
Where(sq.Eq{"UserId": userID})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).
|
|
||||||
OrderBy("c.DisplayName").
|
OrderBy("c.DisplayName").
|
||||||
Limit(model.ChannelSearchDefaultLimit)
|
Limit(model.ChannelSearchDefaultLimit)
|
||||||
|
|
||||||
@@ -2989,6 +2986,22 @@ func (s SqlChannelStore) AutocompleteInTeam(teamID, userID, term string, include
|
|||||||
query = query.Where(sq.Eq{"c.DeleteAt": 0})
|
query = query.Where(sq.Eq{"c.DeleteAt": 0})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isGuest {
|
||||||
|
query = query.Where(sq.Expr("c.Id IN (?)", sq.Select("ChannelId").
|
||||||
|
From("ChannelMembers").
|
||||||
|
Where(sq.Eq{"UserId": userID})))
|
||||||
|
} else {
|
||||||
|
query = query.Where(sq.Or{
|
||||||
|
sq.NotEq{"c.Type": model.ChannelTypePrivate},
|
||||||
|
sq.And{
|
||||||
|
sq.Eq{"c.Type": model.ChannelTypePrivate},
|
||||||
|
sq.Expr("c.Id IN (?)", sq.Select("ChannelId").
|
||||||
|
From("ChannelMembers").
|
||||||
|
Where(sq.Eq{"UserId": userID})),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
searchClause := s.searchClause(term)
|
searchClause := s.searchClause(term)
|
||||||
if searchClause != nil {
|
if searchClause != nil {
|
||||||
query = query.Where(searchClause)
|
query = query.Where(searchClause)
|
||||||
|
|||||||
@@ -235,8 +235,8 @@ type ChannelStore interface {
|
|||||||
GetTeamMembersForChannel(channelID string) ([]string, error)
|
GetTeamMembersForChannel(channelID string) ([]string, error)
|
||||||
GetMembersForUserWithPagination(userID string, page, perPage int) (model.ChannelMembersWithTeamData, error)
|
GetMembersForUserWithPagination(userID string, page, perPage int) (model.ChannelMembersWithTeamData, error)
|
||||||
GetMembersForUserWithCursor(userID, teamID string, opts *ChannelMemberGraphQLSearchOpts) (model.ChannelMembers, error)
|
GetMembersForUserWithCursor(userID, teamID string, opts *ChannelMemberGraphQLSearchOpts) (model.ChannelMembers, error)
|
||||||
Autocomplete(userID, term string, includeDeleted bool) (model.ChannelListWithTeamData, error)
|
Autocomplete(userID, term string, includeDeleted, isGuest bool) (model.ChannelListWithTeamData, error)
|
||||||
AutocompleteInTeam(teamID, userID, term string, includeDeleted bool) (model.ChannelList, error)
|
AutocompleteInTeam(teamID, userID, term string, includeDeleted, isGuest bool) (model.ChannelList, error)
|
||||||
AutocompleteInTeamForSearch(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error)
|
AutocompleteInTeamForSearch(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error)
|
||||||
SearchAllChannels(term string, opts ChannelSearchOpts) (model.ChannelListWithTeamData, int64, error)
|
SearchAllChannels(term string, opts ChannelSearchOpts) (model.ChannelListWithTeamData, int64, error)
|
||||||
SearchInTeam(teamID string, term string, includeDeleted bool) (model.ChannelList, error)
|
SearchInTeam(teamID string, term string, includeDeleted bool) (model.ChannelList, error)
|
||||||
|
|||||||
@@ -5899,7 +5899,7 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
t.Run("AutoCompleteInTeam/"+testCase.Description, func(t *testing.T) {
|
t.Run("AutoCompleteInTeam/"+testCase.Description, func(t *testing.T) {
|
||||||
channels, err := ss.Channel().AutocompleteInTeam(testCase.TeamID, testCase.UserID, testCase.Term, testCase.IncludeDeleted)
|
channels, err := ss.Channel().AutocompleteInTeam(testCase.TeamID, testCase.UserID, testCase.Term, testCase.IncludeDeleted, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sort.Sort(ByChannelDisplayName(channels))
|
sort.Sort(ByChannelDisplayName(channels))
|
||||||
require.Equal(t, testCase.ExpectedResults, channels)
|
require.Equal(t, testCase.ExpectedResults, channels)
|
||||||
@@ -5946,6 +5946,15 @@ func testAutocomplete(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Channel().Save(&o2, -1)
|
_, err = ss.Channel().Save(&o2, -1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
o6 := model.Channel{
|
||||||
|
TeamId: teamID,
|
||||||
|
DisplayName: "ChannelA3",
|
||||||
|
Name: NewTestId(),
|
||||||
|
Type: model.ChannelTypeOpen,
|
||||||
|
}
|
||||||
|
_, err = ss.Channel().Save(&o6, -1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
m1 := model.ChannelMember{
|
m1 := model.ChannelMember{
|
||||||
ChannelId: o1.Id,
|
ChannelId: o1.Id,
|
||||||
UserId: model.NewId(),
|
UserId: model.NewId(),
|
||||||
@@ -6063,20 +6072,22 @@ func testAutocomplete(t *testing.T, ss store.Store) {
|
|||||||
UserID string
|
UserID string
|
||||||
Term string
|
Term string
|
||||||
IncludeDeleted bool
|
IncludeDeleted bool
|
||||||
|
IsGuest bool
|
||||||
ExpectedChannelIds []string
|
ExpectedChannelIds []string
|
||||||
ExpectedTeamNames []string
|
ExpectedTeamNames []string
|
||||||
}{
|
}{
|
||||||
{"user 1, Channel A", m1.UserId, "ChannelA", false, []string{o1.Id, o2.Id}, []string{t1.Name, t2.Name}},
|
{"user 1, Channel A", m1.UserId, "ChannelA", false, false, []string{o1.Id, o2.Id, o6.Id}, []string{t1.Name, t2.Name, t1.Name}},
|
||||||
{"user 1, Channel B", m1.UserId, "ChannelB", false, []string{o4.Id}, []string{t2.Name}},
|
{"user 1, Channel B", m1.UserId, "ChannelB", false, false, []string{o4.Id}, []string{t2.Name}},
|
||||||
{"user 2, Channel A", m3.UserId, "ChannelA", false, []string{o3.Id, o1.Id, o2.Id}, []string{t2.Name, t1.Name, t1.Name}},
|
{"user 2, Channel A", m3.UserId, "ChannelA", false, false, []string{o3.Id, o1.Id, o2.Id, o6.Id}, []string{t2.Name, t1.Name, t1.Name, t1.Name}},
|
||||||
{"user 2, Channel B", m3.UserId, "ChannelB", false, nil, nil},
|
{"user 2 guest, Channel A", m3.UserId, "ChannelA", false, true, []string{o2.Id, o3.Id}, []string{t2.Name, t1.Name}},
|
||||||
{"user 1, empty string", m1.UserId, "", false, []string{o1.Id, o2.Id, o4.Id}, []string{t1.Name, t2.Name, t2.Name}},
|
{"user 2, Channel B", m3.UserId, "ChannelB", false, false, nil, nil},
|
||||||
{"user 2, empty string", m3.UserId, "", false, []string{o1.Id, o2.Id, o3.Id}, []string{t1.Name, t2.Name, t1.Name}},
|
{"user 1, empty string", m1.UserId, "", false, false, []string{o1.Id, o2.Id, o4.Id, o6.Id}, []string{t1.Name, t2.Name, t2.Name, t1.Name}},
|
||||||
|
{"user 2, empty string", m3.UserId, "", false, false, []string{o1.Id, o2.Id, o3.Id, o6.Id}, []string{t1.Name, t2.Name, t1.Name, t1.Name}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
t.Run("Autocomplete/"+testCase.Description, func(t *testing.T) {
|
t.Run("Autocomplete/"+testCase.Description, func(t *testing.T) {
|
||||||
channels, err := ss.Channel().Autocomplete(testCase.UserID, testCase.Term, testCase.IncludeDeleted)
|
channels, err := ss.Channel().Autocomplete(testCase.UserID, testCase.Term, testCase.IncludeDeleted, testCase.IsGuest)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
var gotChannelIds []string
|
var gotChannelIds []string
|
||||||
var gotTeamNames []string
|
var gotTeamNames []string
|
||||||
@@ -6084,8 +6095,8 @@ func testAutocomplete(t *testing.T, ss store.Store) {
|
|||||||
gotChannelIds = append(gotChannelIds, ch.Id)
|
gotChannelIds = append(gotChannelIds, ch.Id)
|
||||||
gotTeamNames = append(gotTeamNames, ch.TeamName)
|
gotTeamNames = append(gotTeamNames, ch.TeamName)
|
||||||
}
|
}
|
||||||
require.ElementsMatch(t, testCase.ExpectedChannelIds, gotChannelIds)
|
require.ElementsMatch(t, testCase.ExpectedChannelIds, gotChannelIds, "channels IDs are not as expected")
|
||||||
require.ElementsMatch(t, testCase.ExpectedTeamNames, gotTeamNames)
|
require.ElementsMatch(t, testCase.ExpectedTeamNames, gotTeamNames, "team names are not as expected")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,13 +60,13 @@ func (_m *ChannelStore) AnalyticsTypeCount(teamID string, channelType model.Chan
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autocomplete provides a mock function with given fields: userID, term, includeDeleted
|
// Autocomplete provides a mock function with given fields: userID, term, includeDeleted, isGuest
|
||||||
func (_m *ChannelStore) Autocomplete(userID string, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (_m *ChannelStore) Autocomplete(userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
ret := _m.Called(userID, term, includeDeleted)
|
ret := _m.Called(userID, term, includeDeleted, isGuest)
|
||||||
|
|
||||||
var r0 model.ChannelListWithTeamData
|
var r0 model.ChannelListWithTeamData
|
||||||
if rf, ok := ret.Get(0).(func(string, string, bool) model.ChannelListWithTeamData); ok {
|
if rf, ok := ret.Get(0).(func(string, string, bool, bool) model.ChannelListWithTeamData); ok {
|
||||||
r0 = rf(userID, term, includeDeleted)
|
r0 = rf(userID, term, includeDeleted, isGuest)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(model.ChannelListWithTeamData)
|
r0 = ret.Get(0).(model.ChannelListWithTeamData)
|
||||||
@@ -74,8 +74,8 @@ func (_m *ChannelStore) Autocomplete(userID string, term string, includeDeleted
|
|||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(string, string, bool) error); ok {
|
if rf, ok := ret.Get(1).(func(string, string, bool, bool) error); ok {
|
||||||
r1 = rf(userID, term, includeDeleted)
|
r1 = rf(userID, term, includeDeleted, isGuest)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
@@ -83,13 +83,13 @@ func (_m *ChannelStore) Autocomplete(userID string, term string, includeDeleted
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutocompleteInTeam provides a mock function with given fields: teamID, userID, term, includeDeleted
|
// AutocompleteInTeam provides a mock function with given fields: teamID, userID, term, includeDeleted, isGuest
|
||||||
func (_m *ChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (_m *ChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelList, error) {
|
||||||
ret := _m.Called(teamID, userID, term, includeDeleted)
|
ret := _m.Called(teamID, userID, term, includeDeleted, isGuest)
|
||||||
|
|
||||||
var r0 model.ChannelList
|
var r0 model.ChannelList
|
||||||
if rf, ok := ret.Get(0).(func(string, string, string, bool) model.ChannelList); ok {
|
if rf, ok := ret.Get(0).(func(string, string, string, bool, bool) model.ChannelList); ok {
|
||||||
r0 = rf(teamID, userID, term, includeDeleted)
|
r0 = rf(teamID, userID, term, includeDeleted, isGuest)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(model.ChannelList)
|
r0 = ret.Get(0).(model.ChannelList)
|
||||||
@@ -97,8 +97,8 @@ func (_m *ChannelStore) AutocompleteInTeam(teamID string, userID string, term st
|
|||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(string, string, string, bool) error); ok {
|
if rf, ok := ret.Get(1).(func(string, string, string, bool, bool) error); ok {
|
||||||
r1 = rf(teamID, userID, term, includeDeleted)
|
r1 = rf(teamID, userID, term, includeDeleted, isGuest)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -550,10 +550,10 @@ func (s *TimerLayerChannelStore) AnalyticsTypeCount(teamID string, channelType m
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TimerLayerChannelStore) Autocomplete(userID string, term string, includeDeleted bool) (model.ChannelListWithTeamData, error) {
|
func (s *TimerLayerChannelStore) Autocomplete(userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelListWithTeamData, error) {
|
||||||
start := timemodule.Now()
|
start := timemodule.Now()
|
||||||
|
|
||||||
result, err := s.ChannelStore.Autocomplete(userID, term, includeDeleted)
|
result, err := s.ChannelStore.Autocomplete(userID, term, includeDeleted, isGuest)
|
||||||
|
|
||||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||||
if s.Root.Metrics != nil {
|
if s.Root.Metrics != nil {
|
||||||
@@ -566,10 +566,10 @@ func (s *TimerLayerChannelStore) Autocomplete(userID string, term string, includ
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TimerLayerChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool) (model.ChannelList, error) {
|
func (s *TimerLayerChannelStore) AutocompleteInTeam(teamID string, userID string, term string, includeDeleted bool, isGuest bool) (model.ChannelList, error) {
|
||||||
start := timemodule.Now()
|
start := timemodule.Now()
|
||||||
|
|
||||||
result, err := s.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted)
|
result, err := s.ChannelStore.AutocompleteInTeam(teamID, userID, term, includeDeleted, isGuest)
|
||||||
|
|
||||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||||
if s.Root.Metrics != nil {
|
if s.Root.Metrics != nil {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user