diff --git a/api4/channel.go b/api4/channel.go index 559d68c81d..1be513b2b0 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -1218,6 +1218,11 @@ func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { return } + if channel.GroupConstrained != nil && *channel.GroupConstrained && (c.Params.UserId != c.App.Session.UserId) { + c.Err = model.NewAppError("removeChannelMember", "api.channel.remove_member.group_constrained.app_error", nil, "", http.StatusBadRequest) + return + } + if c.Params.UserId != c.App.Session.UserId { if channel.Type == model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.App.Session, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) { c.SetPermissionError(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) diff --git a/api4/channel_test.go b/api4/channel_test.go index ec0a43acbf..974426dc06 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -2228,6 +2228,20 @@ func TestRemoveChannelMember(t *testing.T) { _, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id) CheckNoError(t, resp) + _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, th.SystemAdminUser.Id) + CheckNoError(t, resp) + + // If the channel is group-constrained the user cannot be removed + privateChannel.GroupConstrained = model.NewBool(true) + _, err := th.App.UpdateChannel(privateChannel) + require.Nil(t, err) + _, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id) + require.Equal(t, "api.channel.remove_member.group_constrained.app_error", resp.Error.Id) + + // If the channel is group-constrained user can remove self + _, resp = th.SystemAdminClient.RemoveUserFromChannel(privateChannel.Id, th.SystemAdminUser.Id) + CheckNoError(t, resp) + // Test on preventing removal of user from a direct channel directChannel, resp := Client.CreateDirectChannel(user1.Id, user2.Id) CheckNoError(t, resp) diff --git a/api4/team.go b/api4/team.go index 2af116c987..cf0fad7b16 100644 --- a/api4/team.go +++ b/api4/team.go @@ -535,6 +535,17 @@ func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { } } + team, err := c.App.GetTeam(c.Params.TeamId) + if err != nil { + c.Err = err + return + } + + if team.GroupConstrained != nil && *team.GroupConstrained && (c.Params.UserId != c.App.Session.UserId) { + c.Err = model.NewAppError("removeTeamMember", "api.team.remove_member.group_constrained.app_error", nil, "", http.StatusBadRequest) + return + } + if err := c.App.RemoveUserFromTeam(c.Params.TeamId, c.Params.UserId, c.App.Session.UserId); err != nil { c.Err = err return diff --git a/api4/team_test.go b/api4/team_test.go index 1ee68eac43..bc21578b90 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -1712,6 +1712,20 @@ func TestRemoveTeamMember(t *testing.T) { _, resp = th.SystemAdminClient.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser.Id) CheckNoError(t, resp) + + _, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, th.SystemAdminUser.Id) + CheckNoError(t, resp) + + // If the team is group-constrained the user cannot be removed + th.BasicTeam.GroupConstrained = model.NewBool(true) + _, err := th.App.UpdateTeam(th.BasicTeam) + require.Nil(t, err) + _, resp = th.SystemAdminClient.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser.Id) + require.Equal(t, "api.team.remove_member.group_constrained.app_error", resp.Error.Id) + + // Can remove self even if team is group-constrained + _, resp = th.SystemAdminClient.RemoveTeamMember(th.BasicTeam.Id, th.SystemAdminUser.Id) + CheckNoError(t, resp) } func TestGetTeamStats(t *testing.T) { diff --git a/i18n/en.json b/i18n/en.json index 24ef8e01fe..adcdfeabe5 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -295,6 +295,10 @@ "id": "api.channel.remove_channel_member.type.app_error", "translation": "Unable to remove user from a channel." }, + { + "id": "api.channel.remove_member.group_constrained.app_error", + "translation": "Unable to remove a user from a group-constrained channel." + }, { "id": "api.channel.remove_member.removed", "translation": "%v removed from the channel." @@ -1846,6 +1850,10 @@ "id": "api.team.move_channel.success", "translation": "This channel has been moved to this team from %v." }, + { + "id": "api.team.remove_member.group_constrained.app_error", + "translation": "Unable to remove a user from a group-constrained team." + }, { "id": "api.team.remove_team_icon.get_team.app_error", "translation": "An error occurred getting the team"