коммит произвёл
GitHub
родитель
43e797010b
Коммит
3b1b8d9114
@@ -2071,8 +2071,16 @@ func TestGetGroups(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("not associated to channel", func(t *testing.T) {
|
t.Run("not associated to channel", func(t *testing.T) {
|
||||||
opts := baseOpts
|
opts := baseOpts
|
||||||
|
resp, err := th.SystemAdminClient.UpdateChannelRoles(context.Background(), th.BasicChannel.Id, th.BasicUser.Id, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckOKStatus(t, resp)
|
||||||
|
|
||||||
opts.NotAssociatedToChannel = th.BasicChannel.Id
|
opts.NotAssociatedToChannel = th.BasicChannel.Id
|
||||||
|
|
||||||
|
resp, err = th.SystemAdminClient.UpdateChannelRoles(context.Background(), th.BasicChannel.Id, th.BasicUser.Id, "channel_user channel_admin")
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckOKStatus(t, resp)
|
||||||
|
|
||||||
groups, resp, err := th.SystemAdminClient.GetGroups(context.Background(), opts)
|
groups, resp, err := th.SystemAdminClient.GetGroups(context.Background(), opts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
CheckOKStatus(t, resp)
|
CheckOKStatus(t, resp)
|
||||||
@@ -2081,8 +2089,16 @@ func TestGetGroups(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("not associated to team", func(t *testing.T) {
|
t.Run("not associated to team", func(t *testing.T) {
|
||||||
opts := baseOpts
|
opts := baseOpts
|
||||||
|
resp, err := th.SystemAdminClient.UpdateTeamMemberRoles(context.Background(), th.BasicTeam.Id, th.BasicUser.Id, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckOKStatus(t, resp)
|
||||||
|
|
||||||
opts.NotAssociatedToTeam = th.BasicTeam.Id
|
opts.NotAssociatedToTeam = th.BasicTeam.Id
|
||||||
|
|
||||||
|
resp, err = th.SystemAdminClient.UpdateTeamMemberRoles(context.Background(), th.BasicTeam.Id, th.BasicUser.Id, "team_user team_admin")
|
||||||
|
require.NoError(t, err)
|
||||||
|
CheckOKStatus(t, resp)
|
||||||
|
|
||||||
groups, resp, err := th.SystemAdminClient.GetGroups(context.Background(), opts)
|
groups, resp, err := th.SystemAdminClient.GetGroups(context.Background(), opts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
CheckOKStatus(t, resp)
|
CheckOKStatus(t, resp)
|
||||||
|
|||||||
@@ -127,6 +127,12 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't sanitize the team here since the user will be a team admin and their session won't reflect that yet
|
// Don't sanitize the team here since the user will be a team admin and their session won't reflect that yet
|
||||||
|
// instead check the scheme roles for the team and if the user has the permission to invite users
|
||||||
|
_, schemeUserRole, schemeAdminRole, schemeErr := c.App.GetSchemeRolesForTeam(rteam.Id)
|
||||||
|
if schemeErr != nil || !c.App.RolesGrantPermission([]string{schemeUserRole, schemeAdminRole}, model.PermissionInviteUser.Id) {
|
||||||
|
// If we can't check permissions, fail secure by hiding the invite_id because the team is already created above
|
||||||
|
rteam.InviteId = ""
|
||||||
|
}
|
||||||
|
|
||||||
auditRec.Success()
|
auditRec.Success()
|
||||||
auditRec.AddEventResultState(&team)
|
auditRec.AddEventResultState(&team)
|
||||||
|
|||||||
@@ -236,6 +236,29 @@ func TestCreateTeamSanitization(t *testing.T) {
|
|||||||
}, "system admin")
|
}, "system admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateTeamInviteIdHiddenWithoutInvitePermission(t *testing.T) {
|
||||||
|
th := Setup(t)
|
||||||
|
|
||||||
|
defaultRolePermissions := th.SaveDefaultRolePermissions()
|
||||||
|
defer th.RestoreDefaultRolePermissions(defaultRolePermissions)
|
||||||
|
|
||||||
|
// Remove PermissionInviteUser from the default team user role
|
||||||
|
th.RemovePermissionFromRole(model.PermissionInviteUser.Id, model.TeamUserRoleId)
|
||||||
|
|
||||||
|
// Regular user creates a team - InviteId should be hidden
|
||||||
|
// since the team user role lacks invite permission
|
||||||
|
rteam, _, err := th.Client.CreateTeam(context.Background(), &model.Team{
|
||||||
|
DisplayName: "Team Without Invite Permission",
|
||||||
|
Name: GenerateTestTeamName(),
|
||||||
|
Email: th.GenerateTestEmail(),
|
||||||
|
Type: model.TeamOpen,
|
||||||
|
AllowedDomains: "simulator.amazonses.com,localhost",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, rteam.Email, "should not have sanitized email")
|
||||||
|
require.Empty(t, rteam.InviteId, "should have hidden invite_id when user lacks invite permission")
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetTeam(t *testing.T) {
|
func TestGetTeam(t *testing.T) {
|
||||||
mainHelper.Parallel(t)
|
mainHelper.Parallel(t)
|
||||||
th := Setup(t).InitBasic()
|
th := Setup(t).InitBasic()
|
||||||
|
|||||||
@@ -1251,29 +1251,14 @@ func buildChannelModerations(c request.CTX, channelType model.ChannelType, membe
|
|||||||
return channelModerations
|
return channelModerations
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateChannelMemberRoles updates the roles for a channel member.
|
func (a *App) UpdateChannelMemberRoles(c request.CTX, channelID string, userID string, newRoles string) (*model.ChannelMember, *model.AppError) {
|
||||||
// This is the public API used by REST endpoints and plugins.
|
|
||||||
// It enforces strict validation requiring either SchemeUser or SchemeGuest to be true.
|
|
||||||
func (a *App) UpdateChannelMemberRoles(rctx request.CTX, channelID string, userID string, newRoles string) (*model.ChannelMember, *model.AppError) {
|
|
||||||
return a.updateChannelMemberRolesInternal(rctx, channelID, userID, newRoles, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateChannelMemberRolesInternal is the internal implementation of UpdateChannelMemberRoles.
|
|
||||||
// The allowSchemeUserUnset parameter controls whether to enforce the requirement that members
|
|
||||||
// must have either SchemeUser or SchemeGuest set to true.
|
|
||||||
//
|
|
||||||
// When allowSchemeUserUnset is false (default for API/plugin calls), the function enforces
|
|
||||||
// that members must have a base scheme role. When true (bulk import only), this validation
|
|
||||||
// is skipped to support the two-phase import pattern where explicit roles are set first,
|
|
||||||
// then scheme roles are set via UpdateChannelMemberSchemeRoles immediately after.
|
|
||||||
func (a *App) updateChannelMemberRolesInternal(rctx request.CTX, channelID string, userID string, newRoles string, allowSchemeUserUnset bool) (*model.ChannelMember, *model.AppError) {
|
|
||||||
var member *model.ChannelMember
|
var member *model.ChannelMember
|
||||||
var err *model.AppError
|
var err *model.AppError
|
||||||
if member, err = a.GetChannelMember(rctx, channelID, userID); err != nil {
|
if member, err = a.GetChannelMember(c, channelID, userID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
schemeGuestRole, schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(rctx, channelID)
|
schemeGuestRole, schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(c, channelID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1320,16 +1305,9 @@ func (a *App) updateChannelMemberRolesInternal(rctx request.CTX, channelID strin
|
|||||||
return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.changing_guest_role.app_error", nil, "", http.StatusBadRequest)
|
return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.changing_guest_role.app_error", nil, "", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that the member has a base scheme role (SchemeUser or SchemeGuest).
|
|
||||||
// This ensures members always have the minimum required permissions.
|
|
||||||
// Bulk import operations may skip this validation temporarily.
|
|
||||||
if !allowSchemeUserUnset && !member.SchemeGuest && !member.SchemeUser {
|
|
||||||
return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.unset_user_scheme.app_error", nil, "", http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
|
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
|
||||||
|
|
||||||
return a.updateChannelMember(rctx, member)
|
return a.updateChannelMember(c, member)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) UpdateChannelMemberSchemeRoles(c request.CTX, channelID string, userID string, isSchemeGuest bool, isSchemeUser bool, isSchemeAdmin bool) (*model.ChannelMember, *model.AppError) {
|
func (a *App) UpdateChannelMemberSchemeRoles(c request.CTX, channelID string, userID string, isSchemeGuest bool, isSchemeUser bool, isSchemeAdmin bool) (*model.ChannelMember, *model.AppError) {
|
||||||
|
|||||||
@@ -1631,82 +1631,6 @@ func TestUpdateChannelMemberRolesChangingGuest(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateChannelMemberRolesRequireUser(t *testing.T) {
|
|
||||||
mainHelper.Parallel(t)
|
|
||||||
th := Setup(t).InitBasic()
|
|
||||||
|
|
||||||
t.Run("empty roles string requires user or guest scheme role", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
_, appErr = th.App.AddUserToChannel(th.Context, ruser, th.BasicChannel, false)
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
member, appErr := th.App.GetChannelMember(th.Context, th.BasicChannel.Id, ruser.Id)
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
require.True(t, member.SchemeUser)
|
|
||||||
require.False(t, member.SchemeGuest)
|
|
||||||
|
|
||||||
_, appErr = th.App.UpdateChannelMemberRoles(th.Context, th.BasicChannel.Id, ruser.Id, "")
|
|
||||||
require.NotNil(t, appErr)
|
|
||||||
require.Equal(t, "api.channel.update_channel_member_roles.unset_user_scheme.app_error", appErr.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("admin role requires user or guest scheme role", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
_, appErr = th.App.AddUserToChannel(th.Context, ruser, th.BasicChannel, false)
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
_, appErr = th.App.UpdateChannelMemberRoles(th.Context, th.BasicChannel.Id, ruser.Id, "channel_admin")
|
|
||||||
require.NotNil(t, appErr)
|
|
||||||
require.Equal(t, "api.channel.update_channel_member_roles.unset_user_scheme.app_error", appErr.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("valid user and admin roles update succeeds", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
_, appErr = th.App.AddUserToChannel(th.Context, ruser, th.BasicChannel, false)
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
updatedMember, appErr := th.App.UpdateChannelMemberRoles(th.Context, th.BasicChannel.Id, ruser.Id, "channel_user channel_admin")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.True(t, updatedMember.SchemeAdmin)
|
|
||||||
require.False(t, updatedMember.SchemeGuest)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("removing admin role while keeping user role succeeds", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, appErr := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
_, appErr = th.App.AddUserToChannel(th.Context, ruser, th.BasicChannel, false)
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
_, appErr = th.App.UpdateChannelMemberRoles(th.Context, th.BasicChannel.Id, ruser.Id, "channel_user channel_admin")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
|
|
||||||
updatedMember, appErr := th.App.UpdateChannelMemberRoles(th.Context, th.BasicChannel.Id, ruser.Id, "channel_user")
|
|
||||||
require.Nil(t, appErr)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.False(t, updatedMember.SchemeAdmin)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDefaultChannelNames(t *testing.T) {
|
func TestDefaultChannelNames(t *testing.T) {
|
||||||
mainHelper.Parallel(t)
|
mainHelper.Parallel(t)
|
||||||
th := Setup(t)
|
th := Setup(t)
|
||||||
|
|||||||
@@ -1117,8 +1117,7 @@ func (a *App) importUserTeams(rctx request.CTX, user *model.User, data *[]import
|
|||||||
|
|
||||||
for _, member := range append(newMembers, oldMembers...) {
|
for _, member := range append(newMembers, oldMembers...) {
|
||||||
if member.ExplicitRoles != rolesByTeamID[member.TeamId] {
|
if member.ExplicitRoles != rolesByTeamID[member.TeamId] {
|
||||||
// Bulk import uses internal function to support two-phase role updates.
|
if _, appErr = a.UpdateTeamMemberRoles(rctx, member.TeamId, user.Id, rolesByTeamID[member.TeamId]); appErr != nil {
|
||||||
if _, appErr = a.updateTeamMemberRolesInternal(rctx, member.TeamId, user.Id, rolesByTeamID[member.TeamId], true); appErr != nil {
|
|
||||||
return appErr
|
return appErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1310,8 +1309,7 @@ func (a *App) importUserChannels(rctx request.CTX, user *model.User, team *model
|
|||||||
|
|
||||||
for _, member := range append(newMembers, oldMembers...) {
|
for _, member := range append(newMembers, oldMembers...) {
|
||||||
if member.ExplicitRoles != rolesByChannelId[member.ChannelId] {
|
if member.ExplicitRoles != rolesByChannelId[member.ChannelId] {
|
||||||
// Bulk import uses internal function to support two-phase role updates.
|
if _, err = a.UpdateChannelMemberRoles(rctx, member.ChannelId, user.Id, rolesByChannelId[member.ChannelId]); err != nil {
|
||||||
if _, err = a.updateChannelMemberRolesInternal(rctx, member.ChannelId, user.Id, rolesByChannelId[member.ChannelId], true); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -375,6 +375,7 @@ func (a *App) sendTeamEvent(team *model.Team, event model.WebsocketEventType) *m
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSchemeRolesForTeam Gets the scheme roles for a team, they may be empty, default or custom permissions based on the scheme.
|
||||||
func (a *App) GetSchemeRolesForTeam(teamID string) (string, string, string, *model.AppError) {
|
func (a *App) GetSchemeRolesForTeam(teamID string) (string, string, string, *model.AppError) {
|
||||||
team, err := a.GetTeam(teamID)
|
team, err := a.GetTeam(teamID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -392,23 +393,8 @@ func (a *App) GetSchemeRolesForTeam(teamID string) (string, string, string, *mod
|
|||||||
return model.TeamGuestRoleId, model.TeamUserRoleId, model.TeamAdminRoleId, nil
|
return model.TeamGuestRoleId, model.TeamUserRoleId, model.TeamAdminRoleId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateTeamMemberRoles updates the roles for a team member.
|
func (a *App) UpdateTeamMemberRoles(c request.CTX, teamID string, userID string, newRoles string) (*model.TeamMember, *model.AppError) {
|
||||||
// This is the public API used by REST endpoints and plugins.
|
member, nErr := a.Srv().Store().Team().GetMember(c, teamID, userID)
|
||||||
// It enforces strict validation requiring either SchemeUser or SchemeGuest to be true.
|
|
||||||
func (a *App) UpdateTeamMemberRoles(rctx request.CTX, teamID string, userID string, newRoles string) (*model.TeamMember, *model.AppError) {
|
|
||||||
return a.updateTeamMemberRolesInternal(rctx, teamID, userID, newRoles, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateTeamMemberRolesInternal is the internal implementation of UpdateTeamMemberRoles.
|
|
||||||
// The allowSchemeUserUnset parameter controls whether to enforce the requirement that members
|
|
||||||
// must have either SchemeUser or SchemeGuest set to true.
|
|
||||||
//
|
|
||||||
// When allowSchemeUserUnset is false (default for API/plugin calls), the function enforces
|
|
||||||
// that members must have a base scheme role. When true (bulk import only), this validation
|
|
||||||
// is skipped to support the two-phase import pattern where explicit roles are set first,
|
|
||||||
// then scheme roles are set via UpdateTeamMemberSchemeRoles immediately after.
|
|
||||||
func (a *App) updateTeamMemberRolesInternal(rctx request.CTX, teamID string, userID string, newRoles string, allowSchemeUserUnset bool) (*model.TeamMember, *model.AppError) {
|
|
||||||
member, nErr := a.Srv().Store().Team().GetMember(rctx, teamID, userID)
|
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
var nfErr *store.ErrNotFound
|
var nfErr *store.ErrNotFound
|
||||||
switch {
|
switch {
|
||||||
@@ -469,16 +455,9 @@ func (a *App) updateTeamMemberRolesInternal(rctx request.CTX, teamID string, use
|
|||||||
return nil, model.NewAppError("UpdateTeamMemberRoles", "api.channel.update_team_member_roles.changing_guest_role.app_error", nil, "", http.StatusBadRequest)
|
return nil, model.NewAppError("UpdateTeamMemberRoles", "api.channel.update_team_member_roles.changing_guest_role.app_error", nil, "", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that the member has a base scheme role (SchemeUser or SchemeGuest).
|
|
||||||
// This ensures members always have the minimum required permissions.
|
|
||||||
// Bulk import operations may skip this validation temporarily.
|
|
||||||
if !allowSchemeUserUnset && !member.SchemeGuest && !member.SchemeUser {
|
|
||||||
return nil, model.NewAppError("UpdateTeamMemberRoles", "api.team.update_team_member_roles.unset_user_scheme.app_error", nil, "", http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
|
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
|
||||||
|
|
||||||
member, nErr = a.Srv().Store().Team().UpdateMember(rctx, member)
|
member, nErr = a.Srv().Store().Team().UpdateMember(c, member)
|
||||||
if nErr != nil {
|
if nErr != nil {
|
||||||
var appErr *model.AppError
|
var appErr *model.AppError
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -1436,184 +1436,6 @@ func TestUpdateTeamMemberRolesChangingGuest(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateTeamMemberRolesRequireUser(t *testing.T) {
|
|
||||||
mainHelper.Parallel(t)
|
|
||||||
th := Setup(t).InitBasic()
|
|
||||||
|
|
||||||
t.Run("empty roles string requires user or guest scheme role", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
member, err := th.App.GetTeamMember(th.Context, th.BasicTeam.Id, ruser.Id)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, member.SchemeUser)
|
|
||||||
require.False(t, member.SchemeGuest)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("admin role requires user or guest scheme role", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_admin")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("valid user and admin roles update succeeds", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
updatedMember, err := th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user team_admin")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.True(t, updatedMember.SchemeAdmin)
|
|
||||||
require.False(t, updatedMember.SchemeGuest)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("removing admin role while keeping user role succeeds", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user team_admin")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
updatedMember, err := th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.False(t, updatedMember.SchemeAdmin)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("team_post_all alone should fail", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_post_all")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("team_post_all_public alone should fail", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_post_all_public")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("system_post_all alone should fail", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "system_post_all")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("system_user_manager alone should fail", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "system_user_manager")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("multiple non-scheme-managed roles without user scheme should fail", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
_, err = th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_post_all team_post_all_public system_post_all")
|
|
||||||
require.NotNil(t, err)
|
|
||||||
require.Equal(t, "api.team.update_team_member_roles.unset_user_scheme.app_error", err.Id)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("team_post_all with team_user should succeed", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
updatedMember, err := th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user team_post_all")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.Contains(t, updatedMember.ExplicitRoles, "team_post_all")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("team_post_all_public with team_user should succeed", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
updatedMember, err := th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user team_post_all_public")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.Contains(t, updatedMember.ExplicitRoles, "team_post_all_public")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("multiple explicit roles with team_user should succeed", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
updatedMember, err := th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user team_post_all team_post_all_public")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.Contains(t, updatedMember.ExplicitRoles, "team_post_all")
|
|
||||||
require.Contains(t, updatedMember.ExplicitRoles, "team_post_all_public")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("explicit role with admin should succeed", func(t *testing.T) {
|
|
||||||
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Tester", Username: "tester" + model.NewId(), Password: "passwd1", AuthService: ""}
|
|
||||||
ruser, _ := th.App.CreateUser(th.Context, &user)
|
|
||||||
|
|
||||||
_, _, err := th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, ruser.Id, "")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
updatedMember, err := th.App.UpdateTeamMemberRoles(th.Context, th.BasicTeam.Id, ruser.Id, "team_user team_admin team_post_all")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, updatedMember.SchemeUser)
|
|
||||||
require.True(t, updatedMember.SchemeAdmin)
|
|
||||||
require.Contains(t, updatedMember.ExplicitRoles, "team_post_all")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInvalidateAllResendInviteEmailJobs(t *testing.T) {
|
func TestInvalidateAllResendInviteEmailJobs(t *testing.T) {
|
||||||
mainHelper.Parallel(t)
|
mainHelper.Parallel(t)
|
||||||
th := Setup(t)
|
th := Setup(t)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user