Channel banner permissions (#30917)
* Fixed save state panel for channel banner * Defined default background color * Updated test * WIP * wip * removed unused param * Updated tests * CI * Fixed mmctl test * Fixed TestDoAdvancedPermissionsMigration test * Test update * lint fix * lint fix --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d73222dca9
Коммит
a5e68639c2
@@ -378,9 +378,8 @@ func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if patch.BannerInfo != nil {
|
||||
if channelBannerAppErr := canEditChannelBanner(c.App.License(), originalOldChannel); channelBannerAppErr != nil {
|
||||
channelBannerAppErr.Where = "patchChannel"
|
||||
c.Err = channelBannerAppErr
|
||||
canEditChannelBanner(c, originalOldChannel)
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -2459,14 +2458,23 @@ func convertGroupMessageToChannel(c *Context, w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
}
|
||||
|
||||
func canEditChannelBanner(license *model.License, originalChannel *model.Channel) *model.AppError {
|
||||
if !model.MinimumEnterpriseAdvancedLicense(license) {
|
||||
return model.NewAppError("", "license_error.feature_unavailable.specific", map[string]any{"Feature": "Channel Banner"}, "feature is not available for the current license", http.StatusForbidden)
|
||||
func canEditChannelBanner(c *Context, originalChannel *model.Channel) {
|
||||
if !model.MinimumEnterpriseAdvancedLicense(c.App.License()) {
|
||||
c.Err = model.NewAppError("patchChannel", "license_error.feature_unavailable.specific", map[string]any{"Feature": "Channel Banner"}, "feature is not available for the current license", http.StatusForbidden)
|
||||
}
|
||||
|
||||
if originalChannel.Type != model.ChannelTypeOpen && originalChannel.Type != model.ChannelTypePrivate {
|
||||
return model.NewAppError("", "api.channel.update_channel.banner_info.channel_type.not_allowed", nil, "", http.StatusBadRequest)
|
||||
switch originalChannel.Type {
|
||||
case model.ChannelTypePrivate:
|
||||
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), c.Params.ChannelId, model.PermissionManagePrivateChannelBanner) {
|
||||
c.SetPermissionError(model.PermissionManagePrivateChannelBanner)
|
||||
return
|
||||
}
|
||||
case model.ChannelTypeOpen:
|
||||
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), c.Params.ChannelId, model.PermissionManagePublicChannelBanner) {
|
||||
c.SetPermissionError(model.PermissionManagePublicChannelBanner)
|
||||
return
|
||||
}
|
||||
default:
|
||||
c.Err = model.NewAppError("patchChannel", "api.channel.update_channel.banner_info.channel_type.not_allowed", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost/server/v8/channels/web"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -842,6 +844,52 @@ func TestPatchChannel(t *testing.T) {
|
||||
require.Equal(t, "color", *patchedChannel.BannerInfo.BackgroundColor)
|
||||
})
|
||||
|
||||
t.Run("Should not be able to configure channel banner on a channel as a non-admin channel member", func(t *testing.T) {
|
||||
client.Logout(context.Background())
|
||||
th.LoginBasic()
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
|
||||
defer func() {
|
||||
th.App.Srv().RemoveLicense()
|
||||
}()
|
||||
|
||||
patch := &model.ChannelPatch{
|
||||
BannerInfo: &model.ChannelBannerInfo{
|
||||
Enabled: model.NewPointer(true),
|
||||
Text: model.NewPointer("banner text"),
|
||||
BackgroundColor: model.NewPointer("color"),
|
||||
},
|
||||
}
|
||||
|
||||
_, resp, err := client.PatchChannel(context.Background(), th.BasicChannel.Id, patch)
|
||||
require.Error(t, err)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
})
|
||||
|
||||
t.Run("Should be able to configure channel banner as a team admin", func(t *testing.T) {
|
||||
client.Logout(context.Background())
|
||||
th.LoginTeamAdmin()
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced))
|
||||
defer func() {
|
||||
th.App.Srv().RemoveLicense()
|
||||
}()
|
||||
|
||||
patch := &model.ChannelPatch{
|
||||
BannerInfo: &model.ChannelBannerInfo{
|
||||
Enabled: model.NewPointer(true),
|
||||
Text: model.NewPointer("banner text"),
|
||||
BackgroundColor: model.NewPointer("color"),
|
||||
},
|
||||
}
|
||||
|
||||
patchedChannel, resp, err := client.PatchChannel(context.Background(), th.BasicChannel2.Id, patch)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
require.NotNil(t, patchedChannel.BannerInfo)
|
||||
require.True(t, *patchedChannel.BannerInfo.Enabled)
|
||||
require.Equal(t, "banner text", *patchedChannel.BannerInfo.Text)
|
||||
require.Equal(t, "color", *patchedChannel.BannerInfo.BackgroundColor)
|
||||
})
|
||||
|
||||
t.Run("Cannot enable channel banner without configuring it", func(t *testing.T) {
|
||||
client.Logout(context.Background())
|
||||
th.LoginBasic()
|
||||
@@ -958,6 +1006,147 @@ func TestPatchChannel(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCanEditChannelBanner(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
t.Run("when license is nil", func(t *testing.T) {
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
|
||||
th.App.Srv().SetLicense(nil)
|
||||
|
||||
webContext := &Context{
|
||||
App: th.App,
|
||||
AppContext: th.Context,
|
||||
Params: &web.Params{
|
||||
ChannelId: "channel_id",
|
||||
},
|
||||
}
|
||||
|
||||
canEditChannelBanner(webContext, channel)
|
||||
|
||||
require.NotNil(t, webContext.Err)
|
||||
assert.Equal(t, "api.context.permissions.app_error", webContext.Err.Id)
|
||||
assert.Equal(t, http.StatusForbidden, webContext.Err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when license is not E20 or Enterprise", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)
|
||||
th.App.Srv().SetLicense(license)
|
||||
|
||||
webContext := &Context{
|
||||
App: th.App,
|
||||
AppContext: th.Context,
|
||||
Params: &web.Params{
|
||||
ChannelId: "channel_id",
|
||||
},
|
||||
}
|
||||
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
|
||||
canEditChannelBanner(webContext, channel)
|
||||
|
||||
require.NotNil(t, webContext.Err)
|
||||
assert.Equal(t, "api.context.permissions.app_error", webContext.Err.Id)
|
||||
assert.Equal(t, http.StatusForbidden, webContext.Err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when channel type is direct message", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
th.App.Srv().SetLicense(license)
|
||||
|
||||
webContext := &Context{
|
||||
App: th.App,
|
||||
AppContext: th.Context,
|
||||
Params: &web.Params{
|
||||
ChannelId: "channel_id",
|
||||
},
|
||||
}
|
||||
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeDirect,
|
||||
}
|
||||
|
||||
canEditChannelBanner(webContext, channel)
|
||||
|
||||
require.NotNil(t, webContext.Err)
|
||||
assert.Equal(t, "api.channel.update_channel.banner_info.channel_type.not_allowed", webContext.Err.Id)
|
||||
assert.Equal(t, http.StatusBadRequest, webContext.Err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when channel type is group message", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
th.App.Srv().SetLicense(license)
|
||||
|
||||
webContext := &Context{
|
||||
App: th.App,
|
||||
AppContext: th.Context,
|
||||
Params: &web.Params{
|
||||
ChannelId: "channel_id",
|
||||
},
|
||||
}
|
||||
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeGroup,
|
||||
}
|
||||
|
||||
canEditChannelBanner(webContext, channel)
|
||||
require.NotNil(t, webContext.Err)
|
||||
assert.Equal(t, "api.channel.update_channel.banner_info.channel_type.not_allowed", webContext.Err.Id)
|
||||
assert.Equal(t, http.StatusBadRequest, webContext.Err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when channel type is open and license is valid", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
th.App.Srv().SetLicense(license)
|
||||
|
||||
channel := th.CreatePublicChannel()
|
||||
th.MakeUserChannelAdmin(th.BasicUser, channel)
|
||||
|
||||
webContext := &Context{
|
||||
App: th.App,
|
||||
AppContext: th.Context,
|
||||
Params: &web.Params{
|
||||
ChannelId: channel.Id,
|
||||
},
|
||||
}
|
||||
|
||||
webContext.AppContext = webContext.AppContext.WithSession(&model.Session{
|
||||
UserId: th.BasicUser.Id,
|
||||
})
|
||||
|
||||
canEditChannelBanner(webContext, channel)
|
||||
assert.Nil(t, webContext.Err)
|
||||
})
|
||||
|
||||
t.Run("when channel type is private and license is valid", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
th.App.Srv().SetLicense(license)
|
||||
|
||||
channel := th.CreatePrivateChannel()
|
||||
th.MakeUserChannelAdmin(th.BasicUser, channel)
|
||||
|
||||
webContext := &Context{
|
||||
App: th.App,
|
||||
AppContext: th.Context,
|
||||
Params: &web.Params{
|
||||
ChannelId: channel.Id,
|
||||
},
|
||||
}
|
||||
|
||||
webContext.AppContext = webContext.AppContext.WithSession(&model.Session{
|
||||
UserId: th.BasicUser.Id,
|
||||
})
|
||||
|
||||
canEditChannelBanner(webContext, channel)
|
||||
assert.Nil(t, webContext.Err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestChannelUnicodeNames(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
@@ -5737,75 +5926,3 @@ func TestViewChannelWithoutCollapsedThreads(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Zero(t, threads.TotalUnreadMentions)
|
||||
}
|
||||
|
||||
func TestCanEditChannelBanner(t *testing.T) {
|
||||
t.Run("when license is nil", func(t *testing.T) {
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
|
||||
err := canEditChannelBanner(nil, channel)
|
||||
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "license_error.feature_unavailable.specific", err.Id)
|
||||
assert.Equal(t, http.StatusForbidden, err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when license is not E20 or Enterprise", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuProfessional)
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
|
||||
err := canEditChannelBanner(license, channel)
|
||||
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "license_error.feature_unavailable.specific", err.Id)
|
||||
assert.Equal(t, http.StatusForbidden, err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when channel type is direct message", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeDirect,
|
||||
}
|
||||
|
||||
err := canEditChannelBanner(license, channel)
|
||||
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.channel.update_channel.banner_info.channel_type.not_allowed", err.Id)
|
||||
assert.Equal(t, http.StatusBadRequest, err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when channel type is group message", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeGroup,
|
||||
}
|
||||
|
||||
err := canEditChannelBanner(license, channel)
|
||||
require.NotNil(t, err)
|
||||
assert.Equal(t, "api.channel.update_channel.banner_info.channel_type.not_allowed", err.Id)
|
||||
assert.Equal(t, http.StatusBadRequest, err.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("when channel type is open and license is valid", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
|
||||
err := canEditChannelBanner(license, channel)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("when channel type is private and license is valid", func(t *testing.T) {
|
||||
license := model.NewTestLicenseSKU(model.LicenseShortSkuEnterpriseAdvanced)
|
||||
channel := &model.Channel{
|
||||
Type: model.ChannelTypePrivate,
|
||||
}
|
||||
|
||||
err := canEditChannelBanner(license, channel)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user