Adding new "VIEW_MEMBERS" permissions restrict the scope of users visibility (#10487)
* MM-14138: Adding new "VIEW_MEMBERS" permissions restrict the scope of users visibility * Fixing gofmt * Fixing broken tests * Addressing PR review comments from Miguel de la Cruz * Removed hack * A bit nicer and cleaner code in the UserBelongsToChannels function * Adding cluster cache invalidation for user team ids * Checking in the correct order permissions to not leek existency information * Adding restrictions to TeamMembers and User status requests * Fixing tests * Fixing status endpoint permissions checks * Adding more tests * Fixing tests * More tests and making the restrictions query based only on joins * Adding more tests * Adding more tests * fixing merge problems * Reverting status changes to avoid performance issues * Adding more tests * Fixing test * i18n extract * Adding extra method for get restrictions for a team * Add the new elasticsearch functions to search users with restrictions * Add missing translation string * Rename restrictedChannelIds to restrictedToChannels * Remove ToDo * Adding the permission to the SystemAdmin role during permissions migrations
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
5b70962f71
Коммит
c8920588a0
38
api4/team.go
38
api4/team.go
@@ -295,6 +295,17 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
team, err := c.App.GetTeamMember(c.Params.TeamId, c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -315,7 +326,13 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
members, err := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage)
|
||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
members, err := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, restrictions)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -335,6 +352,17 @@ func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
members, err := c.App.GetTeamMembersForUser(c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -362,7 +390,13 @@ func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
members, err := c.App.GetTeamMembersByIds(c.Params.TeamId, userIds)
|
||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
members, err := c.App.GetTeamMembersByIds(c.Params.TeamId, userIds, restrictions)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
|
||||
178
api4/user.go
178
api4/user.go
@@ -111,7 +111,16 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// No permission check required
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
|
||||
if err != nil {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := c.App.GetUser(c.Params.UserId)
|
||||
if err != nil {
|
||||
@@ -154,14 +163,32 @@ func getUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// No permission check required
|
||||
|
||||
user, err := c.App.GetUserByUsername(c.Params.Username)
|
||||
if err != nil {
|
||||
restrictions, err2 := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err2 != nil {
|
||||
c.Err = err2
|
||||
return
|
||||
}
|
||||
if restrictions != nil {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, user.Id)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
if c.IsSystemAdmin() || c.App.Session.UserId == user.Id {
|
||||
userTermsOfService, err := c.App.GetUserTermsOfService(user.Id)
|
||||
if err != nil && err.StatusCode != http.StatusNotFound {
|
||||
@@ -196,8 +223,6 @@ func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// No permission check required, but still prevent users who can't see another user's email address from using this
|
||||
|
||||
sanitizeOptions := c.App.GetSanitizeOptions(c.IsSystemAdmin())
|
||||
if !sanitizeOptions["email"] {
|
||||
c.Err = model.NewAppError("getUserByEmail", "api.user.get_user_by_email.permissions.app_error", nil, "userId="+c.App.Session.UserId, http.StatusForbidden)
|
||||
@@ -206,10 +231,30 @@ func getUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
user, err := c.App.GetUserByEmail(c.Params.Email)
|
||||
if err != nil {
|
||||
restrictions, err2 := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err2 != nil {
|
||||
c.Err = err2
|
||||
return
|
||||
}
|
||||
if restrictions != nil {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, user.Id)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
etag := user.Etag(*c.App.Config().PrivacySettings.ShowFullName, *c.App.Config().PrivacySettings.ShowEmailAddress)
|
||||
|
||||
if c.HandleEtag(etag, "Get User", w, r) {
|
||||
@@ -227,18 +272,23 @@ func getDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
users, err := c.App.GetUsersByIds([]string{c.Params.UserId}, c.IsSystemAdmin())
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
c.Err = model.NewAppError("getProfileImage", "api.user.get_profile_image.not_found.app_error", nil, "", http.StatusNotFound)
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := c.App.GetUser(c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
user := users[0]
|
||||
img, err := c.App.GetDefaultProfileImage(user)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -256,18 +306,23 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
users, err := c.App.GetUsersByIds([]string{c.Params.UserId}, c.IsSystemAdmin())
|
||||
canSee, err := c.App.UserCanSeeOtherUser(c.App.Session.UserId, c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
c.Err = model.NewAppError("getProfileImage", "api.user.get_profile_image.not_found.app_error", nil, "", http.StatusNotFound)
|
||||
if !canSee {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := c.App.GetUser(c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
user := users[0]
|
||||
etag := strconv.FormatInt(user.LastPictureUpdate, 10)
|
||||
if c.HandleEtag(etag, "Get Profile Image", w, r) {
|
||||
return
|
||||
@@ -376,7 +431,13 @@ func getTotalUsersStats(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
stats, err := c.App.GetTotalUsersStats()
|
||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
stats, err := c.App.GetTotalUsersStats(restrictions)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -419,21 +480,27 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
withoutTeamBool, _ := strconv.ParseBool(withoutTeam)
|
||||
inactiveBool, _ := strconv.ParseBool(inactive)
|
||||
|
||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
userGetOptions := &model.UserGetOptions{
|
||||
InTeamId: inTeamId,
|
||||
InChannelId: inChannelId,
|
||||
NotInTeamId: notInTeamId,
|
||||
NotInChannelId: notInChannelId,
|
||||
WithoutTeam: withoutTeamBool,
|
||||
Inactive: inactiveBool,
|
||||
Role: role,
|
||||
Sort: sort,
|
||||
Page: c.Params.Page,
|
||||
PerPage: c.Params.PerPage,
|
||||
InTeamId: inTeamId,
|
||||
InChannelId: inChannelId,
|
||||
NotInTeamId: notInTeamId,
|
||||
NotInChannelId: notInChannelId,
|
||||
WithoutTeam: withoutTeamBool,
|
||||
Inactive: inactiveBool,
|
||||
Role: role,
|
||||
Sort: sort,
|
||||
Page: c.Params.Page,
|
||||
PerPage: c.Params.PerPage,
|
||||
ViewRestrictions: restrictions,
|
||||
}
|
||||
|
||||
var profiles []*model.User
|
||||
var err *model.AppError
|
||||
etag := ""
|
||||
|
||||
if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool {
|
||||
@@ -443,26 +510,26 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
profiles, err = c.App.GetUsersWithoutTeamPage(c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
|
||||
profiles, err = c.App.GetUsersWithoutTeamPage(c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
|
||||
} else if len(notInChannelId) > 0 {
|
||||
if !c.App.SessionHasPermissionToChannel(c.App.Session, notInChannelId, model.PERMISSION_READ_CHANNEL) {
|
||||
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
|
||||
return
|
||||
}
|
||||
|
||||
profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
|
||||
profiles, err = c.App.GetUsersNotInChannelPage(inTeamId, notInChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
|
||||
} else if len(notInTeamId) > 0 {
|
||||
if !c.App.SessionHasPermissionToTeam(c.App.Session, notInTeamId, model.PERMISSION_VIEW_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
|
||||
return
|
||||
}
|
||||
|
||||
etag = c.App.GetUsersNotInTeamEtag(inTeamId)
|
||||
etag = c.App.GetUsersNotInTeamEtag(inTeamId, restrictions.Hash())
|
||||
if c.HandleEtag(etag, "Get Users Not in Team", w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
|
||||
profiles, err = c.App.GetUsersNotInTeamPage(notInTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
|
||||
} else if len(inTeamId) > 0 {
|
||||
if !c.App.SessionHasPermissionToTeam(c.App.Session, inTeamId, model.PERMISSION_VIEW_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_VIEW_TEAM)
|
||||
@@ -470,11 +537,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if sort == "last_activity_at" {
|
||||
profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
|
||||
profiles, err = c.App.GetRecentlyActiveUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
|
||||
} else if sort == "create_at" {
|
||||
profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
|
||||
profiles, err = c.App.GetNewUsersForTeamPage(inTeamId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin(), restrictions)
|
||||
} else {
|
||||
etag = c.App.GetUsersInTeamEtag(inTeamId)
|
||||
etag = c.App.GetUsersInTeamEtag(inTeamId, restrictions.Hash())
|
||||
if c.HandleEtag(etag, "Get Users in Team", w, r) {
|
||||
return
|
||||
}
|
||||
@@ -491,12 +558,16 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
profiles, err = c.App.GetUsersInChannelPage(inChannelId, c.Params.Page, c.Params.PerPage, c.IsSystemAdmin())
|
||||
}
|
||||
} else {
|
||||
// No permission check required
|
||||
|
||||
etag = c.App.GetUsersEtag()
|
||||
etag = c.App.GetUsersEtag(restrictions.Hash())
|
||||
if c.HandleEtag(etag, "Get Users", w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
userGetOptions, err = c.App.RestrictUsersGetByPermissions(c.App.Session.UserId, userGetOptions)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin())
|
||||
}
|
||||
|
||||
@@ -520,9 +591,13 @@ func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// No permission check required
|
||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
users, err := c.App.GetUsersByIds(userIds, c.IsSystemAdmin())
|
||||
users, err := c.App.GetUsersByIds(userIds, c.IsSystemAdmin(), restrictions)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -539,9 +614,13 @@ func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// No permission check required
|
||||
restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
users, err := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin())
|
||||
users, err := c.App.GetUsersByUsernames(usernames, c.IsSystemAdmin(), restrictions)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -607,6 +686,12 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName
|
||||
}
|
||||
|
||||
options, err := c.App.RestrictUsersSearchByPermissions(c.App.Session.UserId, options)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
profiles, err := c.App.SearchUsers(props, options)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -670,6 +755,13 @@ func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
autocomplete.Users = result.InChannel
|
||||
autocomplete.OutOfChannel = result.OutOfChannel
|
||||
} else if len(teamId) > 0 {
|
||||
var err *model.AppError
|
||||
options, err = c.App.RestrictUsersSearchByPermissions(c.App.Session.UserId, options)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
result, err := c.App.AutocompleteUsersInTeam(teamId, name, options)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -678,7 +770,13 @@ func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
autocomplete.Users = result.InTeam
|
||||
} else {
|
||||
// No permission check required
|
||||
var err *model.AppError
|
||||
options, err = c.App.RestrictUsersSearchByPermissions(c.App.Session.UserId, options)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
result, err := c.App.SearchUsersInTeam("", name, options)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
|
||||
@@ -525,7 +525,7 @@ func TestGetBotUser(t *testing.T) {
|
||||
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
|
||||
|
||||
th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID)
|
||||
th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false)
|
||||
th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.TEAM_USER_ROLE_ID, false)
|
||||
|
||||
bot := &model.Bot{
|
||||
Username: GenerateTestUsername(),
|
||||
@@ -538,6 +538,7 @@ func TestGetBotUser(t *testing.T) {
|
||||
defer th.App.PermanentDeleteBot(createdBot.UserId)
|
||||
|
||||
botUser, resp := th.Client.GetUser(createdBot.UserId, "")
|
||||
CheckNoError(t, resp)
|
||||
require.Equal(t, bot.Username, botUser.Username)
|
||||
require.True(t, botUser.IsBot)
|
||||
}
|
||||
|
||||
471
api4/user_viewmembers_test.go
Обычный файл
471
api4/user_viewmembers_test.go
Обычный файл
@@ -0,0 +1,471 @@
|
||||
package api4
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestApiResctrictedViewMembers(t *testing.T) {
|
||||
th := Setup()
|
||||
defer th.TearDown()
|
||||
|
||||
// Create first account for system admin
|
||||
_, err := th.App.CreateUser(&model.User{Email: th.GenerateTestEmail(), Nickname: "test user0", Password: "test-password-0", Username: "test-user-0", Roles: model.SYSTEM_USER_ROLE_ID})
|
||||
require.Nil(t, err)
|
||||
|
||||
user1, err := th.App.CreateUser(&model.User{Email: th.GenerateTestEmail(), Nickname: "test user1", Password: "test-password-1", Username: "test-user-1", Roles: model.SYSTEM_USER_ROLE_ID})
|
||||
require.Nil(t, err)
|
||||
user2, err := th.App.CreateUser(&model.User{Email: th.GenerateTestEmail(), Nickname: "test user2", Password: "test-password-2", Username: "test-user-2", Roles: model.SYSTEM_USER_ROLE_ID})
|
||||
require.Nil(t, err)
|
||||
user3, err := th.App.CreateUser(&model.User{Email: th.GenerateTestEmail(), Nickname: "test user3", Password: "test-password-3", Username: "test-user-3", Roles: model.SYSTEM_USER_ROLE_ID})
|
||||
require.Nil(t, err)
|
||||
user4, err := th.App.CreateUser(&model.User{Email: th.GenerateTestEmail(), Nickname: "test user4", Password: "test-password-4", Username: "test-user-4", Roles: model.SYSTEM_USER_ROLE_ID})
|
||||
require.Nil(t, err)
|
||||
user5, err := th.App.CreateUser(&model.User{Email: th.GenerateTestEmail(), Nickname: "test user5", Password: "test-password-5", Username: "test-user-5", Roles: model.SYSTEM_USER_ROLE_ID})
|
||||
require.Nil(t, err)
|
||||
|
||||
team1, err := th.App.CreateTeam(&model.Team{DisplayName: "dn_" + model.NewId(), Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN})
|
||||
require.Nil(t, err)
|
||||
team2, err := th.App.CreateTeam(&model.Team{DisplayName: "dn_" + model.NewId(), Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN})
|
||||
require.Nil(t, err)
|
||||
|
||||
channel1, err := th.App.CreateChannel(&model.Channel{DisplayName: "dn_" + model.NewId(), Name: "name_" + model.NewId(), Type: model.CHANNEL_OPEN, TeamId: team1.Id, CreatorId: model.NewId()}, false)
|
||||
require.Nil(t, err)
|
||||
channel2, err := th.App.CreateChannel(&model.Channel{DisplayName: "dn_" + model.NewId(), Name: "name_" + model.NewId(), Type: model.CHANNEL_OPEN, TeamId: team1.Id, CreatorId: model.NewId()}, false)
|
||||
require.Nil(t, err)
|
||||
channel3, err := th.App.CreateChannel(&model.Channel{DisplayName: "dn_" + model.NewId(), Name: "name_" + model.NewId(), Type: model.CHANNEL_OPEN, TeamId: team2.Id, CreatorId: model.NewId()}, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
th.LinkUserToTeam(user1, team1)
|
||||
th.LinkUserToTeam(user2, team1)
|
||||
th.LinkUserToTeam(user3, team2)
|
||||
th.LinkUserToTeam(user4, team1)
|
||||
th.LinkUserToTeam(user4, team2)
|
||||
|
||||
th.AddUserToChannel(user1, channel1)
|
||||
th.AddUserToChannel(user2, channel2)
|
||||
th.AddUserToChannel(user3, channel3)
|
||||
th.AddUserToChannel(user4, channel1)
|
||||
th.AddUserToChannel(user4, channel3)
|
||||
|
||||
th.App.SetStatusOnline(user1.Id, true)
|
||||
th.App.SetStatusOnline(user2.Id, true)
|
||||
th.App.SetStatusOnline(user3.Id, true)
|
||||
th.App.SetStatusOnline(user4.Id, true)
|
||||
th.App.SetStatusOnline(user5.Id, true)
|
||||
|
||||
_, resp := th.Client.Login(user1.Username, "test-password-1")
|
||||
CheckNoError(t, resp)
|
||||
|
||||
t.Run("getUser", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
RestrictedTo string
|
||||
UserId string
|
||||
ExpectedError string
|
||||
}{
|
||||
{
|
||||
"Get visible user without restrictions",
|
||||
"",
|
||||
user5.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not existing user without restrictions",
|
||||
"",
|
||||
model.NewId(),
|
||||
"store.sql_user.missing_account.const",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to teams",
|
||||
"teams",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to teams",
|
||||
"teams",
|
||||
user2.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to teams",
|
||||
"teams",
|
||||
user5.Id,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to channels",
|
||||
"channels",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to channels",
|
||||
"channels",
|
||||
user4.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to channels",
|
||||
"channels",
|
||||
user3.Id,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
}
|
||||
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
if tc.RestrictedTo == "channels" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else if tc.RestrictedTo == "teams" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
}
|
||||
|
||||
_, resp := th.Client.GetUser(tc.UserId, "")
|
||||
require.Nil(t, err)
|
||||
if tc.ExpectedError != "" {
|
||||
CheckErrorMessage(t, resp, tc.ExpectedError)
|
||||
} else {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("getUserByUsername", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
RestrictedTo string
|
||||
Username string
|
||||
ExpectedError string
|
||||
}{
|
||||
{
|
||||
"Get visible user without restrictions",
|
||||
"",
|
||||
user5.Username,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not existing user without restrictions",
|
||||
"",
|
||||
model.NewId(),
|
||||
"store.sql_user.get_by_username.app_error",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to teams",
|
||||
"teams",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to teams",
|
||||
"teams",
|
||||
user2.Username,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to teams",
|
||||
"teams",
|
||||
user5.Username,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to channels",
|
||||
"channels",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to channels",
|
||||
"channels",
|
||||
user4.Username,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to channels",
|
||||
"channels",
|
||||
user3.Username,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
}
|
||||
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
if tc.RestrictedTo == "channels" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else if tc.RestrictedTo == "teams" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
}
|
||||
|
||||
_, resp := th.Client.GetUserByUsername(tc.Username, "")
|
||||
require.Nil(t, err)
|
||||
if tc.ExpectedError != "" {
|
||||
CheckErrorMessage(t, resp, tc.ExpectedError)
|
||||
} else {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("getUserByEmail", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
RestrictedTo string
|
||||
Email string
|
||||
ExpectedError string
|
||||
}{
|
||||
{
|
||||
"Get visible user without restrictions",
|
||||
"",
|
||||
user5.Email,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not existing user without restrictions",
|
||||
"",
|
||||
th.GenerateTestEmail(),
|
||||
"store.sql_user.missing_account.const",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to teams",
|
||||
"teams",
|
||||
th.GenerateTestEmail(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to teams",
|
||||
"teams",
|
||||
user2.Email,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to teams",
|
||||
"teams",
|
||||
user5.Email,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to channels",
|
||||
"channels",
|
||||
th.GenerateTestEmail(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to channels",
|
||||
"channels",
|
||||
user4.Email,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to channels",
|
||||
"channels",
|
||||
user3.Email,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
}
|
||||
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
if tc.RestrictedTo == "channels" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else if tc.RestrictedTo == "teams" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
}
|
||||
|
||||
_, resp := th.Client.GetUserByEmail(tc.Email, "")
|
||||
require.Nil(t, err)
|
||||
if tc.ExpectedError != "" {
|
||||
CheckErrorMessage(t, resp, tc.ExpectedError)
|
||||
} else {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("getDefaultProfileImage", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
RestrictedTo string
|
||||
UserId string
|
||||
ExpectedError string
|
||||
}{
|
||||
{
|
||||
"Get visible user without restrictions",
|
||||
"",
|
||||
user5.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not existing user without restrictions",
|
||||
"",
|
||||
model.NewId(),
|
||||
"store.sql_user.missing_account.const",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to teams",
|
||||
"teams",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to teams",
|
||||
"teams",
|
||||
user2.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to teams",
|
||||
"teams",
|
||||
user5.Id,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to channels",
|
||||
"channels",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to channels",
|
||||
"channels",
|
||||
user4.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to channels",
|
||||
"channels",
|
||||
user3.Id,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
}
|
||||
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
if tc.RestrictedTo == "channels" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else if tc.RestrictedTo == "teams" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
}
|
||||
|
||||
_, resp := th.Client.GetDefaultProfileImage(tc.UserId)
|
||||
require.Nil(t, err)
|
||||
if tc.ExpectedError != "" {
|
||||
CheckErrorMessage(t, resp, tc.ExpectedError)
|
||||
} else {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("getProfileImage", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
RestrictedTo string
|
||||
UserId string
|
||||
ExpectedError string
|
||||
}{
|
||||
{
|
||||
"Get visible user without restrictions",
|
||||
"",
|
||||
user5.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not existing user without restrictions",
|
||||
"",
|
||||
model.NewId(),
|
||||
"store.sql_user.missing_account.const",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to teams",
|
||||
"teams",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to teams",
|
||||
"teams",
|
||||
user2.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to teams",
|
||||
"teams",
|
||||
user5.Id,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get not existing user with restrictions to channels",
|
||||
"channels",
|
||||
model.NewId(),
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
{
|
||||
"Get visible user with restrictions to channels",
|
||||
"channels",
|
||||
user4.Id,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get not visible user with restrictions to channels",
|
||||
"channels",
|
||||
user3.Id,
|
||||
"api.context.permissions.app_error",
|
||||
},
|
||||
}
|
||||
defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions())
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
if tc.RestrictedTo == "channels" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else if tc.RestrictedTo == "teams" {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
} else {
|
||||
th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID)
|
||||
}
|
||||
|
||||
_, resp := th.Client.GetProfileImage(tc.UserId, "")
|
||||
require.Nil(t, err)
|
||||
if tc.ExpectedError != "" {
|
||||
CheckErrorMessage(t, resp, tc.ExpectedError)
|
||||
} else {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -150,6 +150,7 @@ func (a *App) InvalidateAllCachesSkipSend() {
|
||||
mlog.Info("Purging all caches")
|
||||
a.Srv.sessionCache.Purge()
|
||||
ClearStatusCache()
|
||||
a.Srv.Store.Team().ClearCaches()
|
||||
a.Srv.Store.Channel().ClearCaches()
|
||||
a.Srv.Store.User().ClearCaches()
|
||||
a.Srv.Store.Post().ClearCaches()
|
||||
|
||||
@@ -254,7 +254,7 @@ func (a *App) GetAnalytics(name string, teamId string) (model.AnalyticsRows, *mo
|
||||
}
|
||||
|
||||
func (a *App) GetRecentlyActiveUsersForTeam(teamId string) (map[string]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetRecentlyActiveUsersForTeam(teamId, 0, 100)
|
||||
result := <-a.Srv.Store.User().GetRecentlyActiveUsersForTeam(teamId, 0, 100, nil)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -269,9 +269,9 @@ func (a *App) GetRecentlyActiveUsersForTeam(teamId string) (map[string]*model.Us
|
||||
return userMap, nil
|
||||
}
|
||||
|
||||
func (a *App) GetRecentlyActiveUsersForTeamPage(teamId string, page, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
func (a *App) GetRecentlyActiveUsersForTeamPage(teamId string, page, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
var users []*model.User
|
||||
result := <-a.Srv.Store.User().GetRecentlyActiveUsersForTeam(teamId, page*perPage, perPage)
|
||||
result := <-a.Srv.Store.User().GetRecentlyActiveUsersForTeam(teamId, page*perPage, perPage, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -280,9 +280,9 @@ func (a *App) GetRecentlyActiveUsersForTeamPage(teamId string, page, perPage int
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetNewUsersForTeamPage(teamId string, page, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
func (a *App) GetNewUsersForTeamPage(teamId string, page, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
var users []*model.User
|
||||
result := <-a.Srv.Store.User().GetNewUsersForTeam(teamId, page*perPage, perPage)
|
||||
result := <-a.Srv.Store.User().GetNewUsersForTeam(teamId, page*perPage, perPage, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
},
|
||||
"system_post_all": []string{
|
||||
@@ -176,6 +177,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
model.PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -305,6 +307,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
},
|
||||
"system_post_all": []string{
|
||||
@@ -356,6 +359,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
model.PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -523,6 +527,7 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_CREATE_EMOJIS.Id,
|
||||
model.PERMISSION_DELETE_EMOJIS.Id,
|
||||
model.PERMISSION_DELETE_OTHERS_EMOJIS.Id,
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
}
|
||||
sort.Strings(expectedSystemAdmin)
|
||||
|
||||
@@ -583,6 +588,7 @@ func TestDoEmojisPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
model.PERMISSION_CREATE_EMOJIS.Id,
|
||||
model.PERMISSION_DELETE_EMOJIS.Id,
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
}
|
||||
sort.Strings(expected3)
|
||||
sort.Strings(role3.Permissions)
|
||||
|
||||
@@ -420,7 +420,7 @@ func (a *App) createGroupChannel(userIds []string, creatorId string) (*model.Cha
|
||||
return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
result := <-a.Srv.Store.User().GetProfileByIds(userIds, true)
|
||||
result := <-a.Srv.Store.User().GetProfileByIds(userIds, true, nil)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -469,7 +469,7 @@ func (a *App) GetGroupChannel(userIds []string) (*model.Channel, *model.AppError
|
||||
return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
result := <-a.Srv.Store.User().GetProfileByIds(userIds, true)
|
||||
result := <-a.Srv.Store.User().GetProfileByIds(userIds, true, nil)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -1907,7 +1907,7 @@ func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.
|
||||
}
|
||||
|
||||
if len(channelMemberIds) > 0 {
|
||||
teamMembers, err2 := a.GetTeamMembersByIds(team.Id, channelMemberIds)
|
||||
teamMembers, err2 := a.GetTeamMembersByIds(team.Id, channelMemberIds, nil)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ func (a *App) RegisterAllClusterMessageHandlers() {
|
||||
a.Cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_BY_NAME, a.ClusterInvalidateCacheForChannelByNameHandler)
|
||||
a.Cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL, a.ClusterInvalidateCacheForChannelHandler)
|
||||
a.Cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER, a.ClusterInvalidateCacheForUserHandler)
|
||||
a.Cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER_TEAMS, a.ClusterInvalidateCacheForUserTeamsHandler)
|
||||
a.Cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER, a.ClusterClearSessionCacheForUserHandler)
|
||||
}
|
||||
|
||||
@@ -65,6 +66,10 @@ func (a *App) ClusterInvalidateCacheForUserHandler(msg *model.ClusterMessage) {
|
||||
a.InvalidateCacheForUserSkipClusterSend(msg.Data)
|
||||
}
|
||||
|
||||
func (a *App) ClusterInvalidateCacheForUserTeamsHandler(msg *model.ClusterMessage) {
|
||||
a.InvalidateCacheForUserTeamsSkipClusterSend(msg.Data)
|
||||
}
|
||||
|
||||
func (a *App) ClusterClearSessionCacheForUserHandler(msg *model.ClusterMessage) {
|
||||
a.ClearSessionCacheForUserSkipClusterSend(msg.Data)
|
||||
}
|
||||
|
||||
@@ -802,7 +802,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
Position: ptrStr(model.NewId()),
|
||||
}
|
||||
|
||||
teamMembers, err := th.App.GetTeamMembers(team.Id, 0, 1000)
|
||||
teamMembers, err := th.App.GetTeamMembers(team.Id, 0, 1000, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get team member count")
|
||||
}
|
||||
@@ -884,7 +884,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Check no new member objects were created because dry run mode.
|
||||
tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000)
|
||||
tmc, err := th.App.GetTeamMembers(team.Id, 0, 1000, nil)
|
||||
require.Nil(t, err, "Failed to get Team Member Count")
|
||||
require.Len(t, tmc, teamMemberCount, "Number of team members not as expected")
|
||||
|
||||
@@ -935,7 +935,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
assert.NotNil(t, err)
|
||||
|
||||
// Check no new member objects were created because all tests should have failed so far.
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000)
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
|
||||
require.Nil(t, err, "Failed to get Team Member Count")
|
||||
require.Len(t, tmc, teamMemberCount)
|
||||
|
||||
@@ -958,7 +958,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
assert.NotNil(t, err)
|
||||
|
||||
// Check only new team member object created because dry run mode.
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000)
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
|
||||
require.Nil(t, err, "Failed to get Team Member Count")
|
||||
require.Len(t, tmc, teamMemberCount+1)
|
||||
|
||||
@@ -991,7 +991,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Check only new channel member object created because dry run mode.
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000)
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
|
||||
require.Nil(t, err, "Failed to get Team Member Count")
|
||||
require.Len(t, tmc, teamMemberCount+1, "Number of team members not as expected")
|
||||
|
||||
@@ -1046,7 +1046,7 @@ func TestImportImportUser(t *testing.T) {
|
||||
checkPreference(t, th.App, user.Id, model.PREFERENCE_CATEGORY_THEME, team.Id, *(*data.Teams)[0].Theme)
|
||||
|
||||
// No more new member objects.
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000)
|
||||
tmc, err = th.App.GetTeamMembers(team.Id, 0, 1000, nil)
|
||||
require.Nil(t, err, "Failed to get Team Member Count")
|
||||
require.Len(t, tmc, teamMemberCount+1, "Number of team members not as expected")
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
|
||||
}
|
||||
|
||||
if len(m.OtherPotentialMentions) > 0 && !post.IsSystemMessage() {
|
||||
if result := <-a.Srv.Store.User().GetProfilesByUsernames(m.OtherPotentialMentions, team.Id); result.Err == nil {
|
||||
if result := <-a.Srv.Store.User().GetProfilesByUsernames(m.OtherPotentialMentions, &model.ViewUsersRestrictions{Teams: []string{team.Id}}); result.Err == nil {
|
||||
channelMentions := model.UserSlice(result.Data.([]*model.User)).FilterByActive(true)
|
||||
|
||||
var outOfChannelMentions model.UserSlice
|
||||
|
||||
@@ -22,6 +22,7 @@ const (
|
||||
MIGRATION_KEY_ADD_BOT_PERMISSIONS = "add_bot_permissions"
|
||||
MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER = "apply_channel_manage_delete_to_channel_user"
|
||||
MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER = "remove_channel_manage_delete_from_team_user"
|
||||
MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION = "view_members_new_permission"
|
||||
|
||||
PERMISSION_MANAGE_SYSTEM = "manage_system"
|
||||
PERMISSION_MANAGE_EMOJIS = "manage_emojis"
|
||||
@@ -49,6 +50,7 @@ const (
|
||||
PERMISSION_DELETE_PRIVATE_CHANNEL = "delete_private_channel"
|
||||
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES = "manage_public_channel_properties"
|
||||
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES = "manage_private_channel_properties"
|
||||
PERMISSION_VIEW_MEMBERS = "view_members"
|
||||
)
|
||||
|
||||
func isRole(role string) func(string, map[string]map[string]bool) bool {
|
||||
@@ -258,6 +260,19 @@ func removeChannelManageDeleteFromTeamUser() permissionsMap {
|
||||
}
|
||||
}
|
||||
|
||||
func getViewMembersPermissionMigration() permissionsMap {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_USER_ROLE_ID),
|
||||
Add: []string{PERMISSION_VIEW_MEMBERS},
|
||||
},
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_VIEW_MEMBERS},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
||||
func (a *App) DoPermissionsMigrations() *model.AppError {
|
||||
PermissionsMigrations := []struct {
|
||||
@@ -271,6 +286,7 @@ func (a *App) DoPermissionsMigrations() *model.AppError {
|
||||
{Key: MIGRATION_KEY_ADD_BOT_PERMISSIONS, Migration: getAddBotPermissionsMigration},
|
||||
{Key: MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Migration: applyChannelManageDeleteToChannelUser},
|
||||
{Key: MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: removeChannelManageDeleteFromTeamUser},
|
||||
{Key: MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Migration: getViewMembersPermissionMigration},
|
||||
}
|
||||
|
||||
for _, migration := range PermissionsMigrations {
|
||||
|
||||
@@ -173,7 +173,7 @@ func (api *PluginAPI) DeleteTeamMember(teamId, userId, requestorId string) *mode
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetTeamMembers(teamId string, page, perPage int) ([]*model.TeamMember, *model.AppError) {
|
||||
return api.app.GetTeamMembers(teamId, page*perPage, perPage)
|
||||
return api.app.GetTeamMembers(teamId, page*perPage, perPage, nil)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) {
|
||||
@@ -222,7 +222,7 @@ func (api *PluginAPI) GetUserByUsername(name string) (*model.User, *model.AppErr
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetUsersByUsernames(usernames []string) ([]*model.User, *model.AppError) {
|
||||
return api.app.GetUsersByUsernames(usernames, true)
|
||||
return api.app.GetUsersByUsernames(usernames, true, nil)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetUsersInTeam(teamId string, page int, perPage int) ([]*model.User, *model.AppError) {
|
||||
|
||||
@@ -780,7 +780,7 @@ func (a *App) DeletePostFiles(post *model.Post) {
|
||||
func (a *App) parseAndFetchChannelIdByNameFromInFilter(channelName, userId, teamId string, includeDeleted bool) (*model.Channel, error) {
|
||||
if strings.HasPrefix(channelName, "@") && strings.Contains(channelName, ",") {
|
||||
var userIds []string
|
||||
users, err := a.GetUsersByUsernames(strings.Split(channelName[1:], ","), false)
|
||||
users, err := a.GetUsersByUsernames(strings.Split(channelName[1:], ","), false, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func replaceUserIds(userStore store.UserStore, text string) string {
|
||||
userIds = append(userIds, match[1])
|
||||
}
|
||||
|
||||
if res := <-userStore.GetProfileByIds(userIds, true); res.Err == nil {
|
||||
if res := <-userStore.GetProfileByIds(userIds, true, nil); res.Err == nil {
|
||||
for _, user := range res.Data.([]*model.User) {
|
||||
text = strings.Replace(text, "<@"+user.Id+">", "@"+user.Username, -1)
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestCreateDefaultMemberships(t *testing.T) {
|
||||
t.Errorf("error retrieving channel member: %s", err.Error())
|
||||
}
|
||||
|
||||
tMembers, err := th.App.GetTeamMembers(singersTeam.Id, 0, 999)
|
||||
tMembers, err := th.App.GetTeamMembers(singersTeam.Id, 0, 999, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error retrieving team members: %s", err.Error())
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func TestCreateDefaultMemberships(t *testing.T) {
|
||||
t.Errorf("wrong error: %s", err.Id)
|
||||
}
|
||||
|
||||
tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999)
|
||||
tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error retrieving team members: %s", err.Error())
|
||||
}
|
||||
@@ -185,7 +185,7 @@ func TestCreateDefaultMemberships(t *testing.T) {
|
||||
t.Errorf("wrong error: %s", err.Id)
|
||||
}
|
||||
|
||||
tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999)
|
||||
tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error retrieving team members: %s", err.Error())
|
||||
}
|
||||
@@ -366,7 +366,7 @@ func TestDeleteGroupMemberships(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
|
||||
// verify the member count
|
||||
tmembers, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100)
|
||||
tmembers, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100, nil)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, tmembers, 3)
|
||||
|
||||
@@ -383,7 +383,7 @@ func TestDeleteGroupMemberships(t *testing.T) {
|
||||
require.Nil(t, appErr)
|
||||
|
||||
// verify the new member counts
|
||||
tmembers, err = th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100)
|
||||
tmembers, err = th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100, nil)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, tmembers, 1)
|
||||
require.Equal(t, th.SystemAdminUser.Id, tmembers[0].UserId)
|
||||
|
||||
10
app/team.go
10
app/team.go
@@ -559,6 +559,7 @@ func (a *App) JoinUserToTeam(team *model.Team, user *model.User, userRequestorId
|
||||
|
||||
a.ClearSessionCacheForUser(user.Id)
|
||||
a.InvalidateCacheForUser(user.Id)
|
||||
a.InvalidateCacheForUserTeams(user.Id)
|
||||
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", user.Id, nil)
|
||||
message.Add("team_id", team.Id)
|
||||
@@ -693,16 +694,16 @@ func (a *App) GetTeamMembersForUserWithPagination(userId string, page, perPage i
|
||||
return result.Data.([]*model.TeamMember), nil
|
||||
}
|
||||
|
||||
func (a *App) GetTeamMembers(teamId string, offset int, limit int) ([]*model.TeamMember, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetMembers(teamId, offset, limit)
|
||||
func (a *App) GetTeamMembers(teamId string, offset int, limit int, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetMembers(teamId, offset, limit, restrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
return result.Data.([]*model.TeamMember), nil
|
||||
}
|
||||
|
||||
func (a *App) GetTeamMembersByIds(teamId string, userIds []string) ([]*model.TeamMember, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetMembersByIds(teamId, userIds)
|
||||
func (a *App) GetTeamMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().GetMembersByIds(teamId, userIds, restrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -932,6 +933,7 @@ func (a *App) LeaveTeam(team *model.Team, user *model.User, requestorId string)
|
||||
|
||||
a.ClearSessionCacheForUser(user.Id)
|
||||
a.InvalidateCacheForUser(user.Id)
|
||||
a.InvalidateCacheForUserTeams(user.Id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -756,10 +756,10 @@ func TestGetTeamMembers(t *testing.T) {
|
||||
sort.Sort(userIDs)
|
||||
|
||||
// Fetch team members multipile times
|
||||
members, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 5)
|
||||
members, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 5, nil)
|
||||
require.Nil(t, err)
|
||||
// This should return 5 members
|
||||
members2, err := th.App.GetTeamMembers(th.BasicTeam.Id, 5, 6)
|
||||
members2, err := th.App.GetTeamMembers(th.BasicTeam.Id, 5, 6, nil)
|
||||
require.Nil(t, err)
|
||||
members = append(members, members2...)
|
||||
|
||||
@@ -776,7 +776,7 @@ func TestGetTeamStats(t *testing.T) {
|
||||
teamStats, err := th.App.GetTeamStats(th.BasicTeam.Id)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, teamStats)
|
||||
members, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 5)
|
||||
members, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 5, nil)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, int64(len(members)), teamStats.TotalMemberCount)
|
||||
}
|
||||
|
||||
255
app/user.go
255
app/user.go
@@ -447,8 +447,8 @@ func (a *App) GetUsersPage(options *model.UserGetOptions, asAdmin bool) ([]*mode
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersEtag() string {
|
||||
return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForAllProfiles()).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress)
|
||||
func (a *App) GetUsersEtag(restrictionsHash string) string {
|
||||
return fmt.Sprintf("%v.%v.%v.%v", (<-a.Srv.Store.User().GetEtagForAllProfiles()).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
|
||||
}
|
||||
|
||||
func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
|
||||
@@ -459,8 +459,8 @@ func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *mod
|
||||
return result.Data.([]*model.User), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersNotInTeam(teamId string, offset int, limit int) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesNotInTeam(teamId, offset, limit)
|
||||
func (a *App) GetUsersNotInTeam(teamId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesNotInTeam(teamId, offset, limit, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -476,8 +476,8 @@ func (a *App) GetUsersInTeamPage(options *model.UserGetOptions, asAdmin bool) ([
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersNotInTeam(teamId, page*perPage, perPage)
|
||||
func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersNotInTeam(teamId, page*perPage, perPage, viewRestrictions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -485,12 +485,12 @@ func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmi
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersInTeamEtag(teamId string) string {
|
||||
return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress)
|
||||
func (a *App) GetUsersInTeamEtag(teamId string, restrictionsHash string) string {
|
||||
return fmt.Sprintf("%v.%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
|
||||
}
|
||||
|
||||
func (a *App) GetUsersNotInTeamEtag(teamId string) string {
|
||||
return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfilesNotInTeam(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress)
|
||||
func (a *App) GetUsersNotInTeamEtag(teamId string, restrictionsHash string) string {
|
||||
return fmt.Sprintf("%v.%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfilesNotInTeam(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
|
||||
}
|
||||
|
||||
func (a *App) GetUsersInChannel(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
|
||||
@@ -541,16 +541,16 @@ func (a *App) GetUsersInChannelPageByStatus(channelId string, page int, perPage
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersNotInChannel(teamId string, channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesNotInChannel(teamId, channelId, offset, limit)
|
||||
func (a *App) GetUsersNotInChannel(teamId string, channelId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesNotInChannel(teamId, channelId, offset, limit, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
return result.Data.([]*model.User), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, offset int, limit int, asAdmin bool) (map[string]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersNotInChannel(teamId, channelId, offset, limit)
|
||||
func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, offset int, limit int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) (map[string]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersNotInChannel(teamId, channelId, offset, limit, viewRestrictions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -565,8 +565,8 @@ func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, offset in
|
||||
return userMap, nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersNotInChannel(teamId, channelId, page*perPage, perPage)
|
||||
func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersNotInChannel(teamId, channelId, page*perPage, perPage, viewRestrictions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -574,8 +574,8 @@ func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, page int
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersWithoutTeam(page*perPage, perPage)
|
||||
func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
users, err := a.GetUsersWithoutTeam(page*perPage, perPage, viewRestrictions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -583,8 +583,8 @@ func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool) ([]*m
|
||||
return a.sanitizeProfiles(users, asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersWithoutTeam(offset int, limit int) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesWithoutTeam(offset, limit)
|
||||
func (a *App) GetUsersWithoutTeam(offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesWithoutTeam(offset, limit, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -609,16 +609,16 @@ func (a *App) GetChannelGroupUsers(channelID string) ([]*model.User, *model.AppE
|
||||
return result.Data.([]*model.User), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersByIds(userIds []string, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfileByIds(userIds, true)
|
||||
func (a *App) GetUsersByIds(userIds []string, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfileByIds(userIds, viewRestrictions == nil, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
return a.sanitizeProfiles(result.Data.([]*model.User), asAdmin), nil
|
||||
}
|
||||
|
||||
func (a *App) GetUsersByUsernames(usernames []string, asAdmin bool) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesByUsernames(usernames, "")
|
||||
func (a *App) GetUsersByUsernames(usernames []string, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().GetProfilesByUsernames(usernames, viewRestrictions)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
@@ -1601,9 +1601,10 @@ func (a *App) GetVerifyEmailToken(token string) (*model.Token, *model.AppError)
|
||||
}
|
||||
|
||||
// GetTotalUsersStats is used for the DM list total
|
||||
func (a *App) GetTotalUsersStats() (*model.UsersStats, *model.AppError) {
|
||||
func (a *App) GetTotalUsersStats(viewRestrictions *model.ViewUsersRestrictions) (*model.UsersStats, *model.AppError) {
|
||||
result := <-a.Srv.Store.User().Count(model.UserCountOptions{
|
||||
IncludeBotAccounts: true,
|
||||
ViewRestrictions: viewRestrictions,
|
||||
})
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
@@ -1682,12 +1683,20 @@ func (a *App) SearchUsersInTeam(teamId string, term string, options *model.UserS
|
||||
esInterface := a.Elasticsearch
|
||||
license := a.License()
|
||||
if esInterface != nil && *a.Config().ElasticsearchSettings.EnableAutocomplete && license != nil && *license.Features.Elasticsearch {
|
||||
usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, term, options)
|
||||
listOfAllowedChannels, err := a.GetViewUsersRestrictionsForTeam(a.Session.UserId, teamId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(listOfAllowedChannels) == 0 {
|
||||
return []*model.User{}, nil
|
||||
}
|
||||
|
||||
usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, listOfAllowedChannels, term, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = <-a.Srv.Store.User().GetProfileByIds(usersIds, false)
|
||||
result = <-a.Srv.Store.User().GetProfileByIds(usersIds, false, nil)
|
||||
} else {
|
||||
result = <-a.Srv.Store.User().Search(teamId, term, options)
|
||||
}
|
||||
@@ -1738,12 +1747,25 @@ func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term s
|
||||
esInterface := a.Elasticsearch
|
||||
license := a.License()
|
||||
if esInterface != nil && *a.Config().ElasticsearchSettings.EnableAutocomplete && license != nil && *license.Features.Elasticsearch {
|
||||
uchanIds, nuchanIds, err := a.Elasticsearch.SearchUsersInChannel(teamId, channelId, term, options)
|
||||
listOfAllowedChannels, err := a.getListOfAllowedChannelsForTeam(teamId, options.ViewRestrictions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uchan = a.Srv.Store.User().GetProfileByIds(uchanIds, false)
|
||||
nuchan = a.Srv.Store.User().GetProfileByIds(nuchanIds, false)
|
||||
if len(listOfAllowedChannels) == 0 {
|
||||
return &model.UserAutocompleteInChannel{}, nil
|
||||
}
|
||||
uchanIds := []string{}
|
||||
nuchanIds := []string{}
|
||||
if !strings.Contains(strings.Join(listOfAllowedChannels, "."), channelId) {
|
||||
nuchanIds, err = a.Elasticsearch.SearchUsersInTeam(teamId, listOfAllowedChannels, term, options)
|
||||
} else {
|
||||
uchanIds, nuchanIds, err = a.Elasticsearch.SearchUsersInChannel(teamId, channelId, listOfAllowedChannels, term, options)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uchan = a.Srv.Store.User().GetProfileByIds(uchanIds, false, nil)
|
||||
nuchan = a.Srv.Store.User().GetProfileByIds(nuchanIds, false, nil)
|
||||
} else {
|
||||
uchan = a.Srv.Store.User().SearchInChannel(channelId, term, options)
|
||||
nuchan = a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options)
|
||||
@@ -1785,12 +1807,20 @@ func (a *App) AutocompleteUsersInTeam(teamId string, term string, options *model
|
||||
esInterface := a.Elasticsearch
|
||||
license := a.License()
|
||||
if esInterface != nil && *a.Config().ElasticsearchSettings.EnableAutocomplete && license != nil && *license.Features.Elasticsearch {
|
||||
usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, term, options)
|
||||
listOfAllowedChannels, err := a.getListOfAllowedChannelsForTeam(teamId, options.ViewRestrictions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(listOfAllowedChannels) == 0 {
|
||||
return &model.UserAutocompleteInTeam{}, nil
|
||||
}
|
||||
|
||||
usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, listOfAllowedChannels, term, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = <-a.Srv.Store.User().GetProfileByIds(usersIds, false)
|
||||
result = <-a.Srv.Store.User().GetProfileByIds(usersIds, false, nil)
|
||||
} else {
|
||||
result = <-a.Srv.Store.User().Search(teamId, term, options)
|
||||
}
|
||||
@@ -1865,6 +1895,16 @@ func (a *App) UpdateOAuthUserAttrs(userData io.Reader, user *model.User, provide
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) RestrictUsersGetByPermissions(userId string, options *model.UserGetOptions) (*model.UserGetOptions, *model.AppError) {
|
||||
restrictions, err := a.GetViewUsersRestrictions(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
options.ViewRestrictions = restrictions
|
||||
return options, nil
|
||||
}
|
||||
|
||||
// FilterNonGroupTeamMembers returns the subset of the given user IDs of the users who are not members of groups
|
||||
// associated to the team.
|
||||
func (a *App) FilterNonGroupTeamMembers(userIDs []string, team *model.Team) ([]string, error) {
|
||||
@@ -1930,3 +1970,154 @@ func (a *App) FilterNonGroupChannelMembers(userIDs []string, channel *model.Chan
|
||||
|
||||
return nonMemberIDs, nil
|
||||
}
|
||||
|
||||
func (a *App) RestrictUsersSearchByPermissions(userId string, options *model.UserSearchOptions) (*model.UserSearchOptions, *model.AppError) {
|
||||
restrictions, err := a.GetViewUsersRestrictions(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
options.ViewRestrictions = restrictions
|
||||
return options, nil
|
||||
}
|
||||
|
||||
func (a *App) UserCanSeeOtherUser(userId string, otherUserId string) (bool, *model.AppError) {
|
||||
if userId == otherUserId {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
restrictions, err := a.GetViewUsersRestrictions(userId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if restrictions == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if len(restrictions.Teams) > 0 {
|
||||
result, err := a.userBelongsToTeams(otherUserId, restrictions.Teams)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if result {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(restrictions.Channels) > 0 {
|
||||
result, err := a.userBelongsToChannels(otherUserId, restrictions.Channels)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if result {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (a *App) userBelongsToTeams(userId string, teamIds []string) (bool, *model.AppError) {
|
||||
result := <-a.Srv.Store.Team().UserBelongsToTeams(userId, teamIds)
|
||||
if result.Err != nil {
|
||||
return false, result.Err
|
||||
}
|
||||
return result.Data.(bool), nil
|
||||
}
|
||||
|
||||
func (a *App) userBelongsToChannels(userId string, channelIds []string) (bool, *model.AppError) {
|
||||
result := <-a.Srv.Store.Channel().UserBelongsToChannels(userId, channelIds)
|
||||
if result.Err != nil {
|
||||
return false, result.Err
|
||||
}
|
||||
return result.Data.(bool), nil
|
||||
}
|
||||
|
||||
func (a *App) GetViewUsersRestrictions(userId string) (*model.ViewUsersRestrictions, *model.AppError) {
|
||||
if a.HasPermissionTo(userId, model.PERMISSION_VIEW_MEMBERS) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
result := <-a.Srv.Store.Team().GetUserTeamIds(userId, true)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
teamIds := result.Data.([]string)
|
||||
|
||||
teamIdsWithPermission := []string{}
|
||||
teamIdsWithoutPermission := []string{}
|
||||
for _, teamId := range teamIds {
|
||||
if a.HasPermissionToTeam(userId, teamId, model.PERMISSION_VIEW_MEMBERS) {
|
||||
teamIdsWithPermission = append(teamIdsWithPermission, teamId)
|
||||
} else {
|
||||
teamIdsWithoutPermission = append(teamIdsWithoutPermission, teamId)
|
||||
}
|
||||
}
|
||||
|
||||
if len(teamIdsWithoutPermission) == 0 {
|
||||
return &model.ViewUsersRestrictions{Teams: teamIdsWithPermission}, nil
|
||||
}
|
||||
|
||||
userChannelMembers := <-a.Srv.Store.Channel().GetAllChannelMembersForUser(userId, true, true)
|
||||
if userChannelMembers.Err != nil {
|
||||
return nil, userChannelMembers.Err
|
||||
}
|
||||
|
||||
channelIds := []string{}
|
||||
for channelId := range userChannelMembers.Data.(map[string]string) {
|
||||
channelIds = append(channelIds, channelId)
|
||||
}
|
||||
|
||||
return &model.ViewUsersRestrictions{Teams: teamIdsWithPermission, Channels: channelIds}, nil
|
||||
}
|
||||
|
||||
func (a *App) GetViewUsersRestrictionsForTeam(userId string, teamId string) ([]string, *model.AppError) {
|
||||
if a.HasPermissionTo(userId, model.PERMISSION_VIEW_MEMBERS) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if a.HasPermissionToTeam(userId, teamId, model.PERMISSION_VIEW_MEMBERS) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
result := <-a.Srv.Store.Channel().GetMembersForUser(teamId, userId)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
|
||||
channelIds := []string{}
|
||||
for _, membership := range *result.Data.(*model.ChannelMembers) {
|
||||
channelIds = append(channelIds, membership.ChannelId)
|
||||
}
|
||||
|
||||
return channelIds, nil
|
||||
}
|
||||
|
||||
func (a *App) getListOfAllowedChannelsForTeam(teamId string, viewRestrictions *model.ViewUsersRestrictions) ([]string, *model.AppError) {
|
||||
var listOfAllowedChannels []string
|
||||
if viewRestrictions == nil || strings.Contains(strings.Join(viewRestrictions.Teams, "."), teamId) {
|
||||
result := <-a.Srv.Store.Channel().GetTeamChannels(teamId)
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
channelIds := []string{}
|
||||
for _, channel := range *result.Data.(*model.ChannelList) {
|
||||
channelIds = append(channelIds, channel.Id)
|
||||
}
|
||||
|
||||
return channelIds, nil
|
||||
}
|
||||
|
||||
cresult := <-a.Srv.Store.Channel().GetChannelsByIds(viewRestrictions.Channels)
|
||||
if cresult.Err != nil {
|
||||
return nil, cresult.Err
|
||||
}
|
||||
for _, c := range cresult.Data.([]*model.Channel) {
|
||||
if c.TeamId == teamId {
|
||||
listOfAllowedChannels = append(listOfAllowedChannels, c.Id)
|
||||
}
|
||||
}
|
||||
|
||||
return listOfAllowedChannels, nil
|
||||
}
|
||||
|
||||
203
app/user_test.go
203
app/user_test.go
@@ -704,3 +704,206 @@ func TestPasswordRecovery(t *testing.T) {
|
||||
err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh")
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestGetViewUsersRestrictions(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
team1 := th.CreateTeam()
|
||||
team2 := th.CreateTeam()
|
||||
th.CreateTeam() // Another team
|
||||
|
||||
user1 := th.CreateUser()
|
||||
|
||||
th.LinkUserToTeam(user1, team1)
|
||||
th.LinkUserToTeam(user1, team2)
|
||||
|
||||
th.App.UpdateTeamMemberRoles(team1.Id, user1.Id, "team_user team_admin")
|
||||
|
||||
team1channel1 := th.CreateChannel(team1)
|
||||
team1channel2 := th.CreateChannel(team1)
|
||||
th.CreateChannel(team1) // Another channel
|
||||
team1offtopic, err := th.App.GetChannelByName("off-topic", team1.Id, false)
|
||||
require.Nil(t, err)
|
||||
team1townsquare, err := th.App.GetChannelByName("town-square", team1.Id, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
team2channel1 := th.CreateChannel(team2)
|
||||
th.CreateChannel(team2) // Another channel
|
||||
team2offtopic, err := th.App.GetChannelByName("off-topic", team2.Id, false)
|
||||
require.Nil(t, err)
|
||||
team2townsquare, err := th.App.GetChannelByName("town-square", team2.Id, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
th.App.AddUserToChannel(user1, team1channel1)
|
||||
th.App.AddUserToChannel(user1, team1channel2)
|
||||
th.App.AddUserToChannel(user1, team2channel1)
|
||||
|
||||
addPermission := func(role *model.Role, permission string) *model.AppError {
|
||||
newPermissions := append(role.Permissions, permission)
|
||||
_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
|
||||
return err
|
||||
}
|
||||
|
||||
removePermission := func(role *model.Role, permission string) *model.AppError {
|
||||
newPermissions := []string{}
|
||||
for _, oldPermission := range role.Permissions {
|
||||
if permission != oldPermission {
|
||||
newPermissions = append(newPermissions, oldPermission)
|
||||
}
|
||||
}
|
||||
_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
|
||||
return err
|
||||
}
|
||||
|
||||
t.Run("VIEW_MEMBERS permission granted at system level", func(t *testing.T) {
|
||||
restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Nil(t, restrictions)
|
||||
})
|
||||
|
||||
t.Run("VIEW_MEMBERS permission granted at team level", func(t *testing.T) {
|
||||
systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
teamUserRole, err := th.App.GetRoleByName(model.TEAM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
require.Nil(t, addPermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer removePermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
|
||||
restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.NotNil(t, restrictions)
|
||||
assert.NotNil(t, restrictions.Teams)
|
||||
assert.Len(t, restrictions.Channels, 0)
|
||||
assert.ElementsMatch(t, []string{team1.Id, team2.Id}, restrictions.Teams)
|
||||
})
|
||||
|
||||
t.Run("VIEW_MEMBERS permission not granted at any level", func(t *testing.T) {
|
||||
systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
|
||||
restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.NotNil(t, restrictions)
|
||||
assert.Len(t, restrictions.Teams, 0)
|
||||
assert.NotNil(t, restrictions.Channels)
|
||||
assert.ElementsMatch(t, []string{team1townsquare.Id, team1offtopic.Id, team1channel1.Id, team1channel2.Id, team2townsquare.Id, team2offtopic.Id, team2channel1.Id}, restrictions.Channels)
|
||||
})
|
||||
|
||||
t.Run("VIEW_MEMBERS permission for some teams but not for others", func(t *testing.T) {
|
||||
systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
teamAdminRole, err := th.App.GetRoleByName(model.TEAM_ADMIN_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
require.Nil(t, addPermission(teamAdminRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer removePermission(teamAdminRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
|
||||
restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.NotNil(t, restrictions)
|
||||
assert.NotNil(t, restrictions.Teams)
|
||||
assert.NotNil(t, restrictions.Channels)
|
||||
assert.ElementsMatch(t, restrictions.Teams, []string{team1.Id})
|
||||
assert.ElementsMatch(t, []string{team1townsquare.Id, team1offtopic.Id, team1channel1.Id, team1channel2.Id, team2townsquare.Id, team2offtopic.Id, team2channel1.Id}, restrictions.Channels)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetViewUsersRestrictionsForTeam(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
team1 := th.CreateTeam()
|
||||
team2 := th.CreateTeam()
|
||||
th.CreateTeam() // Another team
|
||||
|
||||
user1 := th.CreateUser()
|
||||
|
||||
th.LinkUserToTeam(user1, team1)
|
||||
th.LinkUserToTeam(user1, team2)
|
||||
|
||||
th.App.UpdateTeamMemberRoles(team1.Id, user1.Id, "team_user team_admin")
|
||||
|
||||
team1channel1 := th.CreateChannel(team1)
|
||||
team1channel2 := th.CreateChannel(team1)
|
||||
th.CreateChannel(team1) // Another channel
|
||||
team1offtopic, err := th.App.GetChannelByName("off-topic", team1.Id, false)
|
||||
require.Nil(t, err)
|
||||
team1townsquare, err := th.App.GetChannelByName("town-square", team1.Id, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
team2channel1 := th.CreateChannel(team2)
|
||||
th.CreateChannel(team2) // Another channel
|
||||
team2offtopic, err := th.App.GetChannelByName("off-topic", team2.Id, false)
|
||||
require.Nil(t, err)
|
||||
team2townsquare, err := th.App.GetChannelByName("town-square", team2.Id, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
th.App.AddUserToChannel(user1, team1channel1)
|
||||
th.App.AddUserToChannel(user1, team1channel2)
|
||||
th.App.AddUserToChannel(user1, team2channel1)
|
||||
|
||||
addPermission := func(role *model.Role, permission string) *model.AppError {
|
||||
newPermissions := append(role.Permissions, permission)
|
||||
_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
|
||||
return err
|
||||
}
|
||||
|
||||
removePermission := func(role *model.Role, permission string) *model.AppError {
|
||||
newPermissions := []string{}
|
||||
for _, oldPermission := range role.Permissions {
|
||||
if permission != oldPermission {
|
||||
newPermissions = append(newPermissions, oldPermission)
|
||||
}
|
||||
}
|
||||
_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
|
||||
return err
|
||||
}
|
||||
|
||||
t.Run("VIEW_MEMBERS permission granted at system level", func(t *testing.T) {
|
||||
restrictions, err := th.App.GetViewUsersRestrictionsForTeam(user1.Id, team1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Nil(t, restrictions)
|
||||
})
|
||||
|
||||
t.Run("VIEW_MEMBERS permission granted at team level", func(t *testing.T) {
|
||||
systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
teamUserRole, err := th.App.GetRoleByName(model.TEAM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
require.Nil(t, addPermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer removePermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
|
||||
restrictions, err := th.App.GetViewUsersRestrictionsForTeam(user1.Id, team1.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Nil(t, restrictions)
|
||||
})
|
||||
|
||||
t.Run("VIEW_MEMBERS permission not granted at any level", func(t *testing.T) {
|
||||
systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
|
||||
defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
|
||||
|
||||
restrictions, err := th.App.GetViewUsersRestrictionsForTeam(user1.Id, team1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.NotNil(t, restrictions)
|
||||
assert.ElementsMatch(t, []string{team1townsquare.Id, team1offtopic.Id, team1channel1.Id, team1channel2.Id, team2townsquare.Id, team2offtopic.Id, team2channel1.Id}, restrictions)
|
||||
})
|
||||
}
|
||||
|
||||
1088
app/user_viewmembers_test.go
Обычный файл
1088
app/user_viewmembers_test.go
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -303,6 +303,19 @@ func (a *App) InvalidateCacheForUser(userId string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) InvalidateCacheForUserTeams(userId string) {
|
||||
a.InvalidateCacheForUserTeamsSkipClusterSend(userId)
|
||||
|
||||
if a.Cluster != nil {
|
||||
msg := &model.ClusterMessage{
|
||||
Event: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER_TEAMS,
|
||||
SendType: model.CLUSTER_SEND_BEST_EFFORT,
|
||||
Data: userId,
|
||||
}
|
||||
a.Cluster.SendClusterMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) InvalidateCacheForUserSkipClusterSend(userId string) {
|
||||
a.Srv.Store.Channel().InvalidateAllChannelMembersForUser(userId)
|
||||
a.Srv.Store.User().InvalidateProfilesInChannelCacheByUser(userId)
|
||||
@@ -314,6 +327,15 @@ func (a *App) InvalidateCacheForUserSkipClusterSend(userId string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) InvalidateCacheForUserTeamsSkipClusterSend(userId string) {
|
||||
a.Srv.Store.Team().InvalidateAllTeamIdsForUser(userId)
|
||||
|
||||
hub := a.GetHubForUserId(userId)
|
||||
if hub != nil {
|
||||
hub.InvalidateUser(userId)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) InvalidateCacheForWebhook(webhookId string) {
|
||||
a.InvalidateCacheForWebhookSkipClusterSend(webhookId)
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ type ElasticsearchInterface interface {
|
||||
SearchChannels(teamId, term string) ([]string, *model.AppError)
|
||||
DeleteChannel(channel *model.Channel) *model.AppError
|
||||
IndexUser(user *model.User, teamsIds, channelsIds []string) *model.AppError
|
||||
SearchUsersInChannel(teamId, channelId, term string, options *model.UserSearchOptions) ([]string, []string, *model.AppError)
|
||||
SearchUsersInTeam(teamId, term string, options *model.UserSearchOptions) ([]string, *model.AppError)
|
||||
SearchUsersInChannel(teamId, channelId string, restrictedToChannels []string, term string, options *model.UserSearchOptions) ([]string, []string, *model.AppError)
|
||||
SearchUsersInTeam(teamId string, restrictedToChannels []string, term string, options *model.UserSearchOptions) ([]string, *model.AppError)
|
||||
DeleteUser(user *model.User) *model.AppError
|
||||
TestConfig(cfg *model.Config) *model.AppError
|
||||
PurgeIndexes() *model.AppError
|
||||
|
||||
16
i18n/en.json
16
i18n/en.json
@@ -2298,10 +2298,6 @@
|
||||
"id": "api.user.get_authorization_code.unsupported.app_error",
|
||||
"translation": "Unsupported OAuth service provider"
|
||||
},
|
||||
{
|
||||
"id": "api.user.get_profile_image.not_found.app_error",
|
||||
"translation": "Unable to get profile image, user not found."
|
||||
},
|
||||
{
|
||||
"id": "api.user.get_user_by_email.permissions.app_error",
|
||||
"translation": "Unable to get user by email."
|
||||
@@ -5586,6 +5582,10 @@
|
||||
"id": "store.sql_channel.update_member.app_error",
|
||||
"translation": "We encountered an error updating the channel member"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_channel.user_belongs_to_channels.app_error",
|
||||
"translation": "Unable to determine if the user belongs to a list of channels"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_channel_member_history.get_users_in_channel_during.app_error",
|
||||
"translation": "Failed to get users in channel during specified time period"
|
||||
@@ -6450,6 +6450,10 @@
|
||||
"id": "store.sql_team.get_unread.app_error",
|
||||
"translation": "Unable to get the teams unread messages"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.get_user_team_ids.app_error",
|
||||
"translation": "Unable to get the list of teams of a user"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.migrate_team_members.commit_transaction.app_error",
|
||||
"translation": "Failed to commit the database transaction"
|
||||
@@ -6534,6 +6538,10 @@
|
||||
"id": "store.sql_team.update_last_team_icon_update.app_error",
|
||||
"translation": "Unable to update the date of the last team icon update"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_team.user_belongs_to_teams.app_error",
|
||||
"translation": "Unable to determine if the user belongs to a list of teams"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_terms_of_service.save.app_error",
|
||||
"translation": "Unable to save terms of service."
|
||||
|
||||
@@ -20,6 +20,7 @@ const (
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_BY_NAME = "inv_channel_name"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL = "inv_channel"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER = "inv_user"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER_TEAMS = "inv_user_teams"
|
||||
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER = "clear_session_user"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES = "inv_roles"
|
||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES = "inv_schemes"
|
||||
|
||||
@@ -85,6 +85,7 @@ var PERMISSION_READ_BOTS *Permission
|
||||
var PERMISSION_READ_OTHERS_BOTS *Permission
|
||||
var PERMISSION_MANAGE_BOTS *Permission
|
||||
var PERMISSION_MANAGE_OTHERS_BOTS *Permission
|
||||
var PERMISSION_VIEW_MEMBERS *Permission
|
||||
|
||||
// General permission that encompasses all system admin functions
|
||||
// in the future this could be broken up to allow access to some
|
||||
@@ -519,6 +520,12 @@ func initializePermissions() {
|
||||
"authentication.permisssions.manage_jobs.description",
|
||||
PERMISSION_SCOPE_SYSTEM,
|
||||
}
|
||||
PERMISSION_VIEW_MEMBERS = &Permission{
|
||||
"view_members",
|
||||
"authentication.permisssions.view_members.name",
|
||||
"authentication.permisssions.view_members.description",
|
||||
PERMISSION_SCOPE_TEAM,
|
||||
}
|
||||
|
||||
ALL_PERMISSIONS = []*Permission{
|
||||
PERMISSION_INVITE_USER,
|
||||
@@ -591,6 +598,7 @@ func initializePermissions() {
|
||||
PERMISSION_MANAGE_BOTS,
|
||||
PERMISSION_MANAGE_OTHERS_BOTS,
|
||||
PERMISSION_MANAGE_SYSTEM,
|
||||
PERMISSION_VIEW_MEMBERS,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
PERMISSION_CREATE_GROUP_CHANNEL.Id,
|
||||
PERMISSION_VIEW_MEMBERS.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
@@ -357,6 +358,7 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
|
||||
PERMISSION_LIST_PRIVATE_TEAMS.Id,
|
||||
PERMISSION_JOIN_PRIVATE_TEAMS.Id,
|
||||
PERMISSION_VIEW_MEMBERS.Id,
|
||||
},
|
||||
roles[TEAM_USER_ROLE_ID].Permissions...,
|
||||
),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -118,6 +119,22 @@ type UserForIndexing struct {
|
||||
ChannelsIds []string `json:"channel_id"`
|
||||
}
|
||||
|
||||
type ViewUsersRestrictions struct {
|
||||
Teams []string
|
||||
Channels []string
|
||||
}
|
||||
|
||||
func (r *ViewUsersRestrictions) Hash() string {
|
||||
if r == nil {
|
||||
return ""
|
||||
}
|
||||
ids := append(r.Teams, r.Channels...)
|
||||
sort.Strings(ids)
|
||||
hash := sha256.New()
|
||||
hash.Write([]byte(strings.Join(ids, "")))
|
||||
return fmt.Sprintf("%x", hash.Sum(nil))
|
||||
}
|
||||
|
||||
type UserSlice []*User
|
||||
|
||||
func (u UserSlice) Usernames() []string {
|
||||
|
||||
@@ -13,4 +13,6 @@ type UserCountOptions struct {
|
||||
ExcludeRegularUsers bool
|
||||
// Only include users on a specific team. "" for any team.
|
||||
TeamId string
|
||||
// Restrict to search in a list of teams and channels
|
||||
ViewRestrictions *ViewUsersRestrictions
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ type UserGetOptions struct {
|
||||
Role string
|
||||
// Sorting option
|
||||
Sort string
|
||||
// Restrict to search in a list of teams and channels
|
||||
ViewRestrictions *ViewUsersRestrictions
|
||||
// Page
|
||||
Page int
|
||||
// Page size
|
||||
|
||||
@@ -57,4 +57,6 @@ type UserSearchOptions struct {
|
||||
Limit int
|
||||
// Filters for the given role
|
||||
Role string
|
||||
// Restrict to search in a list of teams and channels
|
||||
ViewRestrictions *ViewUsersRestrictions
|
||||
}
|
||||
|
||||
@@ -2604,3 +2604,27 @@ func (s SqlChannelStore) GetChannelsBatchForIndexing(startTime, endTime int64, l
|
||||
result.Data = channels
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) UserBelongsToChannels(userId string, channelIds []string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("Count(*)").
|
||||
From("ChannelMembers").
|
||||
Where(sq.And{
|
||||
sq.Eq{"UserId": userId},
|
||||
sq.Eq{"ChannelId": channelIds},
|
||||
})
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlChannelStore.UserBelongsToChannels", "store.sql_channel.user_belongs_to_channels.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
c, err := s.GetReplica().SelectInt(queryString, args...)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlChannelStore.UserBelongsToChannels", "store.sql_channel.user_belongs_to_channels.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
result.Data = c > 0
|
||||
})
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ func NewSqlSupplier(settings model.SqlSettings, metrics einterfaces.MetricsInter
|
||||
|
||||
supplier.initConnection()
|
||||
|
||||
supplier.oldStores.team = NewSqlTeamStore(supplier)
|
||||
supplier.oldStores.team = NewSqlTeamStore(supplier, metrics)
|
||||
supplier.oldStores.channel = NewSqlChannelStore(supplier, metrics)
|
||||
supplier.oldStores.post = NewSqlPostStore(supplier, metrics)
|
||||
supplier.oldStores.user = NewSqlUserStore(supplier, metrics)
|
||||
|
||||
@@ -5,21 +5,28 @@ package sqlstore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/gorp"
|
||||
"github.com/mattermost/mattermost-server/einterfaces"
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/store"
|
||||
"github.com/mattermost/mattermost-server/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
TEAM_MEMBER_EXISTS_ERROR = "store.sql_team.save_member.exists.app_error"
|
||||
TEAM_MEMBER_EXISTS_ERROR = "store.sql_team.save_member.exists.app_error"
|
||||
ALL_TEAM_IDS_FOR_USER_CACHE_SIZE = model.SESSION_CACHE_SIZE
|
||||
ALL_TEAM_IDS_FOR_USER_CACHE_SEC = 1800 // 30 mins
|
||||
)
|
||||
|
||||
type SqlTeamStore struct {
|
||||
SqlStore
|
||||
metrics einterfaces.MetricsInterface
|
||||
}
|
||||
|
||||
type teamMember struct {
|
||||
@@ -132,8 +139,11 @@ func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember {
|
||||
return tms
|
||||
}
|
||||
|
||||
func NewSqlTeamStore(sqlStore SqlStore) store.TeamStore {
|
||||
s := &SqlTeamStore{sqlStore}
|
||||
func NewSqlTeamStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.TeamStore {
|
||||
s := &SqlTeamStore{
|
||||
sqlStore,
|
||||
metrics,
|
||||
}
|
||||
|
||||
for _, db := range sqlStore.GetAllConns() {
|
||||
table := db.AddTableWithName(model.Team{}, "Teams").SetKeys(false, "Id")
|
||||
@@ -224,6 +234,11 @@ func (s SqlTeamStore) Update(team *model.Team) (*model.Team, *model.AppError) {
|
||||
return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.app_error", nil, "id="+team.Id, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
if oldTeam.DeleteAt == 0 && team.DeleteAt != 0 {
|
||||
// Invalidate this cache after any team deletion
|
||||
allTeamIdsForUserCache.Purge()
|
||||
}
|
||||
|
||||
return team, nil
|
||||
}
|
||||
|
||||
@@ -461,21 +476,21 @@ func (s SqlTeamStore) AnalyticsTeamCount() store.StoreChannel {
|
||||
})
|
||||
}
|
||||
|
||||
var TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY = `
|
||||
SELECT
|
||||
TeamMembers.*,
|
||||
TeamScheme.DefaultTeamUserRole TeamSchemeDefaultUserRole,
|
||||
TeamScheme.DefaultTeamAdminRole TeamSchemeDefaultAdminRole
|
||||
FROM
|
||||
TeamMembers
|
||||
LEFT JOIN
|
||||
Teams ON TeamMembers.TeamId = Teams.Id
|
||||
LEFT JOIN
|
||||
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
|
||||
`
|
||||
func (s SqlTeamStore) getTeamMembersWithSchemeSelectQuery() sq.SelectBuilder {
|
||||
return s.getQueryBuilder().
|
||||
Select(
|
||||
"TeamMembers.*",
|
||||
"TeamScheme.DefaultTeamUserRole TeamSchemeDefaultUserRole",
|
||||
"TeamScheme.DefaultTeamAdminRole TeamSchemeDefaultAdminRole",
|
||||
).
|
||||
From("TeamMembers").
|
||||
LeftJoin("Teams ON TeamMembers.TeamId = Teams.Id").
|
||||
LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id")
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
defer s.InvalidateAllTeamIdsForUser(member.UserId)
|
||||
if result.Err = member.IsValid(); result.Err != nil {
|
||||
return
|
||||
}
|
||||
@@ -517,8 +532,18 @@ func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int)
|
||||
return
|
||||
}
|
||||
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.TeamId": dbMember.TeamId}).
|
||||
Where(sq.Eq{"TeamMembers.UserId": dbMember.UserId})
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var retrievedMember teamMemberWithSchemeRoles
|
||||
if err := s.GetMaster().SelectOne(&retrievedMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": dbMember.TeamId, "UserId": dbMember.UserId}); err != nil {
|
||||
if err := s.GetMaster().SelectOne(&retrievedMember, queryString, args...); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.missing.app_error", nil, "team_id="+dbMember.TeamId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusNotFound)
|
||||
return
|
||||
@@ -543,8 +568,18 @@ func (s SqlTeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel
|
||||
return
|
||||
}
|
||||
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.TeamId": member.TeamId}).
|
||||
Where(sq.Eq{"TeamMembers.UserId": member.UserId})
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var retrievedMember teamMemberWithSchemeRoles
|
||||
if err := s.GetMaster().SelectOne(&retrievedMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": member.TeamId, "UserId": member.UserId}); err != nil {
|
||||
if err := s.GetMaster().SelectOne(&retrievedMember, queryString, args...); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.missing.app_error", nil, "team_id="+member.TeamId+"user_id="+member.UserId+","+err.Error(), http.StatusNotFound)
|
||||
return
|
||||
@@ -559,8 +594,18 @@ func (s SqlTeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel
|
||||
|
||||
func (s SqlTeamStore) GetMember(teamId string, userId string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.TeamId": teamId}).
|
||||
Where(sq.Eq{"TeamMembers.UserId": userId})
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var dbMember teamMemberWithSchemeRoles
|
||||
err := s.GetReplica().SelectOne(&dbMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
err = s.GetReplica().SelectOne(&dbMember, queryString, args...)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound)
|
||||
@@ -573,10 +618,24 @@ func (s SqlTeamStore) GetMember(teamId string, userId string) store.StoreChannel
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int) store.StoreChannel {
|
||||
func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int, restrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.TeamId": teamId}).
|
||||
Where(sq.Eq{"TeamMembers.DeleteAt": 0}).
|
||||
Limit(uint64(limit)).
|
||||
Offset(uint64(offset))
|
||||
|
||||
query = applyTeamMemberViewRestrictionsFilter(query, teamId, restrictions)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var dbMembers teamMemberWithSchemeRolesList
|
||||
_, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"TeamId": teamId, "Limit": limit, "Offset": offset})
|
||||
_, err = s.GetReplica().Select(&dbMembers, queryString, args...)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -629,24 +688,27 @@ func (s SqlTeamStore) GetActiveMemberCount(teamId string) store.StoreChannel {
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string) store.StoreChannel {
|
||||
func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
var dbMembers teamMemberWithSchemeRolesList
|
||||
props := make(map[string]interface{})
|
||||
idQuery := ""
|
||||
|
||||
for index, userId := range userIds {
|
||||
if len(idQuery) > 0 {
|
||||
idQuery += ", "
|
||||
}
|
||||
|
||||
props["userId"+strconv.Itoa(index)] = userId
|
||||
idQuery += ":userId" + strconv.Itoa(index)
|
||||
if len(userIds) == 0 {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "Invalid list of user ids", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
props["TeamId"] = teamId
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.TeamId": teamId}).
|
||||
Where(sq.Eq{"TeamMembers.UserId": userIds}).
|
||||
Where(sq.Eq{"TeamMembers.DeleteAt": 0})
|
||||
|
||||
if _, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId IN ("+idQuery+") AND TeamMembers.DeleteAt = 0", props); err != nil {
|
||||
query = applyTeamMemberViewRestrictionsFilter(query, teamId, restrictions)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var dbMembers teamMemberWithSchemeRolesList
|
||||
if _, err := s.GetReplica().Select(&dbMembers, queryString, args...); err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -656,8 +718,17 @@ func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string) store.Sto
|
||||
|
||||
func (s SqlTeamStore) GetTeamsForUser(userId string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.UserId": userId})
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var dbMembers teamMemberWithSchemeRolesList
|
||||
_, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.UserId = :UserId", map[string]interface{}{"UserId": userId})
|
||||
_, err = s.GetReplica().Select(&dbMembers, queryString, args...)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -669,9 +740,19 @@ func (s SqlTeamStore) GetTeamsForUser(userId string) store.StoreChannel {
|
||||
|
||||
func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage int) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||
Where(sq.Eq{"TeamMembers.UserId": userId}).
|
||||
Limit(uint64(perPage)).
|
||||
Offset(uint64(page * perPage))
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var dbMembers teamMemberWithSchemeRolesList
|
||||
offset := page * perPage
|
||||
_, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.UserId = :UserId Limit :Limit Offset :Offset", map[string]interface{}{"UserId": userId, "Limit": perPage, "Offset": offset})
|
||||
_, err = s.GetReplica().Select(&dbMembers, queryString, args...)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -731,7 +812,7 @@ func (s SqlTeamStore) RemoveMember(teamId string, userId string) store.StoreChan
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
_, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId AND UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
|
||||
result.Err = model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -740,7 +821,7 @@ func (s SqlTeamStore) RemoveAllMembersByTeam(teamId string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
_, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId})
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError)
|
||||
result.Err = model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -749,7 +830,7 @@ func (s SqlTeamStore) RemoveAllMembersByUser(userId string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
_, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
|
||||
result.Err = model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -849,6 +930,22 @@ func (s SqlTeamStore) ResetAllTeamSchemes() store.StoreChannel {
|
||||
})
|
||||
}
|
||||
|
||||
var allTeamIdsForUserCache = utils.NewLru(ALL_TEAM_IDS_FOR_USER_CACHE_SIZE)
|
||||
|
||||
func (s SqlTeamStore) ClearCaches() {
|
||||
allTeamIdsForUserCache.Purge()
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheInvalidationCounter("All Team Ids for User - Purge")
|
||||
}
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) InvalidateAllTeamIdsForUser(userId string) {
|
||||
allTeamIdsForUserCache.Remove(userId)
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheInvalidationCounter("All Team Ids for User - Remove by UserId")
|
||||
}
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) ClearAllCustomRoleAssignments() store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
builtInRoles := model.MakeDefaultRoles()
|
||||
@@ -944,6 +1041,48 @@ func (s SqlTeamStore) GetAllForExportAfter(limit int, afterId string) store.Stor
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) GetUserTeamIds(userId string, allowFromCache bool) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
if allowFromCache {
|
||||
if cacheItem, ok := allTeamIdsForUserCache.Get(userId); ok {
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheHitCounter("All Team Ids for User")
|
||||
}
|
||||
result.Data = cacheItem.([]string)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if s.metrics != nil {
|
||||
s.metrics.IncrementMemCacheMissCounter("All Team Ids for User")
|
||||
}
|
||||
|
||||
var teamIds []string
|
||||
_, err := s.GetReplica().Select(&teamIds, `
|
||||
SELECT
|
||||
TeamId
|
||||
FROM
|
||||
TeamMembers
|
||||
INNER JOIN
|
||||
Teams ON TeamMembers.TeamId = Teams.Id
|
||||
WHERE
|
||||
TeamMembers.UserId = :UserId
|
||||
AND TeamMembers.DeleteAt = 0
|
||||
AND Teams.DeleteAt = 0`,
|
||||
map[string]interface{}{"UserId": userId})
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.GetUserTeamIds", "store.sql_team.get_user_team_ids.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
result.Data = teamIds
|
||||
|
||||
if allowFromCache {
|
||||
allTeamIdsForUserCache.AddWithExpiresInSecs(userId, teamIds, ALL_TEAM_IDS_FOR_USER_CACHE_SEC)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) GetTeamMembersForExport(userId string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
var members []*model.TeamMemberForExport
|
||||
@@ -967,3 +1106,56 @@ func (s SqlTeamStore) GetTeamMembersForExport(userId string) store.StoreChannel
|
||||
result.Data = members
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlTeamStore) UserBelongsToTeams(userId string, teamIds []string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
props := make(map[string]interface{})
|
||||
props["UserId"] = userId
|
||||
idQuery := ""
|
||||
|
||||
for index, teamId := range teamIds {
|
||||
if len(idQuery) > 0 {
|
||||
idQuery += ", "
|
||||
}
|
||||
|
||||
props["teamId"+strconv.Itoa(index)] = teamId
|
||||
idQuery += ":teamId" + strconv.Itoa(index)
|
||||
}
|
||||
c, err := s.GetReplica().SelectInt("SELECT Count(*) FROM TeamMembers WHERE UserId = :UserId AND TeamId IN ("+idQuery+") AND DeleteAt = 0", props)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlTeamStore.UserBelongsToTeams", "store.sql_team.user_belongs_to_teams.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
result.Data = c > 0
|
||||
})
|
||||
}
|
||||
|
||||
func applyTeamMemberViewRestrictionsFilter(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder {
|
||||
if restrictions == nil {
|
||||
return query
|
||||
}
|
||||
|
||||
// If you have no access to teams or channels, return and empty result.
|
||||
if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 {
|
||||
return query.Where("1 = 0")
|
||||
}
|
||||
|
||||
teams := make([]interface{}, len(restrictions.Teams))
|
||||
for i, v := range restrictions.Teams {
|
||||
teams[i] = v
|
||||
}
|
||||
channels := make([]interface{}, len(restrictions.Channels))
|
||||
for i, v := range restrictions.Channels {
|
||||
channels[i] = v
|
||||
}
|
||||
|
||||
resultQuery := query.Join("Users ru ON (TeamMembers.UserId = ru.Id)")
|
||||
if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
|
||||
resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = ru.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
|
||||
}
|
||||
if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
|
||||
resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = ru.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
|
||||
}
|
||||
|
||||
return resultQuery.Distinct()
|
||||
}
|
||||
|
||||
@@ -407,6 +407,8 @@ func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) store.Store
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
|
||||
|
||||
query = applyRoleFilter(query, options.Role, isPostgreSQL)
|
||||
|
||||
if options.Inactive {
|
||||
@@ -466,6 +468,8 @@ func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) store.StoreCha
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
|
||||
|
||||
query = applyRoleFilter(query, options.Role, isPostgreSQL)
|
||||
|
||||
if options.Inactive {
|
||||
@@ -632,7 +636,7 @@ func (us SqlUserStore) GetAllProfilesInChannel(channelId string, allowFromCache
|
||||
})
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) store.StoreChannel {
|
||||
func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery.
|
||||
Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
|
||||
@@ -641,6 +645,8 @@ func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string,
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(offset)).Limit(uint64(limit))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.GetProfilesNotInChannel", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -661,7 +667,7 @@ func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string,
|
||||
})
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetProfilesWithoutTeam(offset int, limit int) store.StoreChannel {
|
||||
func (us SqlUserStore) GetProfilesWithoutTeam(offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery.
|
||||
Where(`(
|
||||
@@ -676,6 +682,8 @@ func (us SqlUserStore) GetProfilesWithoutTeam(offset int, limit int) store.Store
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(offset)).Limit(uint64(limit))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.GetProfilesWithoutTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -696,13 +704,11 @@ func (us SqlUserStore) GetProfilesWithoutTeam(offset int, limit int) store.Store
|
||||
})
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetProfilesByUsernames(usernames []string, teamId string) store.StoreChannel {
|
||||
func (us SqlUserStore) GetProfilesByUsernames(usernames []string, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery
|
||||
|
||||
if teamId != "" {
|
||||
query = query.Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId)
|
||||
}
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
query = query.
|
||||
Where(map[string]interface{}{
|
||||
@@ -731,7 +737,7 @@ type UserWithLastActivityAt struct {
|
||||
LastActivityAt int64
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limit int) store.StoreChannel {
|
||||
func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery.
|
||||
Column("s.LastActivityAt").
|
||||
@@ -741,6 +747,8 @@ func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limi
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(offset)).Limit(uint64(limit))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.GetRecentlyActiveUsers", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -766,7 +774,7 @@ func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limi
|
||||
})
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int) store.StoreChannel {
|
||||
func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery.
|
||||
Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId).
|
||||
@@ -774,6 +782,8 @@ func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int) stor
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(offset)).Limit(uint64(limit))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.GetNewUsersForTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -794,7 +804,7 @@ func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int) stor
|
||||
})
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetProfileByIds(userIds []string, allowFromCache bool) store.StoreChannel {
|
||||
func (us SqlUserStore) GetProfileByIds(userIds []string, allowFromCache bool, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
users := []*model.User{}
|
||||
remainingUserIds := make([]string, 0)
|
||||
@@ -832,6 +842,8 @@ func (us SqlUserStore) GetProfileByIds(userIds []string, allowFromCache bool) st
|
||||
}).
|
||||
OrderBy("u.Username ASC")
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.GetProfileByIds", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -1039,18 +1051,18 @@ func (us SqlUserStore) PermanentDelete(userId string) store.StoreChannel {
|
||||
|
||||
func (us SqlUserStore) Count(options model.UserCountOptions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := sq.Select("COUNT(Users.Id)").From("Users")
|
||||
query := sq.Select("COUNT(DISTINCT u.Id)").From("Users AS u")
|
||||
|
||||
if !options.IncludeDeleted {
|
||||
query = query.Where("Users.DeleteAt = 0")
|
||||
query = query.Where("u.DeleteAt = 0")
|
||||
}
|
||||
|
||||
if options.IncludeBotAccounts {
|
||||
if options.ExcludeRegularUsers {
|
||||
query = query.Join("Bots ON Users.Id = Bots.UserId")
|
||||
query = query.Join("Bots ON u.Id = Bots.UserId")
|
||||
}
|
||||
} else {
|
||||
query = query.LeftJoin("Bots ON Users.Id = Bots.UserId").Where("Bots.UserId IS NULL")
|
||||
query = query.LeftJoin("Bots ON u.Id = Bots.UserId").Where("Bots.UserId IS NULL")
|
||||
if options.ExcludeRegularUsers {
|
||||
// Currenty this doesn't make sense because it will always return 0
|
||||
result.Err = model.NewAppError("SqlUserStore.Count", "store.sql_user.count.app_error", nil, "", http.StatusInternalServerError)
|
||||
@@ -1059,8 +1071,9 @@ func (us SqlUserStore) Count(options model.UserCountOptions) store.StoreChannel
|
||||
}
|
||||
|
||||
if options.TeamId != "" {
|
||||
query = query.LeftJoin("TeamMembers ON Users.Id = TeamMembers.UserId").Where("TeamMembers.TeamId = ? AND TeamMembers.DeleteAt = 0", options.TeamId)
|
||||
query = query.LeftJoin("TeamMembers AS tm ON u.Id = tm.UserId").Where("tm.TeamId = ? AND tm.DeleteAt = 0", options.TeamId)
|
||||
}
|
||||
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, false)
|
||||
|
||||
if us.DriverName() == model.DATABASE_DRIVER_POSTGRES {
|
||||
query = query.PlaceholderFormat(sq.Dollar)
|
||||
@@ -1285,6 +1298,8 @@ func (us SqlUserStore) performSearch(query sq.SelectBuilder, term string, option
|
||||
query = generateSearchQuery(query, strings.Fields(term), searchType, isPostgreSQL)
|
||||
}
|
||||
|
||||
query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.Search", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -1326,7 +1341,7 @@ func (us SqlUserStore) AnalyticsGetSystemAdminCount() store.StoreChannel {
|
||||
})
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetProfilesNotInTeam(teamId string, offset int, limit int) store.StoreChannel {
|
||||
func (us SqlUserStore) GetProfilesNotInTeam(teamId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
query := us.usersQuery.
|
||||
LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
|
||||
@@ -1334,6 +1349,8 @@ func (us SqlUserStore) GetProfilesNotInTeam(teamId string, offset int, limit int
|
||||
OrderBy("u.Username ASC").
|
||||
Offset(uint64(offset)).Limit(uint64(limit))
|
||||
|
||||
query = applyViewRestrictionsFilter(query, viewRestrictions, true)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.GetProfilesNotInTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
@@ -1611,3 +1628,36 @@ func (us SqlUserStore) GetChannelGroupUsers(channelID string) store.StoreChannel
|
||||
result.Data = users
|
||||
})
|
||||
}
|
||||
|
||||
func applyViewRestrictionsFilter(query sq.SelectBuilder, restrictions *model.ViewUsersRestrictions, distinct bool) sq.SelectBuilder {
|
||||
if restrictions == nil {
|
||||
return query
|
||||
}
|
||||
|
||||
// If you have no access to teams or channels, return and empty result.
|
||||
if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 {
|
||||
return query.Where("1 = 0")
|
||||
}
|
||||
|
||||
teams := make([]interface{}, len(restrictions.Teams))
|
||||
for i, v := range restrictions.Teams {
|
||||
teams[i] = v
|
||||
}
|
||||
channels := make([]interface{}, len(restrictions.Channels))
|
||||
for i, v := range restrictions.Channels {
|
||||
channels[i] = v
|
||||
}
|
||||
resultQuery := query
|
||||
if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
|
||||
resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = u.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
|
||||
}
|
||||
if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
|
||||
resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = u.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
|
||||
}
|
||||
|
||||
if distinct {
|
||||
return resultQuery.Distinct()
|
||||
}
|
||||
|
||||
return resultQuery
|
||||
}
|
||||
|
||||
@@ -103,8 +103,8 @@ type TeamStore interface {
|
||||
SaveMember(member *model.TeamMember, maxUsersPerTeam int) StoreChannel
|
||||
UpdateMember(member *model.TeamMember) StoreChannel
|
||||
GetMember(teamId string, userId string) StoreChannel
|
||||
GetMembers(teamId string, offset int, limit int) StoreChannel
|
||||
GetMembersByIds(teamId string, userIds []string) StoreChannel
|
||||
GetMembers(teamId string, offset int, limit int, restrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetTotalMemberCount(teamId string) StoreChannel
|
||||
GetActiveMemberCount(teamId string) StoreChannel
|
||||
GetTeamsForUser(userId string) StoreChannel
|
||||
@@ -122,6 +122,10 @@ type TeamStore interface {
|
||||
AnalyticsGetTeamCountForScheme(schemeId string) StoreChannel
|
||||
GetAllForExportAfter(limit int, afterId string) StoreChannel
|
||||
GetTeamMembersForExport(userId string) StoreChannel
|
||||
UserBelongsToTeams(userId string, teamIds []string) StoreChannel
|
||||
GetUserTeamIds(userId string, allowFromCache bool) StoreChannel
|
||||
InvalidateAllTeamIdsForUser(userId string)
|
||||
ClearCaches()
|
||||
}
|
||||
|
||||
type ChannelStore interface {
|
||||
@@ -195,6 +199,7 @@ type ChannelStore interface {
|
||||
GetChannelMembersForExport(userId string, teamId string) StoreChannel
|
||||
RemoveAllDeactivatedMembers(channelId string) StoreChannel
|
||||
GetChannelsBatchForIndexing(startTime, endTime int64, limit int) StoreChannel
|
||||
UserBelongsToChannels(userId string, channelIds []string) StoreChannel
|
||||
}
|
||||
|
||||
type ChannelMemberHistoryStore interface {
|
||||
@@ -256,12 +261,12 @@ type UserStore interface {
|
||||
GetProfilesInChannel(channelId string, offset int, limit int) StoreChannel
|
||||
GetProfilesInChannelByStatus(channelId string, offset int, limit int) StoreChannel
|
||||
GetAllProfilesInChannel(channelId string, allowFromCache bool) StoreChannel
|
||||
GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) StoreChannel
|
||||
GetProfilesWithoutTeam(offset int, limit int) StoreChannel
|
||||
GetProfilesByUsernames(usernames []string, teamId string) StoreChannel
|
||||
GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetProfilesWithoutTeam(offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetProfilesByUsernames(usernames []string, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetAllProfiles(options *model.UserGetOptions) StoreChannel
|
||||
GetProfiles(options *model.UserGetOptions) StoreChannel
|
||||
GetProfileByIds(userId []string, allowFromCache bool) StoreChannel
|
||||
GetProfileByIds(userId []string, allowFromCache bool, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
InvalidatProfileCacheForUser(userId string)
|
||||
GetByEmail(email string) StoreChannel
|
||||
GetByAuth(authData *string, authService string) StoreChannel
|
||||
@@ -278,8 +283,8 @@ type UserStore interface {
|
||||
GetUnreadCount(userId string) StoreChannel
|
||||
GetUnreadCountForChannel(userId string, channelId string) StoreChannel
|
||||
GetAnyUnreadPostCountForChannel(userId string, channelId string) StoreChannel
|
||||
GetRecentlyActiveUsersForTeam(teamId string, offset, limit int) StoreChannel
|
||||
GetNewUsersForTeam(teamId string, offset, limit int) StoreChannel
|
||||
GetRecentlyActiveUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetNewUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
Search(teamId string, term string, options *model.UserSearchOptions) StoreChannel
|
||||
SearchNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) StoreChannel
|
||||
SearchInChannel(channelId string, term string, options *model.UserSearchOptions) StoreChannel
|
||||
@@ -287,7 +292,7 @@ type UserStore interface {
|
||||
SearchWithoutTeam(term string, options *model.UserSearchOptions) StoreChannel
|
||||
AnalyticsGetInactiveUsersCount() StoreChannel
|
||||
AnalyticsGetSystemAdminCount() StoreChannel
|
||||
GetProfilesNotInTeam(teamId string, offset int, limit int) StoreChannel
|
||||
GetProfilesNotInTeam(teamId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) StoreChannel
|
||||
GetEtagForProfilesNotInTeam(teamId string) StoreChannel
|
||||
ClearAllCustomRoleAssignments() StoreChannel
|
||||
InferSystemInstallDate() StoreChannel
|
||||
|
||||
@@ -1087,3 +1087,19 @@ func (_m *ChannelStore) UpdateMember(member *model.ChannelMember) store.StoreCha
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// UserBelongsToChannels provides a mock function with given fields: userId, channelIds
|
||||
func (_m *ChannelStore) UserBelongsToChannels(userId string, channelIds []string) store.StoreChannel {
|
||||
ret := _m.Called(userId, channelIds)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, []string) store.StoreChannel); ok {
|
||||
r0 = rf(userId, channelIds)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ func (_m *TeamStore) ClearAllCustomRoleAssignments() store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// ClearCaches provides a mock function with given fields:
|
||||
func (_m *TeamStore) ClearCaches() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: id
|
||||
func (_m *TeamStore) Get(id string) (*model.Team, *model.AppError) {
|
||||
ret := _m.Called(id)
|
||||
@@ -294,13 +299,13 @@ func (_m *TeamStore) GetMember(teamId string, userId string) store.StoreChannel
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetMembers provides a mock function with given fields: teamId, offset, limit
|
||||
func (_m *TeamStore) GetMembers(teamId string, offset int, limit int) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit)
|
||||
// GetMembers provides a mock function with given fields: teamId, offset, limit, restrictions
|
||||
func (_m *TeamStore) GetMembers(teamId string, offset int, limit int, restrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit, restrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit)
|
||||
if rf, ok := ret.Get(0).(func(string, int, int, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit, restrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -310,13 +315,13 @@ func (_m *TeamStore) GetMembers(teamId string, offset int, limit int) store.Stor
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetMembersByIds provides a mock function with given fields: teamId, userIds
|
||||
func (_m *TeamStore) GetMembersByIds(teamId string, userIds []string) store.StoreChannel {
|
||||
ret := _m.Called(teamId, userIds)
|
||||
// GetMembersByIds provides a mock function with given fields: teamId, userIds, restrictions
|
||||
func (_m *TeamStore) GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(teamId, userIds, restrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, []string) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, userIds)
|
||||
if rf, ok := ret.Get(0).(func(string, []string, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, userIds, restrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -422,6 +427,27 @@ func (_m *TeamStore) GetTotalMemberCount(teamId string) store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetUserTeamIds provides a mock function with given fields: userId, allowFromCache
|
||||
func (_m *TeamStore) GetUserTeamIds(userId string, allowFromCache bool) store.StoreChannel {
|
||||
ret := _m.Called(userId, allowFromCache)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, bool) store.StoreChannel); ok {
|
||||
r0 = rf(userId, allowFromCache)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// InvalidateAllTeamIdsForUser provides a mock function with given fields: userId
|
||||
func (_m *TeamStore) InvalidateAllTeamIdsForUser(userId string) {
|
||||
_m.Called(userId)
|
||||
}
|
||||
|
||||
// MigrateTeamMembers provides a mock function with given fields: fromTeamId, fromUserId
|
||||
func (_m *TeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) store.StoreChannel {
|
||||
ret := _m.Called(fromTeamId, fromUserId)
|
||||
@@ -686,3 +712,19 @@ func (_m *TeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// UserBelongsToTeams provides a mock function with given fields: userId, teamIds
|
||||
func (_m *TeamStore) UserBelongsToTeams(userId string, teamIds []string) store.StoreChannel {
|
||||
ret := _m.Called(userId, teamIds)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, []string) store.StoreChannel); ok {
|
||||
r0 = rf(userId, teamIds)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@@ -347,13 +347,13 @@ func (_m *UserStore) GetForLogin(loginId string, allowSignInWithUsername bool, a
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetNewUsersForTeam provides a mock function with given fields: teamId, offset, limit
|
||||
func (_m *UserStore) GetNewUsersForTeam(teamId string, offset int, limit int) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit)
|
||||
// GetNewUsersForTeam provides a mock function with given fields: teamId, offset, limit, viewRestrictions
|
||||
func (_m *UserStore) GetNewUsersForTeam(teamId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit)
|
||||
if rf, ok := ret.Get(0).(func(string, int, int, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -363,13 +363,13 @@ func (_m *UserStore) GetNewUsersForTeam(teamId string, offset int, limit int) st
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetProfileByIds provides a mock function with given fields: userId, allowFromCache
|
||||
func (_m *UserStore) GetProfileByIds(userId []string, allowFromCache bool) store.StoreChannel {
|
||||
ret := _m.Called(userId, allowFromCache)
|
||||
// GetProfileByIds provides a mock function with given fields: userId, allowFromCache, viewRestrictions
|
||||
func (_m *UserStore) GetProfileByIds(userId []string, allowFromCache bool, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(userId, allowFromCache, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func([]string, bool) store.StoreChannel); ok {
|
||||
r0 = rf(userId, allowFromCache)
|
||||
if rf, ok := ret.Get(0).(func([]string, bool, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(userId, allowFromCache, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -395,13 +395,13 @@ func (_m *UserStore) GetProfiles(options *model.UserGetOptions) store.StoreChann
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetProfilesByUsernames provides a mock function with given fields: usernames, teamId
|
||||
func (_m *UserStore) GetProfilesByUsernames(usernames []string, teamId string) store.StoreChannel {
|
||||
ret := _m.Called(usernames, teamId)
|
||||
// GetProfilesByUsernames provides a mock function with given fields: usernames, viewRestrictions
|
||||
func (_m *UserStore) GetProfilesByUsernames(usernames []string, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(usernames, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func([]string, string) store.StoreChannel); ok {
|
||||
r0 = rf(usernames, teamId)
|
||||
if rf, ok := ret.Get(0).(func([]string, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(usernames, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -443,13 +443,13 @@ func (_m *UserStore) GetProfilesInChannelByStatus(channelId string, offset int,
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetProfilesNotInChannel provides a mock function with given fields: teamId, channelId, offset, limit
|
||||
func (_m *UserStore) GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) store.StoreChannel {
|
||||
ret := _m.Called(teamId, channelId, offset, limit)
|
||||
// GetProfilesNotInChannel provides a mock function with given fields: teamId, channelId, offset, limit, viewRestrictions
|
||||
func (_m *UserStore) GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(teamId, channelId, offset, limit, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, channelId, offset, limit)
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, channelId, offset, limit, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -459,13 +459,13 @@ func (_m *UserStore) GetProfilesNotInChannel(teamId string, channelId string, of
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetProfilesNotInTeam provides a mock function with given fields: teamId, offset, limit
|
||||
func (_m *UserStore) GetProfilesNotInTeam(teamId string, offset int, limit int) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit)
|
||||
// GetProfilesNotInTeam provides a mock function with given fields: teamId, offset, limit, viewRestrictions
|
||||
func (_m *UserStore) GetProfilesNotInTeam(teamId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit)
|
||||
if rf, ok := ret.Get(0).(func(string, int, int, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -475,13 +475,13 @@ func (_m *UserStore) GetProfilesNotInTeam(teamId string, offset int, limit int)
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetProfilesWithoutTeam provides a mock function with given fields: offset, limit
|
||||
func (_m *UserStore) GetProfilesWithoutTeam(offset int, limit int) store.StoreChannel {
|
||||
ret := _m.Called(offset, limit)
|
||||
// GetProfilesWithoutTeam provides a mock function with given fields: offset, limit, viewRestrictions
|
||||
func (_m *UserStore) GetProfilesWithoutTeam(offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(offset, limit, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(int, int) store.StoreChannel); ok {
|
||||
r0 = rf(offset, limit)
|
||||
if rf, ok := ret.Get(0).(func(int, int, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(offset, limit, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
@@ -491,13 +491,13 @@ func (_m *UserStore) GetProfilesWithoutTeam(offset int, limit int) store.StoreCh
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetRecentlyActiveUsersForTeam provides a mock function with given fields: teamId, offset, limit
|
||||
func (_m *UserStore) GetRecentlyActiveUsersForTeam(teamId string, offset int, limit int) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit)
|
||||
// GetRecentlyActiveUsersForTeam provides a mock function with given fields: teamId, offset, limit, viewRestrictions
|
||||
func (_m *UserStore) GetRecentlyActiveUsersForTeam(teamId string, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) store.StoreChannel {
|
||||
ret := _m.Called(teamId, offset, limit, viewRestrictions)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit)
|
||||
if rf, ok := ret.Get(0).(func(string, int, int, *model.ViewUsersRestrictions) store.StoreChannel); ok {
|
||||
r0 = rf(teamId, offset, limit, viewRestrictions)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
|
||||
@@ -769,14 +769,14 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
||||
store.Must(ss.Team().SaveMember(m2, -1))
|
||||
store.Must(ss.Team().SaveMember(m3, -1))
|
||||
|
||||
if r1 := <-ss.Team().GetMembers(teamId1, 0, 100); r1.Err != nil {
|
||||
if r1 := <-ss.Team().GetMembers(teamId1, 0, 100, nil); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
ms := r1.Data.([]*model.TeamMember)
|
||||
require.Len(t, ms, 2)
|
||||
}
|
||||
|
||||
if r1 := <-ss.Team().GetMembers(teamId2, 0, 100); r1.Err != nil {
|
||||
if r1 := <-ss.Team().GetMembers(teamId2, 0, 100, nil); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
ms := r1.Data.([]*model.TeamMember)
|
||||
@@ -798,7 +798,7 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
||||
t.Fatal(r1.Err)
|
||||
}
|
||||
|
||||
if r1 := <-ss.Team().GetMembers(teamId1, 0, 100); r1.Err != nil {
|
||||
if r1 := <-ss.Team().GetMembers(teamId1, 0, 100, nil); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
ms := r1.Data.([]*model.TeamMember)
|
||||
@@ -813,7 +813,7 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
||||
t.Fatal(r1.Err)
|
||||
}
|
||||
|
||||
if r1 := <-ss.Team().GetMembers(teamId1, 0, 100); r1.Err != nil {
|
||||
if r1 := <-ss.Team().GetMembers(teamId1, 0, 100, nil); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
ms := r1.Data.([]*model.TeamMember)
|
||||
@@ -872,7 +872,7 @@ func testTeamMembersWithPagination(t *testing.T, ss store.Store) {
|
||||
r1 = <-ss.Team().RemoveMember(teamId1, m1.UserId)
|
||||
require.Nil(t, r1.Err)
|
||||
|
||||
r1 = <-ss.Team().GetMembers(teamId1, 0, 100)
|
||||
r1 = <-ss.Team().GetMembers(teamId1, 0, 100, nil)
|
||||
require.Nil(t, r1.Err)
|
||||
|
||||
ms = r1.Data.([]*model.TeamMember)
|
||||
@@ -1077,7 +1077,7 @@ func testGetTeamMembersByIds(t *testing.T, ss store.Store) {
|
||||
m1 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
|
||||
store.Must(ss.Team().SaveMember(m1, -1))
|
||||
|
||||
if r := <-ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId}); r.Err != nil {
|
||||
if r := <-ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId}, nil); r.Err != nil {
|
||||
t.Fatal(r.Err)
|
||||
} else {
|
||||
rm1 := r.Data.([]*model.TeamMember)[0]
|
||||
@@ -1094,7 +1094,7 @@ func testGetTeamMembersByIds(t *testing.T, ss store.Store) {
|
||||
m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
|
||||
store.Must(ss.Team().SaveMember(m2, -1))
|
||||
|
||||
if r := <-ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId, m2.UserId, model.NewId()}); r.Err != nil {
|
||||
if r := <-ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId, m2.UserId, model.NewId()}, nil); r.Err != nil {
|
||||
t.Fatal(r.Err)
|
||||
} else {
|
||||
rm := r.Data.([]*model.TeamMember)
|
||||
@@ -1104,7 +1104,7 @@ func testGetTeamMembersByIds(t *testing.T, ss store.Store) {
|
||||
}
|
||||
}
|
||||
|
||||
if r := <-ss.Team().GetMembersByIds(m1.TeamId, []string{}); r.Err == nil {
|
||||
if r := <-ss.Team().GetMembersByIds(m1.TeamId, []string{}, nil); r.Err == nil {
|
||||
t.Fatal("empty user ids - should have failed")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -860,19 +860,19 @@ func testUserStoreGetProfilesWithoutTeam(t *testing.T, ss store.Store) {
|
||||
defer func() { store.Must(ss.Bot().PermanentDelete(u3.Id)) }()
|
||||
|
||||
t.Run("get, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesWithoutTeam(0, 100)
|
||||
result := <-ss.User().GetProfilesWithoutTeam(0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{sanitized(u2), sanitized(u3)}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get, offset 1, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesWithoutTeam(1, 1)
|
||||
result := <-ss.User().GetProfilesWithoutTeam(1, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{sanitized(u3)}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get, offset 2, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesWithoutTeam(2, 1)
|
||||
result := <-ss.User().GetProfilesWithoutTeam(2, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{}, result.Data.([]*model.User))
|
||||
})
|
||||
@@ -1031,7 +1031,7 @@ func testUserStoreGetProfilesNotInChannel(t *testing.T, ss store.Store) {
|
||||
}, -1)).(*model.Channel)
|
||||
|
||||
t.Run("get team 1, channel 1, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c1.Id, 0, 100)
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c1.Id, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u1),
|
||||
@@ -1041,7 +1041,7 @@ func testUserStoreGetProfilesNotInChannel(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get team 1, channel 2, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c2.Id, 0, 100)
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c2.Id, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u1),
|
||||
@@ -1075,13 +1075,13 @@ func testUserStoreGetProfilesNotInChannel(t *testing.T, ss store.Store) {
|
||||
}))
|
||||
|
||||
t.Run("get team 1, channel 1, offset 0, limit 100, after update", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c1.Id, 0, 100)
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c1.Id, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get team 1, channel 2, offset 0, limit 100, after update", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c2.Id, 0, 100)
|
||||
result := <-ss.User().GetProfilesNotInChannel(teamId, c2.Id, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u2),
|
||||
@@ -1122,31 +1122,31 @@ func testUserStoreGetProfilesByIds(t *testing.T, ss store.Store) {
|
||||
defer func() { store.Must(ss.Bot().PermanentDelete(u3.Id)) }()
|
||||
|
||||
t.Run("get u1 by id, no caching", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id}, false)
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id}, false, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{sanitized(u1)}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get u1 by id, caching", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id}, true)
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id}, true, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{sanitized(u1)}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get u1, u2, u3 by id, no caching", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id, u2.Id, u3.Id}, false)
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id, u2.Id, u3.Id}, false, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{sanitized(u1), sanitized(u2), sanitized(u3)}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get u1, u2, u3 by id, caching", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id, u2.Id, u3.Id}, true)
|
||||
result := <-ss.User().GetProfileByIds([]string{u1.Id, u2.Id, u3.Id}, true, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{sanitized(u1), sanitized(u2), sanitized(u3)}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get unknown id, caching", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfileByIds([]string{"123"}, true)
|
||||
result := <-ss.User().GetProfileByIds([]string{"123"}, true, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{}, result.Data.([]*model.User))
|
||||
})
|
||||
@@ -1185,31 +1185,31 @@ func testUserStoreGetProfilesByUsernames(t *testing.T, ss store.Store) {
|
||||
defer func() { store.Must(ss.Bot().PermanentDelete(u3.Id)) }()
|
||||
|
||||
t.Run("get by u1 and u2 usernames, team id 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u2.Username}, teamId)
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u2.Username}, &model.ViewUsersRestrictions{Teams: []string{teamId}})
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{u1, u2}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get by u1 username, team id 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username}, teamId)
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username}, &model.ViewUsersRestrictions{Teams: []string{teamId}})
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{u1}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get by u1 and u3 usernames, no team id", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u3.Username}, "")
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u3.Username}, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{u1, u3}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get by u1 and u3 usernames, team id 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u3.Username}, teamId)
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u3.Username}, &model.ViewUsersRestrictions{Teams: []string{teamId}})
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{u1}, result.Data.([]*model.User))
|
||||
})
|
||||
|
||||
t.Run("get by u1 and u3 usernames, team id 2", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u3.Username}, team2Id)
|
||||
result := <-ss.User().GetProfilesByUsernames([]string{u1.Username, u3.Username}, &model.ViewUsersRestrictions{Teams: []string{team2Id}})
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{u3}, result.Data.([]*model.User))
|
||||
})
|
||||
@@ -1778,7 +1778,7 @@ func testUserStoreGetRecentlyActiveUsersForTeam(t *testing.T, ss store.Store) {
|
||||
store.Must(ss.Status().SaveOrUpdate(&model.Status{UserId: u3.Id, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: u3.LastActivityAt, ActiveChannel: ""}))
|
||||
|
||||
t.Run("get team 1, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetRecentlyActiveUsersForTeam(teamId, 0, 100)
|
||||
result := <-ss.User().GetRecentlyActiveUsersForTeam(teamId, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u3),
|
||||
@@ -1788,7 +1788,7 @@ func testUserStoreGetRecentlyActiveUsersForTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get team 1, offset 0, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetRecentlyActiveUsersForTeam(teamId, 0, 1)
|
||||
result := <-ss.User().GetRecentlyActiveUsersForTeam(teamId, 0, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u3),
|
||||
@@ -1796,7 +1796,7 @@ func testUserStoreGetRecentlyActiveUsersForTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get team 1, offset 2, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetRecentlyActiveUsersForTeam(teamId, 2, 1)
|
||||
result := <-ss.User().GetRecentlyActiveUsersForTeam(teamId, 2, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u2),
|
||||
@@ -1844,7 +1844,7 @@ func testUserStoreGetNewUsersForTeam(t *testing.T, ss store.Store) {
|
||||
store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: teamId2, UserId: u4.Id}, -1))
|
||||
|
||||
t.Run("get team 1, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId, 0, 100)
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u3),
|
||||
@@ -1854,7 +1854,7 @@ func testUserStoreGetNewUsersForTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get team 1, offset 0, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId, 0, 1)
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId, 0, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u3),
|
||||
@@ -1862,7 +1862,7 @@ func testUserStoreGetNewUsersForTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get team 1, offset 2, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId, 2, 1)
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId, 2, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u1),
|
||||
@@ -1870,7 +1870,7 @@ func testUserStoreGetNewUsersForTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get team 2, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId2, 0, 100)
|
||||
result := <-ss.User().GetNewUsersForTeam(teamId2, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u4),
|
||||
@@ -2982,6 +2982,23 @@ func testCount(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, result.Err)
|
||||
require.Equal(t, int64(0), result.Data.(int64))
|
||||
|
||||
result = <-ss.User().Count(model.UserCountOptions{
|
||||
IncludeBotAccounts: true,
|
||||
IncludeDeleted: true,
|
||||
TeamId: teamId,
|
||||
ViewRestrictions: &model.ViewUsersRestrictions{Teams: []string{teamId}},
|
||||
})
|
||||
require.Nil(t, result.Err)
|
||||
require.Equal(t, int64(1), result.Data.(int64))
|
||||
|
||||
result = <-ss.User().Count(model.UserCountOptions{
|
||||
IncludeBotAccounts: true,
|
||||
IncludeDeleted: true,
|
||||
TeamId: teamId,
|
||||
ViewRestrictions: &model.ViewUsersRestrictions{Teams: []string{model.NewId()}},
|
||||
})
|
||||
require.Nil(t, result.Err)
|
||||
require.Equal(t, int64(0), result.Data.(int64))
|
||||
}
|
||||
|
||||
func testUserStoreAnalyticsGetInactiveUsersCount(t *testing.T, ss store.Store) {
|
||||
@@ -3097,7 +3114,7 @@ func testUserStoreGetProfilesNotInTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get not in team 1, offset 0, limit 100000", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 0, 100000)
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 0, 100000, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u2),
|
||||
@@ -3106,7 +3123,7 @@ func testUserStoreGetProfilesNotInTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get not in team 1, offset 1, limit 1", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 1, 1)
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 1, 1, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u3),
|
||||
@@ -3114,7 +3131,7 @@ func testUserStoreGetProfilesNotInTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get not in team 2, offset 0, limit 100", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId2, 0, 100)
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId2, 0, 100, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u1),
|
||||
@@ -3137,7 +3154,7 @@ func testUserStoreGetProfilesNotInTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get not in team 1, offset 0, limit 100000 after update", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 0, 100000)
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 0, 100000, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u3),
|
||||
@@ -3161,7 +3178,7 @@ func testUserStoreGetProfilesNotInTeam(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("get not in team 1, offset 0, limit 100000 after second update", func(t *testing.T) {
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 0, 100000)
|
||||
result := <-ss.User().GetProfilesNotInTeam(teamId, 0, 100000, nil)
|
||||
require.Nil(t, result.Err)
|
||||
assert.Equal(t, []*model.User{
|
||||
sanitized(u1),
|
||||
|
||||
Ссылка в новой задаче
Block a user