MM-23015: Enable or disable group mentions (#14010)

* MM-23015: Enable or disable group mentions + show them in suggestion list


Co-authored-by: Catalin Tomai <catalin.tomai@mattermost.com>
This commit is contained in:
catalintomai
2020-04-13 11:37:29 -07:00
committed by GitHub
parent 0bfb063c78
commit b90f4f46e2
15 changed files with 777 additions and 102 deletions

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/mattermost/mattermost-server/v5/audit"
"github.com/mattermost/mattermost-server/v5/model"
@@ -61,6 +62,10 @@ func (api *API) InitGroup() {
// GET /api/v4/teams/:team_id/groups?page=0&per_page=100
api.BaseRoutes.Teams.Handle("/{team_id:[A-Za-z0-9]+}/groups",
api.ApiSessionRequired(getGroupsByTeam)).Methods("GET")
// GET /api/v4/teams/:team_id/groups_by_channels?page=0&per_page=100
api.BaseRoutes.Teams.Handle("/{team_id:[A-Za-z0-9]+}/groups_by_channels",
api.ApiSessionRequired(getGroupsAssociatedToChannelsByTeam)).Methods("GET")
}
func getGroup(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -126,6 +131,13 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) {
}
auditRec.AddMeta("group", group)
if groupPatch.AllowReference != nil && *groupPatch.AllowReference {
tmp := model.NewId()
if groupPatch.Name == nil {
tmp = strings.ReplaceAll(strings.ToLower(group.DisplayName), " ", "-")
}
groupPatch.Name = &tmp
}
group.Patch(groupPatch)
group, err = c.App.UpdateGroup(group)
@@ -521,8 +533,9 @@ func getGroupsByChannel(c *Context, w http.ResponseWriter, r *http.Request) {
}
opts := model.GroupSearchOpts{
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
FilterAllowReference: c.Params.FilterAllowReference,
}
if c.Params.Paginate == nil || *c.Params.Paginate {
opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage}
@@ -561,14 +574,10 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
return
}
opts := model.GroupSearchOpts{
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
FilterAllowReference: c.Params.FilterAllowReference,
}
if c.Params.Paginate == nil || *c.Params.Paginate {
opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage}
@@ -596,6 +605,46 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write(b)
}
func getGroupsAssociatedToChannelsByTeam(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireTeamId()
if c.Err != nil {
return
}
if c.App.License() == nil || !*c.App.License().Features.LDAPGroups {
c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented)
return
}
opts := model.GroupSearchOpts{
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
FilterAllowReference: c.Params.FilterAllowReference,
}
if c.Params.Paginate == nil || *c.Params.Paginate {
opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage}
}
groupsAssociatedByChannelID, err := c.App.GetGroupsAssociatedToChannelsByTeam(c.Params.TeamId, opts)
if err != nil {
c.Err = err
return
}
b, marshalErr := json.Marshal(struct {
GroupsAssociatedToChannels map[string][]*model.GroupWithSchemeAdmin `json:"groups"`
}{
GroupsAssociatedToChannels: groupsAssociatedByChannelID,
})
if marshalErr != nil {
c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
return
}
w.Write(b)
}
func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.License() == nil || !*c.App.License().Features.LDAPGroups {
c.Err = model.NewAppError("Api4.getGroups", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented)
@@ -611,14 +660,10 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
channelID = id
}
if teamID == "" && channelID == "" && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
return
}
opts := model.GroupSearchOpts{
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
Q: c.Params.Q,
IncludeMemberCount: c.Params.IncludeMemberCount,
FilterAllowReference: c.Params.FilterAllowReference,
}
if teamID != "" {
@@ -627,10 +672,7 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = err
return
}
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), teamID, model.PERMISSION_MANAGE_TEAM) {
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
return
}
opts.NotAssociatedToTeam = teamID
}

View File

@@ -711,6 +711,80 @@ func TestGetGroupsByChannel(t *testing.T) {
assert.Empty(t, groups)
}
func TestGetGroupsAssociatedToChannelsByTeam(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
id := model.NewId()
group, err := th.App.CreateGroup(&model.Group{
DisplayName: "dn_" + id,
Name: "name" + id,
Source: model.GroupSourceLdap,
Description: "description_" + id,
RemoteId: model.NewId(),
})
assert.Nil(t, err)
groupSyncable, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
AutoAdd: true,
SyncableId: th.BasicChannel.Id,
Type: model.GroupSyncableTypeChannel,
GroupId: group.Id,
})
assert.Nil(t, err)
opts := model.GroupSearchOpts{
PageOpts: &model.PageOpts{
Page: 0,
PerPage: 60,
},
}
_, response := th.SystemAdminClient.GetGroupsAssociatedToChannelsByTeam("asdfasdf", opts)
CheckBadRequestStatus(t, response)
th.App.SetLicense(nil)
_, response = th.SystemAdminClient.GetGroupsAssociatedToChannelsByTeam(th.BasicTeam.Id, opts)
CheckNotImplementedStatus(t, response)
th.App.SetLicense(model.NewTestLicense("ldap"))
groups, response := th.SystemAdminClient.GetGroupsAssociatedToChannelsByTeam(th.BasicTeam.Id, opts)
assert.Nil(t, response.Error)
assert.Equal(t, map[string][]*model.GroupWithSchemeAdmin{
th.BasicChannel.Id: {
{Group: *group, SchemeAdmin: model.NewBool(false)},
},
}, groups)
require.NotNil(t, groups[th.BasicChannel.Id][0].SchemeAdmin)
require.False(t, *groups[th.BasicChannel.Id][0].SchemeAdmin)
// set syncable to true
groupSyncable.SchemeAdmin = true
_, err = th.App.UpdateGroupSyncable(groupSyncable)
require.Nil(t, err)
// ensure that SchemeAdmin field is updated
groups, response = th.SystemAdminClient.GetGroupsAssociatedToChannelsByTeam(th.BasicTeam.Id, opts)
assert.Nil(t, response.Error)
assert.Equal(t, map[string][]*model.GroupWithSchemeAdmin{
th.BasicChannel.Id: {
{Group: *group, SchemeAdmin: model.NewBool(true)},
},
}, groups)
require.NotNil(t, groups[th.BasicChannel.Id][0].SchemeAdmin)
require.True(t, *groups[th.BasicChannel.Id][0].SchemeAdmin)
groups, response = th.SystemAdminClient.GetGroupsAssociatedToChannelsByTeam(model.NewId(), opts)
assert.Nil(t, response.Error)
assert.Empty(t, groups)
}
func TestGetGroupsByTeam(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
@@ -750,9 +824,6 @@ func TestGetGroupsByTeam(t *testing.T) {
th.App.SetLicense(model.NewTestLicense("ldap"))
_, _, response = th.Client.GetGroupsByTeam(th.BasicTeam.Id, opts)
CheckForbiddenStatus(t, response)
groups, _, response := th.SystemAdminClient.GetGroupsByTeam(th.BasicTeam.Id, opts)
assert.Nil(t, response.Error)
assert.ElementsMatch(t, []*model.GroupWithSchemeAdmin{{Group: *group, SchemeAdmin: model.NewBool(false)}}, groups)
@@ -812,9 +883,6 @@ func TestGetGroups(t *testing.T) {
opts.NotAssociatedToChannel = th.BasicChannel.Id
_, response = th.Client.GetGroups(opts)
CheckForbiddenStatus(t, response)
_, response = th.SystemAdminClient.UpdateChannelRoles(th.BasicChannel.Id, th.BasicUser.Id, "channel_user channel_admin")
require.Nil(t, response.Error)
@@ -837,17 +905,10 @@ func TestGetGroups(t *testing.T) {
require.Nil(t, response.Error)
opts.NotAssociatedToTeam = th.BasicTeam.Id
_, response = th.Client.GetGroups(opts)
CheckForbiddenStatus(t, response)
_, response = th.SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, "team_user team_admin")
require.Nil(t, response.Error)
_, response = th.Client.GetGroups(opts)
assert.Nil(t, response.Error)
opts.NotAssociatedToTeam = ""
opts.NotAssociatedToChannel = ""
_, response = th.Client.GetGroups(opts)
CheckForbiddenStatus(t, response)
}