From ca61b4bed94ea98530bf4f1b2f7585fe86ef80cd Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Thu, 22 Dec 2016 20:44:37 +0000 Subject: PLT-5080 (Server): Channel-Admin level permissions (#4874) Adds permissions for manage/delete public/private channels at the Channel Admin level. --- api/apitestlib.go | 36 +++++++++++++++++ api/channel.go | 4 +- api/channel_test.go | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ model/config.go | 7 ++-- utils/authorization.go | 24 +++++++++++ 5 files changed, 172 insertions(+), 5 deletions(-) diff --git a/api/apitestlib.go b/api/apitestlib.go index f11613a90..8fb030488 100644 --- a/api/apitestlib.go +++ b/api/apitestlib.go @@ -171,6 +171,42 @@ func UpdateUserToTeamAdmin(user *model.User, team *model.Team) { utils.EnableDebugLogForTest() } +func MakeUserChannelAdmin(user *model.User, channel *model.Channel) { + utils.DisableDebugLogForTest() + + if cmr := <-Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil { + cm := cmr.Data.(model.ChannelMember) + cm.Roles = "channel_admin channel_user" + if sr := <-Srv.Store.Channel().UpdateMember(&cm); sr.Err != nil { + utils.EnableDebugLogForTest() + panic(sr.Err) + } + } else { + utils.EnableDebugLogForTest() + panic(cmr.Err) + } + + utils.EnableDebugLogForTest() +} + +func MakeUserChannelUser(user *model.User, channel *model.Channel) { + utils.DisableDebugLogForTest() + + if cmr := <-Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil { + cm := cmr.Data.(model.ChannelMember) + cm.Roles = "channel_user" + if sr := <-Srv.Store.Channel().UpdateMember(&cm); sr.Err != nil { + utils.EnableDebugLogForTest() + panic(sr.Err) + } + } else { + utils.EnableDebugLogForTest() + panic(cmr.Err) + } + + utils.EnableDebugLogForTest() +} + func (me *TestHelper) CreateChannel(client *model.Client, team *model.Team) *model.Channel { return me.createChannel(client, team, model.CHANNEL_OPEN) } diff --git a/api/channel.go b/api/channel.go index 7ccf5e2b6..44efc5efb 100644 --- a/api/channel.go +++ b/api/channel.go @@ -804,11 +804,11 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { // Allow delete if user is the only member left in channel if memberCount > 1 { - if channel.Type == model.CHANNEL_OPEN && !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_DELETE_PUBLIC_CHANNEL) { + if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_DELETE_PUBLIC_CHANNEL) { return } - if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_DELETE_PRIVATE_CHANNEL) { + if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_DELETE_PRIVATE_CHANNEL) { return } } diff --git a/api/channel_test.go b/api/channel_test.go index d1bd66a02..dae4feab6 100644 --- a/api/channel_test.go +++ b/api/channel_test.go @@ -330,6 +330,31 @@ func TestUpdateChannel(t *testing.T) { t.Fatal(err) } + *utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN + *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN + utils.SetDefaultRolesBasedOnConfig() + MakeUserChannelUser(th.BasicUser, channel2) + MakeUserChannelUser(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.UpdateChannel(channel2); err == nil { + t.Fatal("should have errored not team admin") + } + if _, err := Client.UpdateChannel(channel3); err == nil { + t.Fatal("should have errored not team admin") + } + + MakeUserChannelAdmin(th.BasicUser, channel2) + MakeUserChannelAdmin(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.UpdateChannel(channel2); err != nil { + t.Fatal(err) + } + if _, err := Client.UpdateChannel(channel3); err != nil { + t.Fatal(err) + } + *utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN utils.SetDefaultRolesBasedOnConfig() @@ -512,6 +537,31 @@ func TestUpdateChannelHeader(t *testing.T) { t.Fatal(err) } + *utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN + *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN + utils.SetDefaultRolesBasedOnConfig() + MakeUserChannelUser(th.BasicUser, channel2) + MakeUserChannelUser(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.UpdateChannelHeader(data2); err == nil { + t.Fatal("should have errored not channel admin") + } + if _, err := Client.UpdateChannelHeader(data3); err == nil { + t.Fatal("should have errored not channel admin") + } + + MakeUserChannelAdmin(th.BasicUser, channel2) + MakeUserChannelAdmin(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.UpdateChannelHeader(data2); err != nil { + t.Fatal(err) + } + if _, err := Client.UpdateChannelHeader(data3); err != nil { + t.Fatal(err) + } + *utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN utils.SetDefaultRolesBasedOnConfig() @@ -646,6 +696,31 @@ func TestUpdateChannelPurpose(t *testing.T) { t.Fatal(err) } + *utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN + *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN + utils.SetDefaultRolesBasedOnConfig() + MakeUserChannelUser(th.BasicUser, channel2) + MakeUserChannelUser(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.UpdateChannelPurpose(data2); err == nil { + t.Fatal("should have errored not channel admin") + } + if _, err := Client.UpdateChannelPurpose(data3); err == nil { + t.Fatal("should have errored not channel admin") + } + + MakeUserChannelAdmin(th.BasicUser, channel2) + MakeUserChannelAdmin(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.UpdateChannelPurpose(data2); err != nil { + t.Fatal(err) + } + if _, err := Client.UpdateChannelPurpose(data3); err != nil { + t.Fatal(err) + } + *utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN utils.SetDefaultRolesBasedOnConfig() @@ -1166,6 +1241,37 @@ func TestDeleteChannel(t *testing.T) { t.Fatal(err) } + *utils.Cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN + *utils.Cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN + utils.SetDefaultRolesBasedOnConfig() + + th.LoginSystemAdmin() + + channel2 = th.CreateChannel(Client, team) + channel3 = th.CreatePrivateChannel(Client, team) + Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser.Id)) + Client.Must(Client.AddChannelMember(channel3.Id, th.BasicUser.Id)) + + Client.Login(th.BasicUser.Email, th.BasicUser.Password) + + if _, err := Client.DeleteChannel(channel2.Id); err == nil { + t.Fatal("should have errored not channel admin") + } + if _, err := Client.DeleteChannel(channel3.Id); err == nil { + t.Fatal("should have errored not channel admin") + } + + MakeUserChannelAdmin(th.BasicUser, channel2) + MakeUserChannelAdmin(th.BasicUser, channel3) + store.ClearChannelCaches() + + if _, err := Client.DeleteChannel(channel2.Id); err != nil { + t.Fatal(err) + } + if _, err := Client.DeleteChannel(channel3.Id); err != nil { + t.Fatal(err) + } + *utils.Cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN *utils.Cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN utils.SetDefaultRolesBasedOnConfig() diff --git a/model/config.go b/model/config.go index 1ac44c579..0134e1a34 100644 --- a/model/config.go +++ b/model/config.go @@ -38,9 +38,10 @@ const ( DIRECT_MESSAGE_ANY = "any" DIRECT_MESSAGE_TEAM = "team" - PERMISSIONS_ALL = "all" - PERMISSIONS_TEAM_ADMIN = "team_admin" - PERMISSIONS_SYSTEM_ADMIN = "system_admin" + PERMISSIONS_ALL = "all" + PERMISSIONS_CHANNEL_ADMIN = "channel_admin" + PERMISSIONS_TEAM_ADMIN = "team_admin" + PERMISSIONS_SYSTEM_ADMIN = "system_admin" FAKE_SETTING = "********************************" diff --git a/utils/authorization.go b/utils/authorization.go index 75f92062d..533808467 100644 --- a/utils/authorization.go +++ b/utils/authorization.go @@ -31,6 +31,12 @@ func SetDefaultRolesBasedOnConfig() { model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, ) break + case model.PERMISSIONS_CHANNEL_ADMIN: + model.ROLE_CHANNEL_ADMIN.Permissions = append( + model.ROLE_CHANNEL_ADMIN.Permissions, + model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, + ) + break case model.PERMISSIONS_TEAM_ADMIN: model.ROLE_TEAM_ADMIN.Permissions = append( model.ROLE_TEAM_ADMIN.Permissions, @@ -46,6 +52,12 @@ func SetDefaultRolesBasedOnConfig() { model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, ) break + case model.PERMISSIONS_CHANNEL_ADMIN: + model.ROLE_CHANNEL_ADMIN.Permissions = append( + model.ROLE_CHANNEL_ADMIN.Permissions, + model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, + ) + break case model.PERMISSIONS_TEAM_ADMIN: model.ROLE_TEAM_ADMIN.Permissions = append( model.ROLE_TEAM_ADMIN.Permissions, @@ -76,6 +88,12 @@ func SetDefaultRolesBasedOnConfig() { model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, ) break + case model.PERMISSIONS_CHANNEL_ADMIN: + model.ROLE_CHANNEL_ADMIN.Permissions = append( + model.ROLE_CHANNEL_ADMIN.Permissions, + model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, + ) + break case model.PERMISSIONS_TEAM_ADMIN: model.ROLE_TEAM_ADMIN.Permissions = append( model.ROLE_TEAM_ADMIN.Permissions, @@ -91,6 +109,12 @@ func SetDefaultRolesBasedOnConfig() { model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, ) break + case model.PERMISSIONS_CHANNEL_ADMIN: + model.ROLE_CHANNEL_ADMIN.Permissions = append( + model.ROLE_CHANNEL_ADMIN.Permissions, + model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, + ) + break case model.PERMISSIONS_TEAM_ADMIN: model.ROLE_TEAM_ADMIN.Permissions = append( model.ROLE_TEAM_ADMIN.Permissions, -- cgit v1.2.3-1-g7c22