PLT-6162: Search for users not in a given team. (#5943)
Этот коммит содержится в:
коммит произвёл
Harrison Healey
родитель
da5265681d
Коммит
232a99f0c7
@@ -397,6 +397,11 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if props.NotInTeamId != "" && !app.SessionHasPermissionToTeam(c.Session, props.NotInTeamId, model.PERMISSION_VIEW_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
|
||||
return
|
||||
}
|
||||
|
||||
searchOptions := map[string]bool{}
|
||||
searchOptions[store.USER_SEARCH_OPTION_ALLOW_INACTIVE] = props.AllowInactive
|
||||
|
||||
|
||||
@@ -385,6 +385,45 @@ func TestSearchUsers(t *testing.T) {
|
||||
_, resp = Client.SearchUsers(search)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
// Test search for users not in any team
|
||||
search.TeamId = ""
|
||||
search.NotInChannelId = ""
|
||||
search.InChannelId = ""
|
||||
search.NotInTeamId = th.BasicTeam.Id
|
||||
|
||||
users, resp = Client.SearchUsers(search)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if findUserInList(th.BasicUser.Id, users) {
|
||||
t.Fatal("should not have found user")
|
||||
}
|
||||
|
||||
oddUser := th.CreateUser()
|
||||
search.Term = oddUser.Username
|
||||
|
||||
users, resp = Client.SearchUsers(search)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if !findUserInList(oddUser.Id, users) {
|
||||
t.Fatal("should have found user")
|
||||
}
|
||||
|
||||
_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, oddUser.Id, "", "", th.BasicTeam.InviteId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
users, resp = Client.SearchUsers(search)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if findUserInList(oddUser.Id, users) {
|
||||
t.Fatal("should not have found user")
|
||||
}
|
||||
|
||||
search.NotInTeamId = model.NewId()
|
||||
_, resp = Client.SearchUsers(search)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
search.Term = th.BasicUser.Username
|
||||
|
||||
emailPrivacy := utils.Cfg.PrivacySettings.ShowEmailAddress
|
||||
namePrivacy := utils.Cfg.PrivacySettings.ShowFullName
|
||||
defer func() {
|
||||
@@ -400,6 +439,7 @@ func TestSearchUsers(t *testing.T) {
|
||||
}
|
||||
|
||||
search.InChannelId = ""
|
||||
search.NotInTeamId = ""
|
||||
search.Term = th.BasicUser2.Email
|
||||
users, resp = Client.SearchUsers(search)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
16
app/user.go
16
app/user.go
@@ -1299,6 +1299,8 @@ func SearchUsers(props *model.UserSearch, searchOptions map[string]bool, asAdmin
|
||||
return SearchUsersInChannel(props.InChannelId, props.Term, searchOptions, asAdmin)
|
||||
} else if props.NotInChannelId != "" {
|
||||
return SearchUsersNotInChannel(props.TeamId, props.NotInChannelId, props.Term, searchOptions, asAdmin)
|
||||
} else if props.NotInTeamId != "" {
|
||||
return SearchUsersNotInTeam(props.NotInTeamId, props.Term, searchOptions, asAdmin)
|
||||
} else {
|
||||
return SearchUsersInTeam(props.TeamId, props.Term, searchOptions, asAdmin)
|
||||
}
|
||||
@@ -1346,6 +1348,20 @@ func SearchUsersInTeam(teamId string, term string, searchOptions map[string]bool
|
||||
}
|
||||
}
|
||||
|
||||
func SearchUsersNotInTeam(notInTeamId string, term string, searchOptions map[string]bool, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
if result := <-Srv.Store.User().SearchNotInTeam(notInTeamId, term, searchOptions); result.Err != nil {
|
||||
return nil, result.Err
|
||||
} else {
|
||||
users := result.Data.([]*model.User)
|
||||
|
||||
for _, user := range users {
|
||||
SanitizeProfile(user, asAdmin)
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
}
|
||||
|
||||
func SearchUsersWithoutTeam(term string, searchOptions map[string]bool, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
if result := <-Srv.Store.User().SearchWithoutTeam(term, searchOptions); result.Err != nil {
|
||||
return nil, result.Err
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
type UserSearch struct {
|
||||
Term string `json:"term"`
|
||||
TeamId string `json:"team_id"`
|
||||
NotInTeamId string `json:"not_in_team_id"`
|
||||
InChannelId string `json:"in_channel_id"`
|
||||
NotInChannelId string `json:"not_in_channel_id"`
|
||||
AllowInactive bool `json:"allow_inactive"`
|
||||
|
||||
@@ -1339,6 +1339,32 @@ func (us SqlUserStore) SearchWithoutTeam(term string, options map[string]bool) S
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
func (us SqlUserStore) SearchNotInTeam(notInTeamId string, term string, options map[string]bool) StoreChannel {
|
||||
storeChannel := make(StoreChannel, 1)
|
||||
|
||||
go func() {
|
||||
searchQuery := `
|
||||
SELECT
|
||||
Users.*
|
||||
FROM Users
|
||||
LEFT JOIN TeamMembers tm
|
||||
ON tm.UserId = Users.Id
|
||||
AND tm.TeamId = :NotInTeamId
|
||||
WHERE
|
||||
tm.UserId IS NULL
|
||||
SEARCH_CLAUSE
|
||||
INACTIVE_CLAUSE
|
||||
ORDER BY Users.Username ASC
|
||||
LIMIT 100`
|
||||
|
||||
storeChannel <- us.performSearch(searchQuery, term, options, map[string]interface{}{"NotInTeamId": notInTeamId})
|
||||
close(storeChannel)
|
||||
|
||||
}()
|
||||
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term string, options map[string]bool) StoreChannel {
|
||||
storeChannel := make(StoreChannel, 1)
|
||||
|
||||
|
||||
@@ -1546,6 +1546,47 @@ func TestUserStoreSearch(t *testing.T) {
|
||||
t.Fatal("should have found user")
|
||||
}
|
||||
}
|
||||
|
||||
// Search Users not in Team.
|
||||
u4 := &model.User{}
|
||||
u4.Username = "simon" + model.NewId()
|
||||
u4.Email = model.NewId()
|
||||
u4.DeleteAt = 0
|
||||
Must(store.User().Save(u4))
|
||||
|
||||
if r1 := <-store.User().SearchNotInTeam(tid, "simo", searchOptions); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
profiles := r1.Data.([]*model.User)
|
||||
found := false
|
||||
for _, profile := range profiles {
|
||||
if profile.Id == u4.Id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Fatal("should have found user")
|
||||
}
|
||||
}
|
||||
|
||||
if r1 := <-store.User().SearchNotInTeam(tid, "jimb", searchOptions); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
profiles := r1.Data.([]*model.User)
|
||||
found := false
|
||||
for _, profile := range profiles {
|
||||
if profile.Id == u1.Id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
t.Fatal("should not have found user")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserStoreSearchWithoutTeam(t *testing.T) {
|
||||
|
||||
@@ -202,6 +202,7 @@ type UserStore interface {
|
||||
GetUnreadCountForChannel(userId string, channelId string) StoreChannel
|
||||
GetRecentlyActiveUsersForTeam(teamId string) StoreChannel
|
||||
Search(teamId string, term string, options map[string]bool) StoreChannel
|
||||
SearchNotInTeam(notInTeamId string, term string, options map[string]bool) StoreChannel
|
||||
SearchInChannel(channelId string, term string, options map[string]bool) StoreChannel
|
||||
SearchNotInChannel(teamId string, channelId string, term string, options map[string]bool) StoreChannel
|
||||
SearchWithoutTeam(term string, options map[string]bool) StoreChannel
|
||||
|
||||
Ссылка в новой задаче
Block a user