[MM-16934] Add API endpoint to update channel privacy (#11993)
* Add API endpoint to update channel privacy setting * Fix language files * Improve tests by making sure channel has been updated correctly * Improve tests
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6a2f09ae78
Коммит
ad9784d7e3
@@ -35,6 +35,7 @@ func (api *API) InitChannel() {
|
|||||||
api.BaseRoutes.Channel.Handle("", api.ApiSessionRequired(updateChannel)).Methods("PUT")
|
api.BaseRoutes.Channel.Handle("", api.ApiSessionRequired(updateChannel)).Methods("PUT")
|
||||||
api.BaseRoutes.Channel.Handle("/patch", api.ApiSessionRequired(patchChannel)).Methods("PUT")
|
api.BaseRoutes.Channel.Handle("/patch", api.ApiSessionRequired(patchChannel)).Methods("PUT")
|
||||||
api.BaseRoutes.Channel.Handle("/convert", api.ApiSessionRequired(convertChannelToPrivate)).Methods("POST")
|
api.BaseRoutes.Channel.Handle("/convert", api.ApiSessionRequired(convertChannelToPrivate)).Methods("POST")
|
||||||
|
api.BaseRoutes.Channel.Handle("/privacy", api.ApiSessionRequired(updateChannelPrivacy)).Methods("PUT")
|
||||||
api.BaseRoutes.Channel.Handle("/restore", api.ApiSessionRequired(restoreChannel)).Methods("POST")
|
api.BaseRoutes.Channel.Handle("/restore", api.ApiSessionRequired(restoreChannel)).Methods("POST")
|
||||||
api.BaseRoutes.Channel.Handle("", api.ApiSessionRequired(deleteChannel)).Methods("DELETE")
|
api.BaseRoutes.Channel.Handle("", api.ApiSessionRequired(deleteChannel)).Methods("DELETE")
|
||||||
api.BaseRoutes.Channel.Handle("/stats", api.ApiSessionRequired(getChannelStats)).Methods("GET")
|
api.BaseRoutes.Channel.Handle("/stats", api.ApiSessionRequired(getChannelStats)).Methods("GET")
|
||||||
@@ -229,6 +230,54 @@ func convertChannelToPrivate(c *Context, w http.ResponseWriter, r *http.Request)
|
|||||||
w.Write([]byte(rchannel.ToJson()))
|
w.Write([]byte(rchannel.ToJson()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateChannelPrivacy(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
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.App.SessionHasPermissionToTeam(c.App.Session, channel.TeamId, model.PERMISSION_MANAGE_TEAM) {
|
||||||
|
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := c.App.GetUser(c.App.Session.UserId)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.Type = privacy
|
||||||
|
|
||||||
|
updatedChannel, err := c.App.UpdateChannelPrivacy(channel, user)
|
||||||
|
if err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.LogAudit("name=" + updatedChannel.Name)
|
||||||
|
|
||||||
|
w.Write([]byte(updatedChannel.ToJson()))
|
||||||
|
}
|
||||||
|
|
||||||
func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
c.RequireChannelId()
|
c.RequireChannelId()
|
||||||
if c.Err != nil {
|
if c.Err != nil {
|
||||||
|
|||||||
@@ -1387,6 +1387,68 @@ func TestConvertChannelToPrivate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateChannelPrivacy(t *testing.T) {
|
||||||
|
th := Setup().InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
Client := th.Client
|
||||||
|
|
||||||
|
type testTable []struct {
|
||||||
|
name string
|
||||||
|
channel *model.Channel
|
||||||
|
expectedPrivacy string
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, th.BasicTeam.Id, false)
|
||||||
|
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},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
_, resp := Client.UpdateChannelPrivacy(tc.channel.Id, tc.expectedPrivacy)
|
||||||
|
CheckForbiddenStatus(t, resp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
th.LoginTeamAdmin()
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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, updatedChannel.Type, tc.expectedPrivacy)
|
||||||
|
updatedChannel, err := th.App.GetChannel(tc.channel.Id)
|
||||||
|
require.Nil(t, err)
|
||||||
|
assert.Equal(t, updatedChannel.Type, tc.expectedPrivacy)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRestoreChannel(t *testing.T) {
|
func TestRestoreChannel(t *testing.T) {
|
||||||
th := Setup().InitBasic()
|
th := Setup().InitBasic()
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
|
|||||||
@@ -387,6 +387,10 @@
|
|||||||
"id": "api.channel.update_channel_member_roles.scheme_role.app_error",
|
"id": "api.channel.update_channel_member_roles.scheme_role.app_error",
|
||||||
"translation": "The provided role is managed by a Scheme and therefore cannot be applied directly to a Channel Member"
|
"translation": "The provided role is managed by a Scheme and therefore cannot be applied directly to a Channel Member"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.update_channel_privacy.default_channel_error",
|
||||||
|
"translation": "The default channel cannot be made private."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.channel.update_channel_scheme.license.error",
|
"id": "api.channel.update_channel_scheme.license.error",
|
||||||
"translation": "Your license does not support updating a channel's scheme"
|
"translation": "Your license does not support updating a channel's scheme"
|
||||||
|
|||||||
@@ -2100,6 +2100,17 @@ func (c *Client4) ConvertChannelToPrivate(channelId string) (*Channel, *Response
|
|||||||
return ChannelFromJson(r.Body), BuildResponse(r)
|
return ChannelFromJson(r.Body), BuildResponse(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateChannelPrivacy updates channel privacy
|
||||||
|
func (c *Client4) UpdateChannelPrivacy(channelId string, privacy string) (*Channel, *Response) {
|
||||||
|
requestBody := map[string]string{"privacy": privacy}
|
||||||
|
r, err := c.DoApiPut(c.GetChannelRoute(channelId)+"/privacy", MapToJson(requestBody))
|
||||||
|
if err != nil {
|
||||||
|
return nil, BuildErrorResponse(r, err)
|
||||||
|
}
|
||||||
|
defer closeBody(r)
|
||||||
|
return ChannelFromJson(r.Body), BuildResponse(r)
|
||||||
|
}
|
||||||
|
|
||||||
// RestoreChannel restores a previously deleted channel. Any missing fields are not updated.
|
// RestoreChannel restores a previously deleted channel. Any missing fields are not updated.
|
||||||
func (c *Client4) RestoreChannel(channelId string) (*Channel, *Response) {
|
func (c *Client4) RestoreChannel(channelId string) (*Channel, *Response) {
|
||||||
r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/restore", "")
|
r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/restore", "")
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user