[MM-27622] Publish messages as SystemBot when a user is required (#17598)
Automatic Merge
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c6d94c8696
Коммит
72c86448b9
@@ -6,6 +6,7 @@ package api4
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/app"
|
||||
"github.com/mattermost/mattermost-server/v5/audit"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
)
|
||||
@@ -18,6 +19,8 @@ func (api *API) InitChannelLocal() {
|
||||
api.BaseRoutes.Channel.Handle("", api.ApiLocal(localDeleteChannel)).Methods("DELETE")
|
||||
api.BaseRoutes.Channel.Handle("/patch", api.ApiLocal(localPatchChannel)).Methods("PUT")
|
||||
api.BaseRoutes.Channel.Handle("/move", api.ApiLocal(localMoveChannel)).Methods("POST")
|
||||
api.BaseRoutes.Channel.Handle("/privacy", api.ApiLocal(localUpdateChannelPrivacy)).Methods("PUT")
|
||||
api.BaseRoutes.Channel.Handle("/restore", api.ApiLocal(localRestoreChannel)).Methods("POST")
|
||||
|
||||
api.BaseRoutes.ChannelMember.Handle("", api.ApiLocal(localRemoveChannelMember)).Methods("DELETE")
|
||||
api.BaseRoutes.ChannelMember.Handle("", api.ApiLocal(getChannelMember)).Methods("GET")
|
||||
@@ -57,6 +60,76 @@ func localCreateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(sc.ToJson()))
|
||||
}
|
||||
|
||||
func localUpdateChannelPrivacy(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireChannelId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
props := model.StringInterfaceFromJson(r.Body)
|
||||
privacy, ok := props["privacy"].(string)
|
||||
if !ok || (privacy != model.CHANNEL_OPEN && privacy != model.CHANNEL_PRIVATE) {
|
||||
c.SetInvalidParam("privacy")
|
||||
return
|
||||
}
|
||||
|
||||
channel, err := c.App.GetChannel(c.Params.ChannelId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("localUpdateChannelPrivacy", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("channel", channel)
|
||||
auditRec.AddMeta("new_type", privacy)
|
||||
|
||||
if channel.Name == model.DEFAULT_CHANNEL && privacy == model.CHANNEL_PRIVATE {
|
||||
c.Err = model.NewAppError("updateChannelPrivacy", "api.channel.update_channel_privacy.default_channel_error", nil, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
channel.Type = privacy
|
||||
|
||||
updatedChannel, err := c.App.UpdateChannelPrivacy(c.AppContext, channel, nil)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
c.LogAudit("name=" + updatedChannel.Name)
|
||||
|
||||
w.Write([]byte(updatedChannel.ToJson()))
|
||||
}
|
||||
|
||||
func localRestoreChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireChannelId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
channel, err := c.App.GetChannel(c.Params.ChannelId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("localRestoreChannel", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("channel", channel)
|
||||
|
||||
channel, err = c.App.RestoreChannel(c.AppContext, channel, "")
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
c.LogAudit("name=" + channel.Name)
|
||||
|
||||
w.Write([]byte(channel.ToJson()))
|
||||
}
|
||||
|
||||
func localAddChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireChannelId()
|
||||
if c.Err != nil {
|
||||
@@ -70,13 +143,30 @@ func localAddChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := c.App.GetUser(userId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
member := &model.ChannelMember{
|
||||
ChannelId: c.Params.ChannelId,
|
||||
UserId: userId,
|
||||
}
|
||||
|
||||
postRootId, ok := props["post_root_id"].(string)
|
||||
if ok && postRootId != "" && !model.IsValidId(postRootId) {
|
||||
c.SetInvalidParam("post_root_id")
|
||||
return
|
||||
}
|
||||
|
||||
channel, err := c.App.GetChannel(c.Params.ChannelId)
|
||||
if ok && len(postRootId) == 26 {
|
||||
rootPost, err := c.App.GetSinglePost(postRootId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
if rootPost.ChannelId != member.ChannelId {
|
||||
c.SetInvalidParam("post_root_id")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
channel, err := c.App.GetChannel(member.ChannelId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -87,27 +177,29 @@ func localAddChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec.AddMeta("channel", channel)
|
||||
|
||||
if channel.Type == model.CHANNEL_DIRECT || channel.Type == model.CHANNEL_GROUP {
|
||||
c.Err = model.NewAppError("addUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest)
|
||||
c.Err = model.NewAppError("localAddChannelMember", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if channel.IsGroupConstrained() {
|
||||
nonMembers, err := c.App.FilterNonGroupChannelMembers([]string{user.Id}, channel)
|
||||
nonMembers, err := c.App.FilterNonGroupChannelMembers([]string{member.UserId}, channel)
|
||||
if err != nil {
|
||||
if v, ok := err.(*model.AppError); ok {
|
||||
c.Err = v
|
||||
} else {
|
||||
c.Err = model.NewAppError("addChannelMember", "api.channel.add_members.error", nil, err.Error(), http.StatusBadRequest)
|
||||
c.Err = model.NewAppError("localAddChannelMember", "api.channel.add_members.error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(nonMembers) > 0 {
|
||||
c.Err = model.NewAppError("addChannelMember", "api.channel.add_members.user_denied", map[string]interface{}{"UserIDs": nonMembers}, "", http.StatusBadRequest)
|
||||
c.Err = model.NewAppError("localAddChannelMember", "api.channel.add_members.user_denied", map[string]interface{}{"UserIDs": nonMembers}, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
cm, err := c.App.AddUserToChannel(user, channel, false)
|
||||
cm, err := c.App.AddChannelMember(c.AppContext, member.UserId, channel, app.ChannelMemberOpts{
|
||||
PostRootID: postRootId,
|
||||
})
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
|
||||
@@ -1844,7 +1844,8 @@ func TestConvertChannelToPrivate(t *testing.T) {
|
||||
func TestUpdateChannelPrivacy(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
Client := th.Client
|
||||
|
||||
defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, th.BasicTeam.Id, false)
|
||||
|
||||
type testTable []struct {
|
||||
name string
|
||||
@@ -1852,100 +1853,112 @@ func TestUpdateChannelPrivacy(t *testing.T) {
|
||||
expectedPrivacy string
|
||||
}
|
||||
|
||||
defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, th.BasicTeam.Id, false)
|
||||
privateChannel := th.CreatePrivateChannel()
|
||||
publicChannel := th.CreatePublicChannel()
|
||||
t.Run("Should get a forbidden response if not logged in", func(t *testing.T) {
|
||||
privateChannel := th.CreatePrivateChannel()
|
||||
publicChannel := th.CreatePublicChannel()
|
||||
|
||||
tt := testTable{
|
||||
{"Updating default channel should fail with forbidden status if not logged in", defaultChannel, model.CHANNEL_OPEN},
|
||||
{"Updating private channel should fail with forbidden status if not logged in", privateChannel, model.CHANNEL_PRIVATE},
|
||||
{"Updating public channel should fail with forbidden status if not logged in", publicChannel, model.CHANNEL_OPEN},
|
||||
}
|
||||
tt := testTable{
|
||||
{"Updating default channel should fail with forbidden status if not logged in", defaultChannel, model.CHANNEL_OPEN},
|
||||
{"Updating private channel should fail with forbidden status if not logged in", privateChannel, model.CHANNEL_PRIVATE},
|
||||
{"Updating public channel should fail with forbidden status if not logged in", publicChannel, model.CHANNEL_OPEN},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, resp := Client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
})
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, resp := th.Client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
th.LoginTeamAdmin()
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
privateChannel := th.CreatePrivateChannel()
|
||||
publicChannel := th.CreatePublicChannel()
|
||||
|
||||
tt = testTable{
|
||||
{"Converting default channel to private should fail", defaultChannel, model.CHANNEL_PRIVATE},
|
||||
{"Updating privacy to an invalid setting should fail", publicChannel, "invalid"},
|
||||
}
|
||||
tt := testTable{
|
||||
{"Converting default channel to private should fail", defaultChannel, model.CHANNEL_PRIVATE},
|
||||
{"Updating privacy to an invalid setting should fail", publicChannel, "invalid"},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, resp := Client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
})
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, resp := client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
})
|
||||
}
|
||||
|
||||
tt = testTable{
|
||||
{"Default channel should stay public", defaultChannel, model.CHANNEL_OPEN},
|
||||
{"Public channel should stay public", publicChannel, model.CHANNEL_OPEN},
|
||||
{"Private channel should stay private", privateChannel, model.CHANNEL_PRIVATE},
|
||||
{"Public channel should convert to private", publicChannel, model.CHANNEL_PRIVATE},
|
||||
{"Private channel should convert to public", privateChannel, model.CHANNEL_OPEN},
|
||||
}
|
||||
tt = testTable{
|
||||
{"Default channel should stay public", defaultChannel, model.CHANNEL_OPEN},
|
||||
{"Public channel should stay public", publicChannel, model.CHANNEL_OPEN},
|
||||
{"Private channel should stay private", privateChannel, model.CHANNEL_PRIVATE},
|
||||
{"Public channel should convert to private", publicChannel, model.CHANNEL_PRIVATE},
|
||||
{"Private channel should convert to public", privateChannel, model.CHANNEL_OPEN},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
updatedChannel, resp := Client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||
CheckNoError(t, resp)
|
||||
assert.Equal(t, tc.expectedPrivacy, updatedChannel.Type)
|
||||
updatedChannel, err := th.App.GetChannel(tc.channel.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, tc.expectedPrivacy, updatedChannel.Type)
|
||||
})
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
updatedChannel, resp := client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||
CheckNoError(t, resp)
|
||||
assert.Equal(t, tc.expectedPrivacy, updatedChannel.Type)
|
||||
updatedChannel, err := th.App.GetChannel(tc.channel.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, tc.expectedPrivacy, updatedChannel.Type)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Enforces convert channel permissions", func(t *testing.T) {
|
||||
privateChannel := th.CreatePrivateChannel()
|
||||
publicChannel := th.CreatePublicChannel()
|
||||
|
||||
th.LoginTeamAdmin()
|
||||
|
||||
th.RemovePermissionFromRole(model.PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE.Id, model.TEAM_ADMIN_ROLE_ID)
|
||||
th.RemovePermissionFromRole(model.PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC.Id, model.TEAM_ADMIN_ROLE_ID)
|
||||
|
||||
_, resp := Client.UpdateChannelPrivacy(publicChannel.Id, model.CHANNEL_PRIVATE)
|
||||
_, resp := th.Client.UpdateChannelPrivacy(publicChannel.Id, model.CHANNEL_PRIVATE)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
_, resp = Client.UpdateChannelPrivacy(privateChannel.Id, model.CHANNEL_OPEN)
|
||||
_, resp = th.Client.UpdateChannelPrivacy(privateChannel.Id, model.CHANNEL_OPEN)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
th.AddPermissionToRole(model.PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE.Id, model.TEAM_ADMIN_ROLE_ID)
|
||||
th.AddPermissionToRole(model.PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC.Id, model.TEAM_ADMIN_ROLE_ID)
|
||||
|
||||
_, resp = Client.UpdateChannelPrivacy(privateChannel.Id, model.CHANNEL_OPEN)
|
||||
_, resp = th.Client.UpdateChannelPrivacy(privateChannel.Id, model.CHANNEL_OPEN)
|
||||
CheckNoError(t, resp)
|
||||
_, resp = Client.UpdateChannelPrivacy(publicChannel.Id, model.CHANNEL_PRIVATE)
|
||||
_, resp = th.Client.UpdateChannelPrivacy(publicChannel.Id, model.CHANNEL_PRIVATE)
|
||||
CheckNoError(t, resp)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestRestoreChannel(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
Client := th.Client
|
||||
|
||||
publicChannel1 := th.CreatePublicChannel()
|
||||
Client.DeleteChannel(publicChannel1.Id)
|
||||
th.Client.DeleteChannel(publicChannel1.Id)
|
||||
|
||||
privateChannel1 := th.CreatePrivateChannel()
|
||||
Client.DeleteChannel(privateChannel1.Id)
|
||||
th.Client.DeleteChannel(privateChannel1.Id)
|
||||
|
||||
_, resp := Client.RestoreChannel(publicChannel1.Id)
|
||||
_, resp := th.Client.RestoreChannel(publicChannel1.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
_, resp = Client.RestoreChannel(privateChannel1.Id)
|
||||
_, resp = th.Client.RestoreChannel(privateChannel1.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
th.LoginTeamAdmin()
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
defer func() {
|
||||
client.DeleteChannel(publicChannel1.Id)
|
||||
client.DeleteChannel(privateChannel1.Id)
|
||||
}()
|
||||
|
||||
_, resp = Client.RestoreChannel(publicChannel1.Id)
|
||||
CheckOKStatus(t, resp)
|
||||
_, resp = client.RestoreChannel(publicChannel1.Id)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
_, resp = Client.RestoreChannel(privateChannel1.Id)
|
||||
CheckOKStatus(t, resp)
|
||||
_, resp = client.RestoreChannel(privateChannel1.Id)
|
||||
CheckOKStatus(t, resp)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetChannelByName(t *testing.T) {
|
||||
@@ -2052,7 +2065,6 @@ func TestGetChannelMembers(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
|
||||
|
||||
members, resp := client.GetChannelMembers(th.BasicChannel.Id, 0, 60, "")
|
||||
CheckNoError(t, resp)
|
||||
require.Len(t, *members, 3, "should only be 3 users in channel")
|
||||
|
||||
Ссылка в новой задаче
Block a user