MM-44101: GraphQL: Add sidebar categories at the top level (#20178)
Also, add a negate parameter to the team members to get all sidebarcategories except the default team. ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
3c625743e5
Коммит
acae0031d1
@@ -53,7 +53,7 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
defer c.LogAuditRec(auditRec)
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
// Allow any user with CREATE_EMOJIS permission at Team level to create emojis at system level
|
// Allow any user with CREATE_EMOJIS permission at Team level to create emojis at system level
|
||||||
memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId, true)
|
memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId, "", true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
@@ -143,7 +143,7 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
auditRec.AddMeta("emoji", emoji)
|
auditRec.AddMeta("emoji", emoji)
|
||||||
|
|
||||||
// Allow any user with DELETE_EMOJIS permission at Team level to delete emojis at system level
|
// Allow any user with DELETE_EMOJIS permission at Team level to delete emojis at system level
|
||||||
memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId, true)
|
memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId, "", true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
|
|||||||
@@ -132,8 +132,9 @@ func (r *resolver) License(ctx context.Context) (model.StringMap, error) {
|
|||||||
// match with api4.getTeamMembersForUser for teamID=""
|
// match with api4.getTeamMembersForUser for teamID=""
|
||||||
// and api4.getTeamMember for teamID != ""
|
// and api4.getTeamMember for teamID != ""
|
||||||
func (r *resolver) TeamMembers(ctx context.Context, args struct {
|
func (r *resolver) TeamMembers(ctx context.Context, args struct {
|
||||||
UserID string
|
UserID string
|
||||||
TeamID string
|
TeamID string
|
||||||
|
ExcludeTeam bool
|
||||||
}) ([]*teamMember, error) {
|
}) ([]*teamMember, error) {
|
||||||
c, err := getCtx(ctx)
|
c, err := getCtx(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -159,7 +160,7 @@ func (r *resolver) TeamMembers(ctx context.Context, args struct {
|
|||||||
return nil, c.Err
|
return nil, c.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.TeamID != "" {
|
if args.TeamID != "" && !args.ExcludeTeam {
|
||||||
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), args.TeamID, model.PermissionViewTeam) {
|
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), args.TeamID, model.PermissionViewTeam) {
|
||||||
c.SetPermissionError(model.PermissionViewTeam)
|
c.SetPermissionError(model.PermissionViewTeam)
|
||||||
return nil, c.Err
|
return nil, c.Err
|
||||||
@@ -173,8 +174,13 @@ func (r *resolver) TeamMembers(ctx context.Context, args struct {
|
|||||||
return []*teamMember{{*tm}}, nil
|
return []*teamMember{{*tm}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
excludeTeamID := ""
|
||||||
|
if args.TeamID != "" && args.ExcludeTeam {
|
||||||
|
excludeTeamID = args.TeamID
|
||||||
|
}
|
||||||
|
|
||||||
// Do not return archived team members
|
// Do not return archived team members
|
||||||
members, appErr := c.App.GetTeamMembersForUser(args.UserID, false)
|
members, appErr := c.App.GetTeamMembersForUser(args.UserID, excludeTeamID, false)
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return nil, appErr
|
return nil, appErr
|
||||||
}
|
}
|
||||||
@@ -301,6 +307,37 @@ func (*resolver) ChannelMembers(ctx context.Context, args struct {
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// match with api4.getCategoriesForTeamForUser
|
||||||
|
func (*resolver) SidebarCategories(ctx context.Context, args struct {
|
||||||
|
UserID string
|
||||||
|
TeamID string
|
||||||
|
}) ([]*model.SidebarCategoryWithChannels, error) {
|
||||||
|
c, err := getCtx(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to primary team logic
|
||||||
|
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), args.TeamID, model.PermissionViewTeam) {
|
||||||
|
primaryTeam := *c.App.Config().TeamSettings.ExperimentalPrimaryTeam
|
||||||
|
if primaryTeam != "" {
|
||||||
|
team, appErr := c.App.GetTeamByName(primaryTeam)
|
||||||
|
if appErr != nil {
|
||||||
|
return []*model.SidebarCategoryWithChannels{}, appErr
|
||||||
|
}
|
||||||
|
args.TeamID = team.Id
|
||||||
|
} else {
|
||||||
|
return []*model.SidebarCategoryWithChannels{}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.UserID == model.Me {
|
||||||
|
args.UserID = c.AppContext.Session().UserId
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSidebarCategories(c, args.UserID, args.TeamID)
|
||||||
|
}
|
||||||
|
|
||||||
// getCtx extracts web.Context out of the usual request context.
|
// getCtx extracts web.Context out of the usual request context.
|
||||||
// Kind of an anti-pattern, but there are lots of methods attached to *web.Context
|
// Kind of an anti-pattern, but there are lots of methods attached to *web.Context
|
||||||
// so we use it for now.
|
// so we use it for now.
|
||||||
|
|||||||
72
api4/resolver_sidebar_categories_test.go
Обычный файл
72
api4/resolver_sidebar_categories_test.go
Обычный файл
@@ -0,0 +1,72 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
package api4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/v6/model"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGraphQLSidebarCategories(t *testing.T) {
|
||||||
|
os.Setenv("MM_FEATUREFLAGS_GRAPHQL", "true")
|
||||||
|
defer os.Unsetenv("MM_FEATUREFLAGS_GRAPHQL")
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
var q struct {
|
||||||
|
SidebarCategories []struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
Sorting model.SidebarCategorySorting `json:"sorting"`
|
||||||
|
ChannelIDs []string `json:"channelIds"`
|
||||||
|
} `json:"sidebarCategories"`
|
||||||
|
}
|
||||||
|
|
||||||
|
input := graphQLInput{
|
||||||
|
OperationName: "sidebarCategories",
|
||||||
|
Query: `
|
||||||
|
query sidebarCategories($userId: String = "", $teamId: String = "") {
|
||||||
|
sidebarCategories(userId: $userId, teamId: $teamId) {
|
||||||
|
id
|
||||||
|
displayName
|
||||||
|
sorting
|
||||||
|
channelIds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Variables: map[string]interface{}{
|
||||||
|
"userId": "me",
|
||||||
|
"teamId": th.BasicTeam.Id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := th.MakeGraphQLRequest(&input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, resp.Errors, 0)
|
||||||
|
require.NoError(t, json.Unmarshal(resp.Data, &q))
|
||||||
|
assert.Len(t, q.SidebarCategories, 3)
|
||||||
|
|
||||||
|
categories, _, err := th.Client.GetSidebarCategoriesForTeamForUser(th.BasicUser.Id, th.BasicTeam.Id, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
sort.Slice(q.SidebarCategories, func(i, j int) bool {
|
||||||
|
return q.SidebarCategories[i].ID < q.SidebarCategories[j].ID
|
||||||
|
})
|
||||||
|
sort.Slice(categories.Categories, func(i, j int) bool {
|
||||||
|
return categories.Categories[i].Id < categories.Categories[j].Id
|
||||||
|
})
|
||||||
|
|
||||||
|
for i := range categories.Categories {
|
||||||
|
assert.Equal(t, categories.Categories[i].Id, q.SidebarCategories[i].ID)
|
||||||
|
assert.Equal(t, categories.Categories[i].DisplayName, q.SidebarCategories[i].DisplayName)
|
||||||
|
assert.Equal(t, categories.Categories[i].Sorting, q.SidebarCategories[i].Sorting)
|
||||||
|
assert.Equal(t, categories.Categories[i].ChannelIds(), q.SidebarCategories[i].ChannelIDs)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/graph-gophers/dataloader/v6"
|
"github.com/graph-gophers/dataloader/v6"
|
||||||
"github.com/mattermost/mattermost-server/v6/model"
|
"github.com/mattermost/mattermost-server/v6/model"
|
||||||
|
"github.com/mattermost/mattermost-server/v6/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
// teamMember is an internal graphQL wrapper struct to add resolver methods.
|
// teamMember is an internal graphQL wrapper struct to add resolver methods.
|
||||||
@@ -33,12 +34,16 @@ func (tm *teamMember) SidebarCategories(ctx context.Context) ([]*model.SidebarCa
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), tm.UserId) {
|
return getSidebarCategories(c, tm.UserId, tm.TeamId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSidebarCategories(c *web.Context, userID, teamID string) ([]*model.SidebarCategoryWithChannels, error) {
|
||||||
|
if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), userID) {
|
||||||
c.SetPermissionError(model.PermissionEditOtherUsers)
|
c.SetPermissionError(model.PermissionEditOtherUsers)
|
||||||
return nil, c.Err
|
return nil, c.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
categories, appErr := c.App.GetSidebarCategories(tm.UserId, tm.TeamId)
|
categories, appErr := c.App.GetSidebarCategories(userID, teamID)
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return nil, appErr
|
return nil, appErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,6 +249,48 @@ func TestGraphQLTeamMembers(t *testing.T) {
|
|||||||
expectedTeams[i].DisplayName = tm.Team.DisplayName
|
expectedTeams[i].DisplayName = tm.Team.DisplayName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Negate team
|
||||||
|
input = graphQLInput{
|
||||||
|
OperationName: "teamMembers",
|
||||||
|
Query: `
|
||||||
|
query teamMembers($userId: String = "", $teamId: String = "") {
|
||||||
|
teamMembers(userId: $userId, teamId: $teamId, excludeTeam: true) {
|
||||||
|
team {
|
||||||
|
id
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Variables: map[string]interface{}{
|
||||||
|
"userId": "me",
|
||||||
|
"teamId": th.BasicTeam.Id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = th.MakeGraphQLRequest(&input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, resp.Errors, 0)
|
||||||
|
require.NoError(t, json.Unmarshal(resp.Data, &q))
|
||||||
|
assert.Len(t, q.TeamMembers, 1)
|
||||||
|
|
||||||
|
input = graphQLInput{
|
||||||
|
OperationName: "teamMembers",
|
||||||
|
Query: `
|
||||||
|
query teamMembers($userId: String = "", $teamId: String = "") {
|
||||||
|
teamMembers(userId: $userId, teamId: $teamId) {
|
||||||
|
team {
|
||||||
|
id
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Variables: map[string]interface{}{
|
||||||
|
"userId": "me",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// Removing from a team and ensuring we get the right response.
|
// Removing from a team and ensuring we get the right response.
|
||||||
th.UnlinkUserFromTeam(th.BasicUser, myTeam)
|
th.UnlinkUserFromTeam(th.BasicUser, myTeam)
|
||||||
resp, err = th.MakeGraphQLRequest(&input)
|
resp, err = th.MakeGraphQLRequest(&input)
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ type Query {
|
|||||||
config(): StringMap!
|
config(): StringMap!
|
||||||
license(): StringMap!
|
license(): StringMap!
|
||||||
teamMembers(userId: String!,
|
teamMembers(userId: String!,
|
||||||
teamId: String = ""): [TeamMember]!
|
teamId: String = "",
|
||||||
|
excludeTeam: Boolean = false): [TeamMember]!
|
||||||
channels(userId: String!,
|
channels(userId: String!,
|
||||||
teamId: String = "",
|
teamId: String = "",
|
||||||
includeDeleted: Boolean = false,
|
includeDeleted: Boolean = false,
|
||||||
@@ -24,6 +25,8 @@ type Query {
|
|||||||
first: Int = 60,
|
first: Int = 60,
|
||||||
after: String = "",
|
after: String = "",
|
||||||
lastUpdateAt: Float = 0): [ChannelMember]!
|
lastUpdateAt: Float = 0): [ChannelMember]!
|
||||||
|
sidebarCategories(userId: String!,
|
||||||
|
teamId: String!): [SidebarCategory]!
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar ChannelType
|
scalar ChannelType
|
||||||
|
|||||||
@@ -554,7 +554,7 @@ func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
members, err := c.App.GetTeamMembersForUser(c.Params.UserId, true)
|
members, err := c.App.GetTeamMembersForUser(c.Params.UserId, "", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -737,7 +737,7 @@ type AppIface interface {
|
|||||||
GetTeamMember(teamID, userID string) (*model.TeamMember, *model.AppError)
|
GetTeamMember(teamID, userID string) (*model.TeamMember, *model.AppError)
|
||||||
GetTeamMembers(teamID string, offset int, limit int, teamMembersGetOptions *model.TeamMembersGetOptions) ([]*model.TeamMember, *model.AppError)
|
GetTeamMembers(teamID string, offset int, limit int, teamMembersGetOptions *model.TeamMembersGetOptions) ([]*model.TeamMember, *model.AppError)
|
||||||
GetTeamMembersByIds(teamID string, userIDs []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError)
|
GetTeamMembersByIds(teamID string, userIDs []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError)
|
||||||
GetTeamMembersForUser(userID string, includeDeleted bool) ([]*model.TeamMember, *model.AppError)
|
GetTeamMembersForUser(userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, *model.AppError)
|
||||||
GetTeamMembersForUserWithPagination(userID string, page, perPage int) ([]*model.TeamMember, *model.AppError)
|
GetTeamMembersForUserWithPagination(userID string, page, perPage int) ([]*model.TeamMember, *model.AppError)
|
||||||
GetTeamPoliciesForUser(userID string, offset, limit int) (*model.RetentionPolicyForTeamList, *model.AppError)
|
GetTeamPoliciesForUser(userID string, offset, limit int) (*model.RetentionPolicyForTeamList, *model.AppError)
|
||||||
GetTeamStats(teamID string, restrictions *model.ViewUsersRestrictions) (*model.TeamStats, *model.AppError)
|
GetTeamStats(teamID string, restrictions *model.ViewUsersRestrictions) (*model.TeamStats, *model.AppError)
|
||||||
|
|||||||
@@ -737,7 +737,7 @@ func (a *App) importUserTeams(user *model.User, data *[]UserTeamImportData) *mod
|
|||||||
isGuestByTeamId := map[string]bool{}
|
isGuestByTeamId := map[string]bool{}
|
||||||
isUserByTeamId := map[string]bool{}
|
isUserByTeamId := map[string]bool{}
|
||||||
isAdminByTeamId := map[string]bool{}
|
isAdminByTeamId := map[string]bool{}
|
||||||
existingMemberships, nErr := a.Srv().Store.Team().GetTeamsForUser(context.Background(), user.Id, true)
|
existingMemberships, nErr := a.Srv().Store.Team().GetTeamsForUser(context.Background(), user.Id, "", true)
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
return model.NewAppError("importUserTeams", "app.team.get_members.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
return model.NewAppError("importUserTeams", "app.team.get_members.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1717,7 +1717,7 @@ func TestImportUserTeams(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
teamMembers, nErr := th.App.Srv().Store.Team().GetTeamsForUser(context.Background(), user.Id, true)
|
teamMembers, nErr := th.App.Srv().Store.Team().GetTeamsForUser(context.Background(), user.Id, "", true)
|
||||||
require.NoError(t, nErr)
|
require.NoError(t, nErr)
|
||||||
require.Len(t, teamMembers, tc.expectedUserTeams)
|
require.Len(t, teamMembers, tc.expectedUserTeams)
|
||||||
if tc.expectedUserTeams == 1 {
|
if tc.expectedUserTeams == 1 {
|
||||||
|
|||||||
@@ -9200,7 +9200,7 @@ func (a *OpenTracingAppLayer) GetTeamMembersByIds(teamID string, userIDs []strin
|
|||||||
return resultVar0, resultVar1
|
return resultVar0, resultVar1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) GetTeamMembersForUser(userID string, includeDeleted bool) ([]*model.TeamMember, *model.AppError) {
|
func (a *OpenTracingAppLayer) GetTeamMembersForUser(userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, *model.AppError) {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetTeamMembersForUser")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetTeamMembersForUser")
|
||||||
|
|
||||||
@@ -9212,7 +9212,7 @@ func (a *OpenTracingAppLayer) GetTeamMembersForUser(userID string, includeDelete
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
resultVar0, resultVar1 := a.app.GetTeamMembersForUser(userID, includeDeleted)
|
resultVar0, resultVar1 := a.app.GetTeamMembersForUser(userID, excludeTeamID, includeDeleted)
|
||||||
|
|
||||||
if resultVar1 != nil {
|
if resultVar1 != nil {
|
||||||
span.LogFields(spanlog.Error(resultVar1))
|
span.LogFields(spanlog.Error(resultVar1))
|
||||||
|
|||||||
@@ -893,8 +893,8 @@ func (a *App) GetTeamMember(teamID, userID string) (*model.TeamMember, *model.Ap
|
|||||||
return teamMember, nil
|
return teamMember, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) GetTeamMembersForUser(userID string, includeDeleted bool) ([]*model.TeamMember, *model.AppError) {
|
func (a *App) GetTeamMembersForUser(userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, *model.AppError) {
|
||||||
teamMembers, err := a.Srv().Store.Team().GetTeamsForUser(context.Background(), userID, includeDeleted)
|
teamMembers, err := a.Srv().Store.Team().GetTeamsForUser(context.Background(), userID, excludeTeamID, includeDeleted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("GetTeamMembersForUser", "app.team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("GetTeamMembersForUser", "app.team.get_members.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2145,7 +2145,7 @@ func (a *App) PromoteGuestToUser(c *request.Context, user *model.User, requestor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
teamMembers, err := a.GetTeamMembersForUser(user.Id, true)
|
teamMembers, err := a.GetTeamMembersForUser(user.Id, "", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mlog.Warn("Failed to get team members for user on promote guest to user", mlog.Err(err))
|
mlog.Warn("Failed to get team members for user on promote guest to user", mlog.Err(err))
|
||||||
}
|
}
|
||||||
@@ -2189,7 +2189,7 @@ func (a *App) DemoteUserToGuest(user *model.User) *model.AppError {
|
|||||||
mlog.Warn("Unable to update user sessions", mlog.String("user_id", demotedUser.Id), mlog.Err(uErr))
|
mlog.Warn("Unable to update user sessions", mlog.String("user_id", demotedUser.Id), mlog.Err(uErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
teamMembers, err := a.GetTeamMembersForUser(user.Id, true)
|
teamMembers, err := a.GetTeamMembersForUser(user.Id, "", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mlog.Warn("Failed to get team members for users on demote user to guest", mlog.Err(err))
|
mlog.Warn("Failed to get team members for users on demote user to guest", mlog.Err(err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8822,7 +8822,7 @@ func (s *OpenTracingLayerTeamStore) GetTeamsByUserId(userID string) ([]*model.Te
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *OpenTracingLayerTeamStore) GetTeamsForUser(ctx context.Context, userID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
func (s *OpenTracingLayerTeamStore) GetTeamsForUser(ctx context.Context, userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
||||||
origCtx := s.Root.Store.Context()
|
origCtx := s.Root.Store.Context()
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "TeamStore.GetTeamsForUser")
|
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "TeamStore.GetTeamsForUser")
|
||||||
s.Root.Store.SetContext(newCtx)
|
s.Root.Store.SetContext(newCtx)
|
||||||
@@ -8831,7 +8831,7 @@ func (s *OpenTracingLayerTeamStore) GetTeamsForUser(ctx context.Context, userID
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
result, err := s.TeamStore.GetTeamsForUser(ctx, userID, includeDeleted)
|
result, err := s.TeamStore.GetTeamsForUser(ctx, userID, excludeTeamID, includeDeleted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.LogFields(spanlog.Error(err))
|
span.LogFields(spanlog.Error(err))
|
||||||
ext.Error.Set(span, true)
|
ext.Error.Set(span, true)
|
||||||
|
|||||||
@@ -10072,11 +10072,11 @@ func (s *RetryLayerTeamStore) GetTeamsByUserId(userID string) ([]*model.Team, er
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RetryLayerTeamStore) GetTeamsForUser(ctx context.Context, userID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
func (s *RetryLayerTeamStore) GetTeamsForUser(ctx context.Context, userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
||||||
|
|
||||||
tries := 0
|
tries := 0
|
||||||
for {
|
for {
|
||||||
result, err := s.TeamStore.GetTeamsForUser(ctx, userID, includeDeleted)
|
result, err := s.TeamStore.GetTeamsForUser(ctx, userID, excludeTeamID, includeDeleted)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (me SqlSessionStore) Save(session *model.Session) (*model.Session, error) {
|
|||||||
return nil, errors.Wrapf(err, "failed to save Session with id=%s", session.Id)
|
return nil, errors.Wrapf(err, "failed to save Session with id=%s", session.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
teamMembers, err := me.Team().GetTeamsForUser(context.Background(), session.UserId, true)
|
teamMembers, err := me.Team().GetTeamsForUser(context.Background(), session.UserId, "", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to find TeamMembers for Session with userId=%s", session.UserId)
|
return nil, errors.Wrapf(err, "failed to find TeamMembers for Session with userId=%s", session.UserId)
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ func (me SqlSessionStore) Get(ctx context.Context, sessionIdOrToken string) (*mo
|
|||||||
|
|
||||||
tempMembers, err := me.Team().GetTeamsForUser(
|
tempMembers, err := me.Team().GetTeamsForUser(
|
||||||
WithMaster(context.Background()),
|
WithMaster(context.Background()),
|
||||||
session.UserId, true)
|
session.UserId, "", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to find TeamMembers for Session with userId=%s", session.UserId)
|
return nil, errors.Wrapf(err, "failed to find TeamMembers for Session with userId=%s", session.UserId)
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ func (me SqlSessionStore) GetSessions(userId string) ([]*model.Session, error) {
|
|||||||
return nil, errors.Wrapf(err, "failed to find Sessions with userId=%s", userId)
|
return nil, errors.Wrapf(err, "failed to find Sessions with userId=%s", userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
teamMembers, err := me.Team().GetTeamsForUser(context.Background(), userId, true)
|
teamMembers, err := me.Team().GetTeamsForUser(context.Background(), userId, "", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to find TeamMembers for Session with userId=%s", userId)
|
return nil, errors.Wrapf(err, "failed to find TeamMembers for Session with userId=%s", userId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1080,11 +1080,15 @@ func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string, restricti
|
|||||||
return dbMembers.ToModel(), nil
|
return dbMembers.ToModel(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTeamsForUser returns a list of teams that the user is a member of. Expects userId to be passed as a parameter.
|
// GetTeamsForUser returns a list of teams that the user is a member of. Expects userId to be passed as a parameter. It can also negative the teamID passed.
|
||||||
func (s SqlTeamStore) GetTeamsForUser(ctx context.Context, userId string, includeDeleted bool) ([]*model.TeamMember, error) {
|
func (s SqlTeamStore) GetTeamsForUser(ctx context.Context, userId, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
||||||
query := s.getTeamMembersWithSchemeSelectQuery().
|
query := s.getTeamMembersWithSchemeSelectQuery().
|
||||||
Where(sq.Eq{"TeamMembers.UserId": userId})
|
Where(sq.Eq{"TeamMembers.UserId": userId})
|
||||||
|
|
||||||
|
if excludeTeamID != "" {
|
||||||
|
query = query.Where(sq.NotEq{"TeamMembers.TeamId": excludeTeamID})
|
||||||
|
}
|
||||||
|
|
||||||
if !includeDeleted {
|
if !includeDeleted {
|
||||||
query = query.Where(sq.Eq{"TeamMembers.DeleteAt": 0})
|
query = query.Where(sq.Eq{"TeamMembers.DeleteAt": 0})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ type TeamStore interface {
|
|||||||
GetMembersByIds(teamID string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, error)
|
GetMembersByIds(teamID string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, error)
|
||||||
GetTotalMemberCount(teamID string, restrictions *model.ViewUsersRestrictions) (int64, error)
|
GetTotalMemberCount(teamID string, restrictions *model.ViewUsersRestrictions) (int64, error)
|
||||||
GetActiveMemberCount(teamID string, restrictions *model.ViewUsersRestrictions) (int64, error)
|
GetActiveMemberCount(teamID string, restrictions *model.ViewUsersRestrictions) (int64, error)
|
||||||
GetTeamsForUser(ctx context.Context, userID string, includeDeleted bool) ([]*model.TeamMember, error)
|
GetTeamsForUser(ctx context.Context, userID, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, error)
|
||||||
GetTeamsForUserWithPagination(userID string, page, perPage int) ([]*model.TeamMember, error)
|
GetTeamsForUserWithPagination(userID string, page, perPage int) ([]*model.TeamMember, error)
|
||||||
GetChannelUnreadsForAllTeams(excludeTeamID, userID string) ([]*model.ChannelUnread, error)
|
GetChannelUnreadsForAllTeams(excludeTeamID, userID string) ([]*model.ChannelUnread, error)
|
||||||
GetChannelUnreadsForTeam(teamID, userID string) ([]*model.ChannelUnread, error)
|
GetChannelUnreadsForTeam(teamID, userID string) ([]*model.ChannelUnread, error)
|
||||||
|
|||||||
@@ -535,13 +535,13 @@ func (_m *TeamStore) GetTeamsByUserId(userID string) ([]*model.Team, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTeamsForUser provides a mock function with given fields: ctx, userID, includeDeleted
|
// GetTeamsForUser provides a mock function with given fields: ctx, userID, excludeTeamID, includeDeleted
|
||||||
func (_m *TeamStore) GetTeamsForUser(ctx context.Context, userID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
func (_m *TeamStore) GetTeamsForUser(ctx context.Context, userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
||||||
ret := _m.Called(ctx, userID, includeDeleted)
|
ret := _m.Called(ctx, userID, excludeTeamID, includeDeleted)
|
||||||
|
|
||||||
var r0 []*model.TeamMember
|
var r0 []*model.TeamMember
|
||||||
if rf, ok := ret.Get(0).(func(context.Context, string, bool) []*model.TeamMember); ok {
|
if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) []*model.TeamMember); ok {
|
||||||
r0 = rf(ctx, userID, includeDeleted)
|
r0 = rf(ctx, userID, excludeTeamID, includeDeleted)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]*model.TeamMember)
|
r0 = ret.Get(0).([]*model.TeamMember)
|
||||||
@@ -549,8 +549,8 @@ func (_m *TeamStore) GetTeamsForUser(ctx context.Context, userID string, include
|
|||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(context.Context, string, bool) error); ok {
|
if rf, ok := ret.Get(1).(func(context.Context, string, string, bool) error); ok {
|
||||||
r1 = rf(ctx, userID, includeDeleted)
|
r1 = rf(ctx, userID, excludeTeamID, includeDeleted)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1318,7 +1318,7 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
|||||||
require.Equal(t, m3.UserId, ms[0].UserId)
|
require.Equal(t, m3.UserId, ms[0].UserId)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ms, err = ss.Team().GetTeamsForUser(ctx, m1.UserId, true)
|
ms, err = ss.Team().GetTeamsForUser(ctx, m1.UserId, "", true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, ms, 1)
|
require.Len(t, ms, 1)
|
||||||
require.Equal(t, m1.TeamId, ms[0].TeamId)
|
require.Equal(t, m1.TeamId, ms[0].TeamId)
|
||||||
@@ -1347,26 +1347,30 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
|||||||
_, nErr = ss.Team().SaveMultipleMembers([]*model.TeamMember{m4, m5}, -1)
|
_, nErr = ss.Team().SaveMultipleMembers([]*model.TeamMember{m4, m5}, -1)
|
||||||
require.NoError(t, nErr)
|
require.NoError(t, nErr)
|
||||||
|
|
||||||
ms, err = ss.Team().GetTeamsForUser(ctx, uid, true)
|
ms, err = ss.Team().GetTeamsForUser(ctx, uid, "", true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, ms, 2)
|
require.Len(t, ms, 2)
|
||||||
|
|
||||||
|
ms, err = ss.Team().GetTeamsForUser(ctx, uid, teamId2, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, ms, 1)
|
||||||
|
|
||||||
m4.DeleteAt = model.GetMillis()
|
m4.DeleteAt = model.GetMillis()
|
||||||
_, err = ss.Team().UpdateMember(m4)
|
_, err = ss.Team().UpdateMember(m4)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ms, err = ss.Team().GetTeamsForUser(ctx, uid, true)
|
ms, err = ss.Team().GetTeamsForUser(ctx, uid, "", true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, ms, 2)
|
require.Len(t, ms, 2)
|
||||||
|
|
||||||
ms, err = ss.Team().GetTeamsForUser(ctx, uid, false)
|
ms, err = ss.Team().GetTeamsForUser(ctx, uid, "", false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, ms, 1)
|
require.Len(t, ms, 1)
|
||||||
|
|
||||||
nErr = ss.Team().RemoveAllMembersByUser(uid)
|
nErr = ss.Team().RemoveAllMembersByUser(uid)
|
||||||
require.NoError(t, nErr)
|
require.NoError(t, nErr)
|
||||||
|
|
||||||
ms, err = ss.Team().GetTeamsForUser(ctx, m1.UserId, true)
|
ms, err = ss.Team().GetTeamsForUser(ctx, m1.UserId, "", true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Empty(t, ms)
|
require.Empty(t, ms)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7944,10 +7944,10 @@ func (s *TimerLayerTeamStore) GetTeamsByUserId(userID string) ([]*model.Team, er
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TimerLayerTeamStore) GetTeamsForUser(ctx context.Context, userID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
func (s *TimerLayerTeamStore) GetTeamsForUser(ctx context.Context, userID string, excludeTeamID string, includeDeleted bool) ([]*model.TeamMember, error) {
|
||||||
start := timemodule.Now()
|
start := timemodule.Now()
|
||||||
|
|
||||||
result, err := s.TeamStore.GetTeamsForUser(ctx, userID, includeDeleted)
|
result, err := s.TeamStore.GetTeamsForUser(ctx, userID, excludeTeamID, includeDeleted)
|
||||||
|
|
||||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||||
if s.Root.Metrics != nil {
|
if s.Root.Metrics != nil {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user