Merge branch 'advanced-permissions-phase-1'

Этот коммит содержится в:
George Goldberg
2018-03-27 22:36:55 +01:00
родитель 2af4c7e649 e13e64711f
Коммит 71c9dff766
75 изменённых файлов: 4362 добавлений и 1504 удалений

Просмотреть файл

@@ -116,6 +116,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
Init(th.App, th.App.Srv.Router)
wsapi.Init(th.App, th.App.Srv.WebSocketRouter)
th.App.Srv.Store.MarkSystemRanUnitTests()
th.App.DoAdvancedPermissionsMigration()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
@@ -395,3 +396,114 @@ func (me *TestHelper) TearDown() {
panic(err)
}
}
func (me *TestHelper) SaveDefaultRolePermissions() map[string][]string {
utils.DisableDebugLogForTest()
results := make(map[string][]string)
for _, roleName := range []string{
"system_user",
"system_admin",
"team_user",
"team_admin",
"channel_user",
"channel_admin",
} {
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
results[roleName] = role.Permissions
}
utils.EnableDebugLogForTest()
return results
}
func (me *TestHelper) RestoreDefaultRolePermissions(data map[string][]string) {
utils.DisableDebugLogForTest()
for roleName, permissions := range data {
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
if strings.Join(role.Permissions, " ") == strings.Join(permissions, " ") {
continue
}
role.Permissions = permissions
_, err2 := me.App.UpdateRole(role)
if err2 != nil {
utils.EnableDebugLogForTest()
panic(err2)
}
}
utils.EnableDebugLogForTest()
}
func (me *TestHelper) RemovePermissionFromRole(permission string, roleName string) {
utils.DisableDebugLogForTest()
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
var newPermissions []string
for _, p := range role.Permissions {
if p != permission {
newPermissions = append(newPermissions, p)
}
}
if strings.Join(role.Permissions, " ") == strings.Join(newPermissions, " ") {
utils.EnableDebugLogForTest()
return
}
role.Permissions = newPermissions
_, err2 := me.App.UpdateRole(role)
if err2 != nil {
utils.EnableDebugLogForTest()
panic(err2)
}
utils.EnableDebugLogForTest()
}
func (me *TestHelper) AddPermissionToRole(permission string, roleName string) {
utils.DisableDebugLogForTest()
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
for _, existingPermission := range role.Permissions {
if existingPermission == permission {
utils.EnableDebugLogForTest()
return
}
}
role.Permissions = append(role.Permissions, permission)
_, err2 := me.App.UpdateRole(role)
if err2 != nil {
utils.EnableDebugLogForTest()
panic(err2)
}
utils.EnableDebugLogForTest()
}

Просмотреть файл

@@ -18,7 +18,6 @@ func TestCreateChannel(t *testing.T) {
defer th.TearDown()
Client := th.BasicClient
SystemAdminClient := th.SystemAdminClient
team := th.BasicTeam
th.LoginBasic2()
team2 := th.CreateTeam(th.BasicClient)
@@ -95,9 +94,14 @@ func TestCreateChannel(t *testing.T) {
t.Fatal("Should have errored out on direct channel type")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel3 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -108,12 +112,10 @@ func TestCreateChannel(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id, model.TEAM_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id, model.TEAM_ADMIN_ROLE_ID)
th.LoginBasic2()
channel2.Name = "zz" + model.NewId() + "a"
@@ -136,46 +138,6 @@ func TestCreateChannel(t *testing.T) {
if _, err := Client.CreateChannel(channel3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
})
channel2.Name = "zz" + model.NewId() + "a"
channel3.Name = "zz" + model.NewId() + "a"
if _, err := Client.CreateChannel(channel2); err == nil {
t.Fatal("should have errored not system admin")
}
if _, err := Client.CreateChannel(channel3); err == nil {
t.Fatal("should have errored not system admin")
}
th.LinkUserToTeam(th.SystemAdminUser, team)
if _, err := SystemAdminClient.CreateChannel(channel2); err != nil {
t.Fatal(err)
}
if _, err := SystemAdminClient.CreateChannel(channel3); err != nil {
t.Fatal(err)
}
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
channel4 := model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel5 := model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
if _, err := Client.CreateChannel(&channel4); err != nil {
t.Fatal("should have succeeded")
}
if _, err := Client.CreateChannel(&channel5); err != nil {
t.Fatal("should have succeeded")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL })
}
func TestCreateDirectChannel(t *testing.T) {
@@ -346,9 +308,17 @@ func TestUpdateChannel(t *testing.T) {
t.Fatal("should have failed - channel deleted")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
channel2 := th.CreateChannel(Client, team)
channel3 := th.CreatePrivateChannel(Client, team)
@@ -367,10 +337,11 @@ func TestUpdateChannel(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.MakeUserChannelUser(th.BasicUser, channel2)
th.MakeUserChannelUser(th.BasicUser, channel3)
th.App.Srv.Store.Channel().ClearCaches()
@@ -382,17 +353,6 @@ func TestUpdateChannel(t *testing.T) {
t.Fatal("should have errored not channel admin")
}
th.UpdateUserToTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches()
if _, err := Client.UpdateChannel(channel2); err != nil {
t.Fatal(err)
}
if _, err := Client.UpdateChannel(channel3); err != nil {
t.Fatal(err)
}
th.UpdateUserToNonTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches()
th.MakeUserChannelAdmin(th.BasicUser, channel2)
th.MakeUserChannelAdmin(th.BasicUser, channel3)
th.App.Srv.Store.Channel().ClearCaches()
@@ -403,62 +363,6 @@ func TestUpdateChannel(t *testing.T) {
if _, err := Client.UpdateChannel(channel3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
th.App.SetLicense(model.NewTestLicense())
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")
}
th.UpdateUserToTeamAdmin(th.BasicUser, team)
Client.Logout()
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
Client.SetTeamId(team.Id)
if _, err := Client.UpdateChannel(channel2); err != nil {
t.Fatal(err)
}
if _, err := Client.UpdateChannel(channel3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
})
if _, err := Client.UpdateChannel(channel2); err == nil {
t.Fatal("should have errored not system admin")
}
if _, err := Client.UpdateChannel(channel3); err == nil {
t.Fatal("should have errored not system admin")
}
th.LoginSystemAdmin()
if _, err := Client.UpdateChannel(channel2); err != nil {
t.Fatal(err)
}
if _, err := Client.UpdateChannel(channel3); err != nil {
t.Fatal(err)
}
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
if _, err := Client.UpdateChannel(channel2); err != nil {
t.Fatal(err)
}
if _, err := Client.UpdateChannel(channel3); err != nil {
t.Fatal(err)
}
}
func TestUpdateChannelDisplayName(t *testing.T) {
@@ -494,7 +398,6 @@ func TestUpdateChannelHeader(t *testing.T) {
defer th.TearDown()
Client := th.BasicClient
SystemAdminClient := th.SystemAdminClient
team := th.BasicTeam
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
@@ -564,9 +467,17 @@ func TestUpdateChannelHeader(t *testing.T) {
t.Fatal("should have errored non-channel member trying to update header")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.LoginBasic()
channel2 := th.CreateChannel(Client, team)
@@ -589,10 +500,11 @@ func TestUpdateChannelHeader(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.MakeUserChannelUser(th.BasicUser, channel2)
th.MakeUserChannelUser(th.BasicUser, channel3)
th.App.Srv.Store.Channel().ClearCaches()
@@ -614,64 +526,6 @@ func TestUpdateChannelHeader(t *testing.T) {
if _, err := Client.UpdateChannelHeader(data3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
if _, err := Client.UpdateChannelHeader(data2); err == nil {
t.Fatal("should have errored not team admin")
}
if _, err := Client.UpdateChannelHeader(data3); err == nil {
t.Fatal("should have errored not team admin")
}
th.UpdateUserToTeamAdmin(th.BasicUser, team)
Client.Logout()
th.LoginBasic()
Client.SetTeamId(team.Id)
if _, err := Client.UpdateChannelHeader(data2); err != nil {
t.Fatal(err)
}
if _, err := Client.UpdateChannelHeader(data3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
})
if _, err := Client.UpdateChannelHeader(data2); err == nil {
t.Fatal("should have errored not system admin")
}
if _, err := Client.UpdateChannelHeader(data3); err == nil {
t.Fatal("should have errored not system admin")
}
th.LinkUserToTeam(th.SystemAdminUser, team)
Client.Must(Client.AddChannelMember(channel2.Id, th.SystemAdminUser.Id))
Client.Must(Client.AddChannelMember(channel3.Id, th.SystemAdminUser.Id))
th.LoginSystemAdmin()
if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil {
t.Fatal(err)
}
if _, err := SystemAdminClient.UpdateChannelHeader(data3); err != nil {
t.Fatal(err)
}
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil {
t.Fatal(err)
}
if _, err := SystemAdminClient.UpdateChannelHeader(data3); err != nil {
t.Fatal(err)
}
}
func TestUpdateChannelPurpose(t *testing.T) {
@@ -679,7 +533,6 @@ func TestUpdateChannelPurpose(t *testing.T) {
defer th.TearDown()
Client := th.BasicClient
SystemAdminClient := th.SystemAdminClient
team := th.BasicTeam
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
@@ -735,9 +588,17 @@ func TestUpdateChannelPurpose(t *testing.T) {
t.Fatal("should have errored non-channel member trying to update purpose")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.LoginBasic()
channel2 := th.CreateChannel(Client, team)
@@ -760,10 +621,11 @@ func TestUpdateChannelPurpose(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.MakeUserChannelUser(th.BasicUser, channel2)
th.MakeUserChannelUser(th.BasicUser, channel3)
th.App.Srv.Store.Channel().ClearCaches()
@@ -785,63 +647,6 @@ func TestUpdateChannelPurpose(t *testing.T) {
if _, err := Client.UpdateChannelPurpose(data3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
if _, err := Client.UpdateChannelPurpose(data2); err == nil {
t.Fatal("should have errored not team admin")
}
if _, err := Client.UpdateChannelPurpose(data3); err == nil {
t.Fatal("should have errored not team admin")
}
th.UpdateUserToTeamAdmin(th.BasicUser, team)
Client.Logout()
th.LoginBasic()
Client.SetTeamId(team.Id)
if _, err := Client.UpdateChannelPurpose(data2); err != nil {
t.Fatal(err)
}
if _, err := Client.UpdateChannelPurpose(data3); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
})
if _, err := Client.UpdateChannelPurpose(data2); err == nil {
t.Fatal("should have errored not system admin")
}
if _, err := Client.UpdateChannelPurpose(data3); err == nil {
t.Fatal("should have errored not system admin")
}
th.LinkUserToTeam(th.SystemAdminUser, team)
Client.Must(Client.AddChannelMember(channel2.Id, th.SystemAdminUser.Id))
Client.Must(Client.AddChannelMember(channel3.Id, th.SystemAdminUser.Id))
th.LoginSystemAdmin()
if _, err := SystemAdminClient.UpdateChannelPurpose(data2); err != nil {
t.Fatal(err)
}
if _, err := SystemAdminClient.UpdateChannelPurpose(data3); err != nil {
t.Fatal(err)
}
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil {
t.Fatal(err)
}
if _, err := SystemAdminClient.UpdateChannelHeader(data3); err != nil {
t.Fatal(err)
}
}
func TestGetChannel(t *testing.T) {
@@ -1296,9 +1101,14 @@ func TestDeleteChannel(t *testing.T) {
t.Fatal("should have failed - channel already deleted")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.LoginSystemAdmin()
th.LinkUserToTeam(th.BasicUser, team)
@@ -1320,10 +1130,10 @@ func TestDeleteChannel(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.LoginSystemAdmin()
@@ -1354,67 +1164,6 @@ func TestDeleteChannel(t *testing.T) {
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))
th.UpdateUserToTeamAdmin(th.BasicUser, team)
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
th.App.InvalidateAllCaches()
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
t.Fatal(err)
}
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
t.Fatal(err)
}
th.UpdateUserToNonTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
})
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 team admin")
}
if _, err := Client.DeleteChannel(channel3.Id); err == nil {
t.Fatal("should have errored not team admin")
}
th.UpdateUserToTeamAdmin(th.BasicUser, team)
Client.Logout()
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
Client.SetTeamId(team.Id)
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
t.Fatal(err)
}
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
})
th.LoginSystemAdmin()
channel2 = th.CreateChannel(Client, team)
channel3 = th.CreatePrivateChannel(Client, team)
Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser.Id))
@@ -1441,23 +1190,6 @@ func TestDeleteChannel(t *testing.T) {
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
t.Fatal(err)
}
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
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(err)
}
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
t.Fatal(err)
}
}
func TestGetChannelStats(t *testing.T) {
@@ -1533,21 +1265,14 @@ func TestAddChannelMember(t *testing.T) {
t.Fatal("Should have errored, user not on team")
}
// Test policy does not apply to TE.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
channel3 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel3 = Client.Must(th.SystemAdminClient.CreateChannel(channel3)).Data.(*model.Channel)
Client.Must(th.SystemAdminClient.AddChannelMember(channel3.Id, user1.Id))
if _, err := Client.AddChannelMember(channel3.Id, user2.Id); err != nil {
t.Fatal(err)
}
// Add a license
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
// Check that a regular channel user can add other users.
channel4 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -1557,10 +1282,10 @@ func TestAddChannelMember(t *testing.T) {
t.Fatal(err)
}
// Test with CHANNEL_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_ADMIN_ROLE_ID)
channel5 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel5 = Client.Must(th.SystemAdminClient.CreateChannel(channel5)).Data.(*model.Channel)
@@ -1571,47 +1296,10 @@ func TestAddChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user1, channel5)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
if _, err := Client.AddChannelMember(channel5.Id, user2.Id); err != nil {
t.Fatal(err)
}
// Test with TEAM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
})
channel6 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel6 = Client.Must(th.SystemAdminClient.CreateChannel(channel6)).Data.(*model.Channel)
Client.Must(th.SystemAdminClient.AddChannelMember(channel6.Id, user1.Id))
if _, err := Client.AddChannelMember(channel6.Id, user2.Id); err == nil {
t.Fatal("Should have failed due to permissions")
}
th.UpdateUserToTeamAdmin(user1, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
if _, err := Client.AddChannelMember(channel6.Id, user2.Id); err != nil {
t.Fatal(err)
}
// Test with SYSTEM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
})
channel7 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel7 = Client.Must(th.SystemAdminClient.CreateChannel(channel7)).Data.(*model.Channel)
Client.Must(th.SystemAdminClient.AddChannelMember(channel7.Id, user1.Id))
if _, err := Client.AddChannelMember(channel7.Id, user2.Id); err == nil {
t.Fatal("Should have failed due to permissions")
}
if _, err := th.SystemAdminClient.AddChannelMember(channel7.Id, user2.Id); err != nil {
t.Fatal(err)
}
}
func TestRemoveChannelMember(t *testing.T) {
@@ -1683,22 +1371,14 @@ func TestRemoveChannelMember(t *testing.T) {
th.LoginBasic()
// Test policy does not apply to TE.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
channel3 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel3 = Client.Must(th.SystemAdminClient.CreateChannel(channel3)).Data.(*model.Channel)
Client.Must(th.SystemAdminClient.AddChannelMember(channel3.Id, user1.Id))
Client.Must(th.SystemAdminClient.AddChannelMember(channel3.Id, user2.Id))
if _, err := Client.RemoveChannelMember(channel3.Id, user2.Id); err != nil {
t.Fatal(err)
}
// Add a license
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
// Check that a regular channel user can remove other users.
channel4 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -1709,10 +1389,10 @@ func TestRemoveChannelMember(t *testing.T) {
t.Fatal(err)
}
// Test with CHANNEL_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_ADMIN_ROLE_ID)
channel5 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel5 = Client.Must(th.SystemAdminClient.CreateChannel(channel5)).Data.(*model.Channel)
@@ -1724,49 +1404,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user1, channel5)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
if _, err := Client.RemoveChannelMember(channel5.Id, user2.Id); err != nil {
t.Fatal(err)
}
// Test with TEAM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
})
channel6 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel6 = Client.Must(th.SystemAdminClient.CreateChannel(channel6)).Data.(*model.Channel)
Client.Must(th.SystemAdminClient.AddChannelMember(channel6.Id, user1.Id))
Client.Must(th.SystemAdminClient.AddChannelMember(channel6.Id, user2.Id))
if _, err := Client.RemoveChannelMember(channel6.Id, user2.Id); err == nil {
t.Fatal("Should have failed due to permissions")
}
th.UpdateUserToTeamAdmin(user1, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
if _, err := Client.RemoveChannelMember(channel6.Id, user2.Id); err != nil {
t.Fatal(err)
}
// Test with SYSTEM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
})
channel7 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel7 = Client.Must(th.SystemAdminClient.CreateChannel(channel7)).Data.(*model.Channel)
Client.Must(th.SystemAdminClient.AddChannelMember(channel7.Id, user1.Id))
Client.Must(th.SystemAdminClient.AddChannelMember(channel7.Id, user2.Id))
if _, err := Client.RemoveChannelMember(channel7.Id, user2.Id); err == nil {
t.Fatal("Should have failed due to permissions")
}
if _, err := th.SystemAdminClient.RemoveChannelMember(channel7.Id, user2.Id); err != nil {
t.Fatal(err)
}
}
func TestUpdateNotifyProps(t *testing.T) {

Просмотреть файл

@@ -202,13 +202,10 @@ func TestDeleteCommand(t *testing.T) {
Client := th.SystemAdminClient
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
onlyAdminIntegration := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = enableCommands })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = onlyAdminIntegration })
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
cmd := &model.Command{URL: "http://nowhere.com", Method: model.COMMAND_METHOD_POST, Trigger: "trigger"}
cmd = Client.Must(Client.CreateCommand(cmd)).Data.(*model.Command)

Просмотреть файл

@@ -88,7 +88,12 @@ func TestOAuthRegisterApp(t *testing.T) {
t.Fatal("should have failed. not enough permissions")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.LoginBasic()
@@ -210,7 +215,12 @@ func TestOAuthGetAppsByUser(t *testing.T) {
t.Fatal("Should have failed.")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
if result, err := Client.GetOAuthAppsByUser(); err != nil {
t.Fatal(err)
@@ -250,7 +260,9 @@ func TestOAuthGetAppsByUser(t *testing.T) {
user := &model.User{Email: strings.ToLower("test+"+model.NewId()) + "@simulator.amazonses.com", Password: "hello1", Username: "n" + model.NewId(), EmailVerified: true}
ruser := Client.Must(AdminClient.CreateUser(user, "")).Data.(*model.User)
th.App.UpdateUserRoles(ruser.Id, "", false)
if _, err := th.App.UpdateUserRoles(ruser.Id, "", false); err != nil {
t.Fatal(err)
}
Client.Logout()
Client.Login(user.Email, user.Password)
@@ -437,7 +449,13 @@ func TestOAuthDeleteApp(t *testing.T) {
}
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
oauthApp := &model.OAuthApp{Name: "TestApp5" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -492,13 +510,17 @@ func TestOAuthAccessToken(t *testing.T) {
Client := th.BasicClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
oauthApp := &model.OAuthApp{Name: "TestApp5" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
oauthApp = Client.Must(Client.RegisterApp(oauthApp)).Data.(*model.OAuthApp)
@@ -739,7 +761,13 @@ func TestOAuthComplete(t *testing.T) {
// We are going to use mattermost as the provider emulating gitlab
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
oauthApp := &model.OAuthApp{
Name: "TestApp5" + model.NewId(),

Просмотреть файл

@@ -385,7 +385,14 @@ func TestUpdatePost(t *testing.T) {
Client := th.BasicClient
channel1 := th.BasicChannel
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS })
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.App.SetLicense(model.NewTestLicense())
th.AddPermissionToRole(model.PERMISSION_EDIT_POST.Id, model.CHANNEL_USER_ROLE_ID)
post1 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"}
rpost1, err := Client.CreatePost(post1)
@@ -454,8 +461,7 @@ func TestUpdatePost(t *testing.T) {
}
// Test licensed policy controls for edit post
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_NEVER })
th.RemovePermissionFromRole(model.PERMISSION_EDIT_POST.Id, model.CHANNEL_USER_ROLE_ID)
post4 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id}
rpost4, err := Client.CreatePost(post4)
@@ -468,7 +474,7 @@ func TestUpdatePost(t *testing.T) {
t.Fatal("shouldn't have been able to update a message when not allowed")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_TIME_LIMIT })
th.AddPermissionToRole(model.PERMISSION_EDIT_POST.Id, model.CHANNEL_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.PostEditTimeLimit = 1 }) //seconds
post5 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id}
@@ -944,8 +950,6 @@ func TestDeletePosts(t *testing.T) {
channel1 := th.BasicChannel
team1 := th.BasicTeam
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_ALL })
time.Sleep(10 * time.Millisecond)
post1 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"}
post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post)
@@ -998,8 +1002,11 @@ func TestDeletePosts(t *testing.T) {
t.Fatal(err)
}
// Test licensed policy controls for delete post
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
@@ -1011,9 +1018,8 @@ func TestDeletePosts(t *testing.T) {
SystemAdminClient.Must(SystemAdminClient.DeletePost(channel1.Id, post4b.Id))
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_TEAM_ADMIN
})
th.RemovePermissionFromRole(model.PERMISSION_DELETE_POST.Id, model.CHANNEL_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_POST.Id, model.TEAM_ADMIN_ROLE_ID)
th.LoginBasic()
@@ -1034,40 +1040,6 @@ func TestDeletePosts(t *testing.T) {
Client.Must(Client.DeletePost(channel1.Id, post5a.Id))
SystemAdminClient.Must(SystemAdminClient.DeletePost(channel1.Id, post5b.Id))
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_SYSTEM_ADMIN
})
th.LoginBasic()
time.Sleep(10 * time.Millisecond)
post6a := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"}
post6a = Client.Must(Client.CreatePost(post6a)).Data.(*model.Post)
if _, err := Client.DeletePost(channel1.Id, post6a.Id); err == nil {
t.Fatal(err)
}
th.LoginBasic2()
if _, err := Client.DeletePost(channel1.Id, post6a.Id); err == nil {
t.Fatal(err)
}
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
time.Sleep(10 * time.Millisecond)
post7 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"}
post7 = Client.Must(Client.CreatePost(post7)).Data.(*model.Post)
if _, err := Client.DeletePost(channel1.Id, post7.Id); err != nil {
t.Fatal(err)
}
SystemAdminClient.Must(SystemAdminClient.DeletePost(channel1.Id, post6a.Id))
}
func TestEmailMention(t *testing.T) {

Просмотреть файл

@@ -36,8 +36,8 @@ func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_ADD_REACTION) {
c.SetPermissionError(model.PERMISSION_ADD_REACTION)
return
}
@@ -87,8 +87,8 @@ func deleteReaction(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_REMOVE_REACTION) {
c.SetPermissionError(model.PERMISSION_REMOVE_REACTION)
return
}

Просмотреть файл

@@ -116,15 +116,13 @@ func getAll(c *Context, w http.ResponseWriter, r *http.Request) {
func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
invites := model.InvitesFromJson(r.Body)
if c.App.License() != nil && !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_INVITE_USER) {
errorId := ""
if *c.App.Config().TeamSettings.RestrictTeamInvite == model.PERMISSIONS_SYSTEM_ADMIN {
errorId = "api.team.invite_members.restricted_system_admin.app_error"
} else if *c.App.Config().TeamSettings.RestrictTeamInvite == model.PERMISSIONS_TEAM_ADMIN {
errorId = "api.team.invite_members.restricted_team_admin.app_error"
}
if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_INVITE_USER) {
c.SetPermissionError(model.PERMISSION_INVITE_USER)
return
}
c.Err = model.NewAppError("inviteMembers", errorId, nil, "", http.StatusForbidden)
if !c.App.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_ADD_USER_TO_TEAM) {
c.SetPermissionError(model.PERMISSION_INVITE_USER)
return
}

Просмотреть файл

@@ -139,17 +139,17 @@ func TestAddUserToTeam(t *testing.T) {
t.Fatal(err)
}
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Set the config so that only team admins can add a user to a team.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
// Test without the EE license to see that the permission restriction is ignored.
user3 := th.CreateUser(th.BasicClient)
if _, err := th.BasicClient.AddUserToTeam(th.BasicTeam.Id, user3.Id); err != nil {
t.Fatal(err)
}
// Add an EE license.
th.App.SetLicense(model.NewTestLicense())
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
// Check that a regular user can't add someone to the team.
user4 := th.CreateUser(th.BasicClient)
@@ -160,28 +160,17 @@ func TestAddUserToTeam(t *testing.T) {
// Should work as team admin.
th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
// Change permission level to team user
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
user5 := th.CreateUser(th.BasicClient)
if _, err := th.BasicClient.AddUserToTeam(th.BasicTeam.Id, user5.Id); err != nil {
t.Fatal(err)
}
// Change permission level to System Admin
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
// Should not work as team admin.
user6 := th.CreateUser(th.BasicClient)
if _, err := th.BasicClient.AddUserToTeam(th.BasicTeam.Id, user6.Id); err == nil {
t.Fatal("should have failed due to permissions error")
}
// Should work as system admin.
user7 := th.CreateUser(th.BasicClient)
if _, err := th.SystemAdminClient.AddUserToTeam(th.BasicTeam.Id, user7.Id); err != nil {
t.Fatal(err)
}
}
func TestRemoveUserFromTeam(t *testing.T) {
@@ -515,7 +504,6 @@ func TestInviteMembers(t *testing.T) {
defer th.TearDown()
Client := th.BasicClient
SystemAdminClient := th.SystemAdminClient
team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)
@@ -546,17 +534,21 @@ func TestInviteMembers(t *testing.T) {
t.Fatal("Should have errored out on no invites to send")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Set the config so that only team admins can add a user to a team.
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
th.LoginBasic2()
th.LinkUserToTeam(th.BasicUser2, team)
if _, err := Client.InviteMembers(invites); err != nil {
t.Fatal(err)
}
th.App.SetLicense(model.NewTestLicense())
if _, err := Client.InviteMembers(invites); err == nil {
t.Fatal("should have errored not team admin and licensed")
}
@@ -569,18 +561,6 @@ func TestInviteMembers(t *testing.T) {
if _, err := Client.InviteMembers(invites); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
if _, err := Client.InviteMembers(invites); err == nil {
t.Fatal("should have errored not system admin and licensed")
}
th.LinkUserToTeam(th.SystemAdminUser, team)
if _, err := SystemAdminClient.InviteMembers(invites); err != nil {
t.Fatal(err)
}
}
func TestUpdateTeamDisplayName(t *testing.T) {

Просмотреть файл

@@ -24,8 +24,16 @@ func TestCreateIncomingHook(t *testing.T) {
user2 := th.CreateUser(Client)
th.LinkUserToTeam(user2, team)
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
@@ -91,7 +99,8 @@ func TestCreateIncomingHook(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
if _, err := Client.CreateIncomingWebhook(hook); err != nil {
t.Fatal(err)
@@ -130,7 +139,12 @@ func TestUpdateIncomingHook(t *testing.T) {
th.UpdateUserToTeamAdmin(user3, team2)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
hook := createIncomingWebhook(channel1.Id, Client, t)
@@ -213,7 +227,9 @@ func TestUpdateIncomingHook(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
t.Run("UpdateHookOfSameUser", func(t *testing.T) {
sameUserHook := &model.IncomingWebhook{ChannelId: channel1.Id, UserId: user2.Id}
@@ -235,7 +251,8 @@ func TestUpdateIncomingHook(t *testing.T) {
})
})
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
Client.Logout()
th.UpdateUserToTeamAdmin(user2, team)
@@ -318,7 +335,15 @@ func TestListIncomingHooks(t *testing.T) {
th.LinkUserToTeam(user2, team)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook1 := &model.IncomingWebhook{ChannelId: channel1.Id}
hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook)
@@ -344,7 +369,8 @@ func TestListIncomingHooks(t *testing.T) {
t.Fatal("should have errored - not system/team admin")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
if _, err := Client.ListIncomingWebhooks(); err != nil {
t.Fatal(err)
@@ -368,7 +394,15 @@ func TestDeleteIncomingHook(t *testing.T) {
th.LinkUserToTeam(user2, team)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
@@ -401,7 +435,8 @@ func TestDeleteIncomingHook(t *testing.T) {
t.Fatal("should have failed - not system/team admin")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
t.Fatal("should have failed - not creator or team admin")
@@ -437,7 +472,15 @@ func TestCreateOutgoingHook(t *testing.T) {
th.LinkUserToTeam(user3, team2)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
@@ -507,7 +550,8 @@ func TestCreateOutgoingHook(t *testing.T) {
t.Fatal("should have failed - not system/team admin")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
if _, err := Client.CreateOutgoingWebhook(hook); err != nil {
t.Fatal(err)
@@ -539,7 +583,15 @@ func TestListOutgoingHooks(t *testing.T) {
th.LinkUserToTeam(user2, team)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook)
@@ -565,7 +617,8 @@ func TestListOutgoingHooks(t *testing.T) {
t.Fatal("should have failed - not system/team admin")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
if _, err := Client.ListOutgoingWebhooks(); err != nil {
t.Fatal(err)
@@ -595,7 +648,15 @@ func TestUpdateOutgoingHook(t *testing.T) {
th.LinkUserToTeam(user3, team2)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"cats"}, Client, t)
createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"dogs"}, Client, t)
@@ -668,14 +729,17 @@ func TestUpdateOutgoingHook(t *testing.T) {
t.Fatal("should have failed - user does not have permissions to manage webhooks")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook2 := createOutgoingWebhook(channel1.Id, []string{"http://nowhereelse.com"}, []string{"dogs"}, Client, t)
if _, err := Client.UpdateOutgoingWebhook(hook2); err != nil {
t.Fatal("update webhook failed when admin only integrations is turned off")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
Client.Logout()
th.LinkUserToTeam(user3, team)
@@ -762,7 +826,15 @@ func TestDeleteOutgoingHook(t *testing.T) {
th.LinkUserToTeam(user2, team)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -795,7 +867,8 @@ func TestDeleteOutgoingHook(t *testing.T) {
t.Fatal("should have failed - not system/team admin")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
t.Fatal("should have failed - not creator or team admin")
@@ -829,7 +902,15 @@ func TestRegenOutgoingHookToken(t *testing.T) {
th.LinkUserToTeam(user3, team2)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -863,7 +944,8 @@ func TestRegenOutgoingHookToken(t *testing.T) {
t.Fatal("should have failed - not system/team admin")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)

Просмотреть файл

@@ -98,6 +98,8 @@ type Routes struct {
Reactions *mux.Router // 'api/v4/reactions'
Roles *mux.Router // 'api/v4/roles'
Emojis *mux.Router // 'api/v4/emoji'
Emoji *mux.Router // 'api/v4/emoji/{emoji_id:[A-Za-z0-9]+}'
EmojiByName *mux.Router // 'api/v4/emoji/name/{emoji_name:[A-Za-z0-9_-\.]+}'
@@ -196,6 +198,8 @@ func Init(a *app.App, root *mux.Router, full bool) *API {
api.BaseRoutes.OpenGraph = api.BaseRoutes.ApiRoot.PathPrefix("/opengraph").Subrouter()
api.BaseRoutes.Roles = api.BaseRoutes.ApiRoot.PathPrefix("/roles").Subrouter()
api.BaseRoutes.Image = api.BaseRoutes.ApiRoot.PathPrefix("/image").Subrouter()
api.InitUser()
@@ -223,6 +227,7 @@ func Init(a *app.App, root *mux.Router, full bool) *API {
api.InitWebrtc()
api.InitOpenGraph()
api.InitPlugin()
api.InitRole()
api.InitImage()
root.Handle("/api/v4/{anything:.*}", http.HandlerFunc(Handle404))

Просмотреть файл

@@ -122,6 +122,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
Init(th.App, th.App.Srv.Router, true)
wsapi.Init(th.App, th.App.Srv.WebSocketRouter)
th.App.Srv.Store.MarkSystemRanUnitTests()
th.App.DoAdvancedPermissionsMigration()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
@@ -804,3 +805,114 @@ func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Tea
}
utils.EnableDebugLogForTest()
}
func (me *TestHelper) SaveDefaultRolePermissions() map[string][]string {
utils.DisableDebugLogForTest()
results := make(map[string][]string)
for _, roleName := range []string{
"system_user",
"system_admin",
"team_user",
"team_admin",
"channel_user",
"channel_admin",
} {
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
results[roleName] = role.Permissions
}
utils.EnableDebugLogForTest()
return results
}
func (me *TestHelper) RestoreDefaultRolePermissions(data map[string][]string) {
utils.DisableDebugLogForTest()
for roleName, permissions := range data {
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
if strings.Join(role.Permissions, " ") == strings.Join(permissions, " ") {
continue
}
role.Permissions = permissions
_, err2 := me.App.UpdateRole(role)
if err2 != nil {
utils.EnableDebugLogForTest()
panic(err2)
}
}
utils.EnableDebugLogForTest()
}
func (me *TestHelper) RemovePermissionFromRole(permission string, roleName string) {
utils.DisableDebugLogForTest()
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
var newPermissions []string
for _, p := range role.Permissions {
if p != permission {
newPermissions = append(newPermissions, p)
}
}
if strings.Join(role.Permissions, " ") == strings.Join(newPermissions, " ") {
utils.EnableDebugLogForTest()
return
}
role.Permissions = newPermissions
_, err2 := me.App.UpdateRole(role)
if err2 != nil {
utils.EnableDebugLogForTest()
panic(err2)
}
utils.EnableDebugLogForTest()
}
func (me *TestHelper) AddPermissionToRole(permission string, roleName string) {
utils.DisableDebugLogForTest()
role, err1 := me.App.GetRoleByName(roleName)
if err1 != nil {
utils.EnableDebugLogForTest()
panic(err1)
}
for _, existingPermission := range role.Permissions {
if existingPermission == permission {
utils.EnableDebugLogForTest()
return
}
}
role.Permissions = append(role.Permissions, permission)
_, err2 := me.App.UpdateRole(role)
if err2 != nil {
utils.EnableDebugLogForTest()
panic(err2)
}
utils.EnableDebugLogForTest()
}

Просмотреть файл

@@ -7,6 +7,7 @@ import (
"net/http"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/model"
)

Просмотреть файл

@@ -78,12 +78,16 @@ func TestCreateChannel(t *testing.T) {
_, resp = Client.CreateChannel(private)
CheckForbiddenStatus(t, resp)
th.LoginBasic()
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Check permissions with policy config changes
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
th.AddPermissionToRole(model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.LoginBasic()
channel.Name = GenerateTestChannelName()
_, resp = Client.CreateChannel(channel)
@@ -93,10 +97,10 @@ func TestCreateChannel(t *testing.T) {
_, resp = Client.CreateChannel(private)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_TEAM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN
})
th.AddPermissionToRole(model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id, model.TEAM_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
_, resp = Client.CreateChannel(channel)
CheckForbiddenStatus(t, resp)
@@ -122,46 +126,7 @@ func TestCreateChannel(t *testing.T) {
_, resp = th.SystemAdminClient.CreateChannel(private)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
})
th.LoginBasic()
_, resp = Client.CreateChannel(channel)
CheckForbiddenStatus(t, resp)
_, resp = Client.CreateChannel(private)
CheckForbiddenStatus(t, resp)
th.LoginTeamAdmin()
_, resp = Client.CreateChannel(channel)
CheckForbiddenStatus(t, resp)
_, resp = Client.CreateChannel(private)
CheckForbiddenStatus(t, resp)
channel.Name = GenerateTestChannelName()
_, resp = th.SystemAdminClient.CreateChannel(channel)
CheckNoError(t, resp)
private.Name = GenerateTestChannelName()
_, resp = th.SystemAdminClient.CreateChannel(private)
CheckNoError(t, resp)
// Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil)
channel.Name = GenerateTestChannelName()
_, resp = Client.CreateChannel(channel)
CheckNoError(t, resp)
private.Name = GenerateTestChannelName()
_, resp = Client.CreateChannel(private)
CheckNoError(t, resp)
// Test posting Garbage
if r, err := Client.DoApiPost("/channels", "garbage"); err == nil {
t.Fatal("should have errored")
} else {
@@ -805,12 +770,6 @@ func TestDeleteChannel(t *testing.T) {
_, resp = Client.DeleteChannel(publicChannel3.Id)
CheckNoError(t, resp)
// successful delete by TeamAdmin of channel created by user
publicChannel4 := th.CreatePublicChannel()
th.LoginTeamAdmin()
_, resp = Client.DeleteChannel(publicChannel4.Id)
CheckNoError(t, resp)
// default channel cannot be deleted.
defaultChannel, _ := th.App.GetChannelByName(model.DEFAULT_CHANNEL, team.Id)
pass, resp = Client.DeleteChannel(defaultChannel.Id)
@@ -864,9 +823,14 @@ func TestDeleteChannel(t *testing.T) {
th.InitBasic().InitSystemAdmin()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
Client = th.Client
team = th.BasicTeam
@@ -887,10 +851,11 @@ func TestDeleteChannel(t *testing.T) {
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
})
// Restrict permissions to Channel Admins
th.RemovePermissionFromRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.CHANNEL_ADMIN_ROLE_ID)
// channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
@@ -917,115 +882,9 @@ func TestDeleteChannel(t *testing.T) {
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckNoError(t, resp)
// // channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
privateChannel7 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
th.App.AddUserToChannel(user, publicChannel6)
th.App.AddUserToChannel(user, privateChannel7)
th.App.AddUserToChannel(user2, privateChannel7)
// successful delete by team admin
th.UpdateUserToTeamAdmin(user, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckNoError(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
})
th.UpdateUserToNonTeamAdmin(user, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
// channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
privateChannel7 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
th.App.AddUserToChannel(user, publicChannel6)
th.App.AddUserToChannel(user, privateChannel7)
th.App.AddUserToChannel(user2, privateChannel7)
// cannot delete by user
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckForbiddenStatus(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckForbiddenStatus(t, resp)
// // cannot delete by channel admin
th.MakeUserChannelAdmin(user, publicChannel6)
th.MakeUserChannelAdmin(user, privateChannel7)
th.App.Srv.Store.Channel().ClearCaches()
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckForbiddenStatus(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckForbiddenStatus(t, resp)
// successful delete by team admin
th.UpdateUserToTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckNoError(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
})
// channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
privateChannel7 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
th.App.AddUserToChannel(user, publicChannel6)
th.App.AddUserToChannel(user, privateChannel7)
th.App.AddUserToChannel(user2, privateChannel7)
// cannot delete by user
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckForbiddenStatus(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckForbiddenStatus(t, resp)
// cannot delete by channel admin
th.MakeUserChannelAdmin(user, publicChannel6)
th.MakeUserChannelAdmin(user, privateChannel7)
th.App.Srv.Store.Channel().ClearCaches()
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckForbiddenStatus(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckForbiddenStatus(t, resp)
// cannot delete by team admin
th.UpdateUserToTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
_, resp = Client.DeleteChannel(publicChannel6.Id)
CheckForbiddenStatus(t, resp)
_, resp = Client.DeleteChannel(privateChannel7.Id)
CheckForbiddenStatus(t, resp)
// successful delete by SystemAdmin
_, resp = th.SystemAdminClient.DeleteChannel(publicChannel6.Id)
CheckNoError(t, resp)
_, resp = th.SystemAdminClient.DeleteChannel(privateChannel7.Id)
CheckNoError(t, resp)
// Make sure team admins don't have permission to delete channels.
th.RemovePermissionFromRole(model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id, model.CHANNEL_ADMIN_ROLE_ID)
// last member of a public channel should have required permission to delete
publicChannel6 = th.CreateChannelWithClient(th.Client, model.CHANNEL_OPEN)
@@ -1768,25 +1627,13 @@ func TestAddChannelMember(t *testing.T) {
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
// Test policy does not apply to TE.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel()
_, resp = Client.AddChannelMember(privateChannel.Id, user.Id)
CheckNoError(t, resp)
Client.Logout()
Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
CheckNoError(t, resp)
Client.Logout()
// Add a license
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
// Check that a regular channel user can add other users.
Client.Login(user2.Username, user2.Password)
@@ -1800,10 +1647,9 @@ func TestAddChannelMember(t *testing.T) {
CheckNoError(t, resp)
Client.Logout()
// Test with CHANNEL_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
// Restrict the permission for adding users to Channel Admins
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel()
@@ -1818,56 +1664,11 @@ func TestAddChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user, privateChannel)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
CheckNoError(t, resp)
Client.Logout()
// Test with TEAM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
})
Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel()
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user.Id)
CheckNoError(t, resp)
Client.Logout()
Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
CheckForbiddenStatus(t, resp)
Client.Logout()
th.UpdateUserToTeamAdmin(user, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
CheckNoError(t, resp)
Client.Logout()
// Test with SYSTEM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
})
Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel()
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user.Id)
CheckNoError(t, resp)
Client.Logout()
Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
CheckForbiddenStatus(t, resp)
Client.Logout()
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user3.Id)
CheckNoError(t, resp)
}
func TestRemoveChannelMember(t *testing.T) {
@@ -1929,11 +1730,15 @@ func TestRemoveChannelMember(t *testing.T) {
th.UpdateUserToNonTeamAdmin(user1, team)
th.App.InvalidateAllCaches()
// Test policy does not apply to TE.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
// Check that a regular channel user can remove other users.
privateChannel := th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
CheckNoError(t, resp)
@@ -1943,24 +1748,9 @@ func TestRemoveChannelMember(t *testing.T) {
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
// Add a license
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
// Check that a regular channel user can remove other users.
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
CheckNoError(t, resp)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
// Test with CHANNEL_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
})
// Restrict the permission for adding users to Channel Admins
th.AddPermissionToRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, model.CHANNEL_USER_ROLE_ID)
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
@@ -1973,48 +1763,9 @@ func TestRemoveChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user1, privateChannel)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
// Test with TEAM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
})
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
CheckNoError(t, resp)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckForbiddenStatus(t, resp)
th.UpdateUserToTeamAdmin(user1, team)
th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
// Test with SYSTEM_ADMIN level permission.
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
})
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
CheckNoError(t, resp)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckForbiddenStatus(t, resp)
_, resp = th.SystemAdminClient.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp)
}
func TestAutocompleteChannels(t *testing.T) {

Просмотреть файл

@@ -636,3 +636,26 @@ func (c *Context) RequireActionId() *Context {
}
return c
}
func (c *Context) RequireRoleId() *Context {
if c.Err != nil {
return c
}
if len(c.Params.RoleId) != 26 {
c.SetInvalidUrlParam("role_id")
}
return c
}
func (c *Context) RequireRoleName() *Context {
if c.Err != nil {
return c
}
if !model.IsValidRoleName(c.Params.RoleName) {
c.SetInvalidUrlParam("role_name")
}
return c
}

Просмотреть файл

@@ -18,6 +18,14 @@ func TestCreateOAuthApp(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}, IsTrusted: true}
@@ -34,11 +42,15 @@ func TestCreateOAuthApp(t *testing.T) {
t.Fatal("trusted did no match")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.CreateOAuthApp(oapp)
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
rapp, resp = Client.CreateOAuthApp(oapp)
CheckNoError(t, resp)
CheckCreatedStatus(t, resp)
@@ -77,6 +89,13 @@ func TestUpdateOAuthApp(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
oapp := &model.OAuthApp{
@@ -155,7 +174,9 @@ func TestUpdateOAuthApp(t *testing.T) {
th.LoginBasic()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.UpdateOAuthApp(oapp)
CheckForbiddenStatus(t, resp)
@@ -164,6 +185,7 @@ func TestUpdateOAuthApp(t *testing.T) {
CheckNotFoundStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
_, resp = AdminClient.UpdateOAuthApp(oapp)
CheckNotImplementedStatus(t, resp)
@@ -182,8 +204,14 @@ func TestGetOAuthApps(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -226,7 +254,8 @@ func TestGetOAuthApps(t *testing.T) {
t.Fatal("wrong apps returned")
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.GetOAuthApps(0, 1000)
CheckForbiddenStatus(t, resp)
@@ -247,8 +276,14 @@ func TestGetOAuthApp(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -287,7 +322,8 @@ func TestGetOAuthApp(t *testing.T) {
_, resp = Client.GetOAuthApp(rapp.Id)
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.GetOAuthApp(rapp2.Id)
CheckForbiddenStatus(t, resp)
@@ -314,8 +350,14 @@ func TestGetOAuthAppInfo(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -354,7 +396,8 @@ func TestGetOAuthAppInfo(t *testing.T) {
_, resp = Client.GetOAuthAppInfo(rapp.Id)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.GetOAuthAppInfo(rapp2.Id)
CheckNoError(t, resp)
@@ -381,8 +424,14 @@ func TestDeleteOAuthApp(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -416,7 +465,9 @@ func TestDeleteOAuthApp(t *testing.T) {
_, resp = Client.DeleteOAuthApp(rapp2.Id)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.DeleteOAuthApp(rapp.Id)
CheckForbiddenStatus(t, resp)
@@ -441,8 +492,14 @@ func TestRegenerateOAuthAppSecret(t *testing.T) {
Client := th.Client
AdminClient := th.SystemAdminClient
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Grant permission to regular users.
th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -480,7 +537,9 @@ func TestRegenerateOAuthAppSecret(t *testing.T) {
_, resp = Client.RegenerateOAuthAppSecret(rapp2.Id)
CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
_, resp = Client.RegenerateOAuthAppSecret(rapp.Id)
CheckForbiddenStatus(t, resp)

Просмотреть файл

@@ -45,6 +45,8 @@ type ApiParams struct {
JobId string
JobType string
ActionId string
RoleId string
RoleName string
Page int
PerPage int
LogsPerPage int
@@ -157,6 +159,14 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams {
params.ActionId = val
}
if val, ok := props["role_id"]; ok {
params.RoleId = val
}
if val, ok := props["role_name"]; ok {
params.RoleName = val
}
if val, err := strconv.Atoi(query.Get("page")); err != nil || val < 0 {
params.Page = PAGE_DEFAULT
} else {

Просмотреть файл

@@ -130,7 +130,6 @@ func testCreatePostWithOutgoingHook(
channel := th.BasicChannel
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
})
@@ -477,7 +476,6 @@ func TestUpdatePost(t *testing.T) {
channel := th.BasicChannel
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS })
post := &model.Post{ChannelId: channel.Id, Message: "zz" + model.NewId() + "a"}
rpost, resp := Client.CreatePost(post)
@@ -549,7 +547,6 @@ func TestPatchPost(t *testing.T) {
channel := th.BasicChannel
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS })
post := &model.Post{
ChannelId: channel.Id,

Просмотреть файл

@@ -32,8 +32,8 @@ func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionToChannelByPost(c.Session, reaction.PostId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
if !c.App.SessionHasPermissionToChannelByPost(c.Session, reaction.PostId, model.PERMISSION_ADD_REACTION) {
c.SetPermissionError(model.PERMISSION_ADD_REACTION)
return
}
@@ -82,13 +82,13 @@ func deleteReaction(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionToChannelByPost(c.Session, c.Params.PostId, model.PERMISSION_READ_CHANNEL) {
c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
if !c.App.SessionHasPermissionToChannelByPost(c.Session, c.Params.PostId, model.PERMISSION_REMOVE_REACTION) {
c.SetPermissionError(model.PERMISSION_REMOVE_REACTION)
return
}
if c.Params.UserId != c.Session.UserId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
if c.Params.UserId != c.Session.UserId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_REMOVE_OTHERS_REACTIONS) {
c.SetPermissionError(model.PERMISSION_REMOVE_OTHERS_REACTIONS)
return
}

Просмотреть файл

@@ -19,116 +19,159 @@ func TestSaveReaction(t *testing.T) {
userId := th.BasicUser.Id
postId := th.BasicPost.Id
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
reaction := &model.Reaction{
UserId: userId,
PostId: postId,
EmojiName: "smile",
}
rr, resp := Client.SaveReaction(reaction)
CheckNoError(t, resp)
t.Run("successful-reaction", func(t *testing.T) {
rr, resp := Client.SaveReaction(reaction)
CheckNoError(t, resp)
if rr.UserId != reaction.UserId {
t.Fatal("UserId did not match")
}
if rr.UserId != reaction.UserId {
t.Fatal("UserId did not match")
}
if rr.PostId != reaction.PostId {
t.Fatal("PostId did not match")
}
if rr.PostId != reaction.PostId {
t.Fatal("PostId did not match")
}
if rr.EmojiName != reaction.EmojiName {
t.Fatal("EmojiName did not match")
}
if rr.EmojiName != reaction.EmojiName {
t.Fatal("EmojiName did not match")
}
if rr.CreateAt == 0 {
t.Fatal("CreateAt should exist")
}
if rr.CreateAt == 0 {
t.Fatal("CreateAt should exist")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 1 {
t.Fatal("didn't save reaction correctly")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 1 {
t.Fatal("didn't save reaction correctly")
}
})
// saving a duplicate reaction
rr, resp = Client.SaveReaction(reaction)
CheckNoError(t, resp)
t.Run("duplicated-reaction", func(t *testing.T) {
_, resp := Client.SaveReaction(reaction)
CheckNoError(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 1 {
t.Fatal("should have not save duplicated reaction")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 1 {
t.Fatal("should have not save duplicated reaction")
}
})
reaction.EmojiName = "sad"
t.Run("save-second-reaction", func(t *testing.T) {
reaction.EmojiName = "sad"
rr, resp = Client.SaveReaction(reaction)
CheckNoError(t, resp)
rr, resp := Client.SaveReaction(reaction)
CheckNoError(t, resp)
if rr.EmojiName != reaction.EmojiName {
t.Fatal("EmojiName did not match")
}
if rr.EmojiName != reaction.EmojiName {
t.Fatal("EmojiName did not match")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 2 {
t.Fatal("should have save multiple reactions")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 2 {
t.Fatal("should have save multiple reactions")
}
})
// saving special case
reaction.EmojiName = "+1"
t.Run("saving-special-case", func(t *testing.T) {
reaction.EmojiName = "+1"
rr, resp = Client.SaveReaction(reaction)
CheckNoError(t, resp)
rr, resp := Client.SaveReaction(reaction)
CheckNoError(t, resp)
if rr.EmojiName != reaction.EmojiName {
t.Fatal("EmojiName did not match")
}
if rr.EmojiName != reaction.EmojiName {
t.Fatal("EmojiName did not match")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 3 {
t.Fatal("should have save multiple reactions")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil && len(reactions) != 3 {
t.Fatal("should have save multiple reactions")
}
})
reaction.PostId = GenerateTestId()
t.Run("react-to-not-existing-post-id", func(t *testing.T) {
reaction.PostId = GenerateTestId()
_, resp = Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
})
reaction.PostId = "junk"
t.Run("react-to-not-valid-post-id", func(t *testing.T) {
reaction.PostId = "junk"
_, resp = Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
})
reaction.PostId = postId
reaction.UserId = GenerateTestId()
t.Run("react-as-not-existing-user-id", func(t *testing.T) {
reaction.PostId = postId
reaction.UserId = GenerateTestId()
_, resp = Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
})
reaction.UserId = "junk"
t.Run("react-as-not-valid-user-id", func(t *testing.T) {
reaction.UserId = "junk"
_, resp = Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
})
reaction.UserId = userId
reaction.EmojiName = ""
t.Run("react-as-empty-emoji-name", func(t *testing.T) {
reaction.UserId = userId
reaction.EmojiName = ""
_, resp = Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
})
reaction.EmojiName = strings.Repeat("a", 65)
t.Run("react-as-not-valid-emoji-name", func(t *testing.T) {
reaction.EmojiName = strings.Repeat("a", 65)
_, resp = Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckBadRequestStatus(t, resp)
})
reaction.EmojiName = "smile"
otherUser := th.CreateUser()
Client.Logout()
Client.Login(otherUser.Email, otherUser.Password)
t.Run("react-as-other-user", func(t *testing.T) {
reaction.EmojiName = "smile"
otherUser := th.CreateUser()
Client.Logout()
Client.Login(otherUser.Email, otherUser.Password)
_, resp = Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
_, resp := Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
})
Client.Logout()
_, resp = Client.SaveReaction(reaction)
CheckUnauthorizedStatus(t, resp)
t.Run("react-being-not-logged-in", func(t *testing.T) {
Client.Logout()
_, resp := Client.SaveReaction(reaction)
CheckUnauthorizedStatus(t, resp)
})
_, resp = th.SystemAdminClient.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
t.Run("react-as-other-user-being-system-admin", func(t *testing.T) {
_, resp := th.SystemAdminClient.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
})
t.Run("unable-to-create-reaction-without-permissions", func(t *testing.T) {
th.LoginBasic()
th.RemovePermissionFromRole(model.PERMISSION_ADD_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
_, resp := Client.SaveReaction(reaction)
CheckForbiddenStatus(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 3 {
t.Fatal("should have not created a reactions")
}
th.AddPermissionToRole(model.PERMISSION_ADD_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
})
}
func TestGetReactions(t *testing.T) {
@@ -177,29 +220,39 @@ func TestGetReactions(t *testing.T) {
}
}
rr, resp := Client.GetReactions(postId)
CheckNoError(t, resp)
t.Run("get-reactions", func(t *testing.T) {
rr, resp := Client.GetReactions(postId)
CheckNoError(t, resp)
assert.Len(t, rr, 5)
for _, r := range reactions {
assert.Contains(t, reactions, r)
}
assert.Len(t, rr, 5)
for _, r := range reactions {
assert.Contains(t, reactions, r)
}
})
rr, resp = Client.GetReactions("junk")
CheckBadRequestStatus(t, resp)
t.Run("get-reactions-of-invalid-post-id", func(t *testing.T) {
rr, resp := Client.GetReactions("junk")
CheckBadRequestStatus(t, resp)
assert.Empty(t, rr)
assert.Empty(t, rr)
})
_, resp = Client.GetReactions(GenerateTestId())
CheckForbiddenStatus(t, resp)
t.Run("get-reactions-of-not-existing-post-id", func(t *testing.T) {
_, resp := Client.GetReactions(GenerateTestId())
CheckForbiddenStatus(t, resp)
})
Client.Logout()
t.Run("get-reactions-as-anonymous-user", func(t *testing.T) {
Client.Logout()
_, resp = Client.GetReactions(postId)
CheckUnauthorizedStatus(t, resp)
_, resp := Client.GetReactions(postId)
CheckUnauthorizedStatus(t, resp)
})
_, resp = th.SystemAdminClient.GetReactions(postId)
CheckNoError(t, resp)
t.Run("get-reactions-as-system-admin", func(t *testing.T) {
_, resp := th.SystemAdminClient.GetReactions(postId)
CheckNoError(t, resp)
})
}
func TestDeleteReaction(t *testing.T) {
@@ -216,131 +269,186 @@ func TestDeleteReaction(t *testing.T) {
EmojiName: "smile",
}
th.App.SaveReactionForPost(r1)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
t.Fatal("didn't save reaction correctly")
}
ok, resp := Client.DeleteReaction(r1)
CheckNoError(t, resp)
if !ok {
t.Fatal("should have returned true")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
t.Fatal("should have deleted reaction")
}
// deleting one reaction when a post has multiple reactions
r2 := &model.Reaction{
UserId: userId,
PostId: postId,
EmojiName: "smile-",
}
th.App.SaveReactionForPost(r1)
th.App.SaveReactionForPost(r2)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("didn't save reactions correctly")
}
_, resp = Client.DeleteReaction(r2)
CheckNoError(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
t.Fatal("should have deleted 1 reaction only")
}
// deleting one reaction of name +1
r3 := &model.Reaction{
UserId: userId,
PostId: postId,
EmojiName: "+1",
}
th.App.SaveReactionForPost(r3)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("didn't save reactions correctly")
}
_, resp = Client.DeleteReaction(r3)
CheckNoError(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
t.Fatal("should have deleted 1 reaction only")
}
// deleting a reaction made by another user
r4 := &model.Reaction{
UserId: user2Id,
PostId: postId,
EmojiName: "smile_",
}
th.LoginBasic2()
th.App.SaveReactionForPost(r4)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("didn't save reaction correctly")
}
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.LoginBasic()
t.Run("delete-reaction", func(t *testing.T) {
th.App.SaveReactionForPost(r1)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
t.Fatal("didn't save reaction correctly")
}
ok, resp = Client.DeleteReaction(r4)
CheckForbiddenStatus(t, resp)
ok, resp := Client.DeleteReaction(r1)
CheckNoError(t, resp)
if ok {
t.Fatal("should have returned false")
}
if !ok {
t.Fatal("should have returned true")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("should have not deleted a reaction")
}
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
t.Fatal("should have deleted reaction")
}
})
r1.PostId = GenerateTestId()
_, resp = Client.DeleteReaction(r1)
CheckForbiddenStatus(t, resp)
t.Run("delete-reaction-when-post-has-multiple-reactions", func(t *testing.T) {
th.App.SaveReactionForPost(r1)
th.App.SaveReactionForPost(r2)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("didn't save reactions correctly")
}
r1.PostId = "junk"
_, resp := Client.DeleteReaction(r2)
CheckNoError(t, resp)
_, resp = Client.DeleteReaction(r1)
CheckBadRequestStatus(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
t.Fatal("should have deleted 1 reaction only")
}
})
r1.PostId = postId
r1.UserId = GenerateTestId()
t.Run("delete-reaction-when-plus-one-reaction-name", func(t *testing.T) {
th.App.SaveReactionForPost(r3)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("didn't save reactions correctly")
}
_, resp = Client.DeleteReaction(r1)
CheckForbiddenStatus(t, resp)
_, resp := Client.DeleteReaction(r3)
CheckNoError(t, resp)
r1.UserId = "junk"
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 || *reactions[0] != *r1 {
t.Fatal("should have deleted 1 reaction only")
}
})
_, resp = Client.DeleteReaction(r1)
CheckBadRequestStatus(t, resp)
t.Run("delete-reaction-made-by-another-user", func(t *testing.T) {
th.LoginBasic2()
th.App.SaveReactionForPost(r4)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("didn't save reaction correctly")
}
r1.UserId = userId
r1.EmojiName = ""
th.LoginBasic()
_, resp = Client.DeleteReaction(r1)
CheckNotFoundStatus(t, resp)
ok, resp := Client.DeleteReaction(r4)
CheckForbiddenStatus(t, resp)
r1.EmojiName = strings.Repeat("a", 65)
if ok {
t.Fatal("should have returned false")
}
_, resp = Client.DeleteReaction(r1)
CheckBadRequestStatus(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 2 {
t.Fatal("should have not deleted a reaction")
}
})
Client.Logout()
r1.EmojiName = "smile"
t.Run("delete-reaction-from-not-existing-post-id", func(t *testing.T) {
r1.PostId = GenerateTestId()
_, resp := Client.DeleteReaction(r1)
CheckForbiddenStatus(t, resp)
})
_, resp = Client.DeleteReaction(r1)
CheckUnauthorizedStatus(t, resp)
t.Run("delete-reaction-from-not-valid-post-id", func(t *testing.T) {
r1.PostId = "junk"
_, resp = th.SystemAdminClient.DeleteReaction(r1)
CheckNoError(t, resp)
_, resp := Client.DeleteReaction(r1)
CheckBadRequestStatus(t, resp)
})
_, resp = th.SystemAdminClient.DeleteReaction(r4)
CheckNoError(t, resp)
t.Run("delete-reaction-from-not-existing-user-id", func(t *testing.T) {
r1.PostId = postId
r1.UserId = GenerateTestId()
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
t.Fatal("should have deleted both reactions")
}
_, resp := Client.DeleteReaction(r1)
CheckForbiddenStatus(t, resp)
})
t.Run("delete-reaction-from-not-valid-user-id", func(t *testing.T) {
r1.UserId = "junk"
_, resp := Client.DeleteReaction(r1)
CheckBadRequestStatus(t, resp)
})
t.Run("delete-reaction-with-empty-name", func(t *testing.T) {
r1.UserId = userId
r1.EmojiName = ""
_, resp := Client.DeleteReaction(r1)
CheckNotFoundStatus(t, resp)
})
t.Run("delete-reaction-with-not-existing-name", func(t *testing.T) {
r1.EmojiName = strings.Repeat("a", 65)
_, resp := Client.DeleteReaction(r1)
CheckBadRequestStatus(t, resp)
})
t.Run("delete-reaction-as-anonymous-user", func(t *testing.T) {
Client.Logout()
r1.EmojiName = "smile"
_, resp := Client.DeleteReaction(r1)
CheckUnauthorizedStatus(t, resp)
})
t.Run("delete-reaction-as-system-admin", func(t *testing.T) {
_, resp := th.SystemAdminClient.DeleteReaction(r1)
CheckNoError(t, resp)
_, resp = th.SystemAdminClient.DeleteReaction(r4)
CheckNoError(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 0 {
t.Fatal("should have deleted both reactions")
}
})
t.Run("unable-to-delete-reaction-without-permissions", func(t *testing.T) {
th.LoginBasic()
th.RemovePermissionFromRole(model.PERMISSION_REMOVE_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
th.App.SaveReactionForPost(r1)
_, resp := Client.DeleteReaction(r1)
CheckForbiddenStatus(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
t.Fatal("should have not deleted a reactions")
}
th.AddPermissionToRole(model.PERMISSION_REMOVE_REACTION.Id, model.CHANNEL_USER_ROLE_ID)
})
t.Run("unable-to-delete-others-reactions-without-permissions", func(t *testing.T) {
th.RemovePermissionFromRole(model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id, model.SYSTEM_ADMIN_ROLE_ID)
th.App.SaveReactionForPost(r1)
_, resp := th.SystemAdminClient.DeleteReaction(r1)
CheckForbiddenStatus(t, resp)
if reactions, err := th.App.GetReactionsForPost(postId); err != nil || len(reactions) != 1 {
t.Fatal("should have not deleted a reactions")
}
th.AddPermissionToRole(model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id, model.SYSTEM_ADMIN_ROLE_ID)
})
}

133
api4/role.go Обычный файл
Просмотреть файл

@@ -0,0 +1,133 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api4
import (
"net/http"
"strings"
"github.com/mattermost/mattermost-server/model"
)
func (api *API) InitRole() {
api.BaseRoutes.Roles.Handle("/{role_id:[A-Za-z0-9]+}", api.ApiSessionRequiredTrustRequester(getRole)).Methods("GET")
api.BaseRoutes.Roles.Handle("/name/{role_name:[a-z0-9_]+}", api.ApiSessionRequiredTrustRequester(getRoleByName)).Methods("GET")
api.BaseRoutes.Roles.Handle("/names", api.ApiSessionRequiredTrustRequester(getRolesByNames)).Methods("POST")
api.BaseRoutes.Roles.Handle("/{role_id:[A-Za-z0-9]+}/patch", api.ApiSessionRequired(patchRole)).Methods("PUT")
}
func getRole(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireRoleId()
if c.Err != nil {
return
}
if role, err := c.App.GetRole(c.Params.RoleId); err != nil {
c.Err = err
return
} else {
w.Write([]byte(role.ToJson()))
}
}
func getRoleByName(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireRoleName()
if c.Err != nil {
return
}
if role, err := c.App.GetRoleByName(c.Params.RoleName); err != nil {
c.Err = err
return
} else {
w.Write([]byte(role.ToJson()))
}
}
func getRolesByNames(c *Context, w http.ResponseWriter, r *http.Request) {
rolenames := model.ArrayFromJson(r.Body)
if len(rolenames) == 0 {
c.SetInvalidParam("rolenames")
return
}
var cleanedRoleNames []string
for _, rolename := range rolenames {
if strings.TrimSpace(rolename) == "" {
continue
}
if !model.IsValidRoleName(rolename) {
c.SetInvalidParam("rolename")
return
}
cleanedRoleNames = append(cleanedRoleNames, rolename)
}
if roles, err := c.App.GetRolesByNames(cleanedRoleNames); err != nil {
c.Err = err
return
} else {
w.Write([]byte(model.RoleListToJson(roles)))
}
}
func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
c.RequireRoleId()
if c.Err != nil {
return
}
patch := model.RolePatchFromJson(r.Body)
if patch == nil {
c.SetInvalidParam("role")
return
}
oldRole, err := c.App.GetRole(c.Params.RoleId)
if err != nil {
c.Err = err
return
}
if c.App.License() == nil && patch.Permissions != nil {
allowedPermissions := []string{
model.PERMISSION_CREATE_TEAM.Id,
model.PERMISSION_MANAGE_WEBHOOKS.Id,
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_OAUTH.Id,
model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
}
changedPermissions := model.PermissionsChangedByPatch(oldRole, patch)
for _, permission := range changedPermissions {
allowed := false
for _, allowedPermission := range allowedPermissions {
if permission == allowedPermission {
allowed = true
}
}
if !allowed {
c.Err = model.NewAppError("Api4.PatchRoles", "api.roles.patch_roles.license.error", nil, "", http.StatusNotImplemented)
return
}
}
}
if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
return
}
if role, err := c.App.PatchRole(oldRole, patch); err != nil {
c.Err = err
return
} else {
c.LogAudit("")
w.Write([]byte(role.ToJson()))
}
}

214
api4/role_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,214 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api4
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-server/model"
)
func TestGetRole(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer th.TearDown()
role := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{"manage_system", "create_public_channel"},
SchemeManaged: true,
}
res1 := <-th.App.Srv.Store.Role().Save(role)
assert.Nil(t, res1.Err)
role = res1.Data.(*model.Role)
defer th.App.Srv.Store.Job().Delete(role.Id)
received, resp := th.Client.GetRole(role.Id)
CheckNoError(t, resp)
assert.Equal(t, received.Id, role.Id)
assert.Equal(t, received.Name, role.Name)
assert.Equal(t, received.DisplayName, role.DisplayName)
assert.Equal(t, received.Description, role.Description)
assert.EqualValues(t, received.Permissions, role.Permissions)
assert.Equal(t, received.SchemeManaged, role.SchemeManaged)
_, resp = th.SystemAdminClient.GetRole("1234")
CheckBadRequestStatus(t, resp)
_, resp = th.SystemAdminClient.GetRole(model.NewId())
CheckNotFoundStatus(t, resp)
}
func TestGetRoleByName(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer th.TearDown()
role := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{"manage_system", "create_public_channel"},
SchemeManaged: true,
}
res1 := <-th.App.Srv.Store.Role().Save(role)
assert.Nil(t, res1.Err)
role = res1.Data.(*model.Role)
defer th.App.Srv.Store.Job().Delete(role.Id)
received, resp := th.Client.GetRoleByName(role.Name)
CheckNoError(t, resp)
assert.Equal(t, received.Id, role.Id)
assert.Equal(t, received.Name, role.Name)
assert.Equal(t, received.DisplayName, role.DisplayName)
assert.Equal(t, received.Description, role.Description)
assert.EqualValues(t, received.Permissions, role.Permissions)
assert.Equal(t, received.SchemeManaged, role.SchemeManaged)
_, resp = th.SystemAdminClient.GetRoleByName(strings.Repeat("abcdefghij", 10))
CheckBadRequestStatus(t, resp)
_, resp = th.SystemAdminClient.GetRoleByName(model.NewId())
CheckNotFoundStatus(t, resp)
}
func TestGetRolesByNames(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer th.TearDown()
role1 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{"manage_system", "create_public_channel"},
SchemeManaged: true,
}
role2 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{"manage_system", "delete_private_channel"},
SchemeManaged: true,
}
role3 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{"manage_system", "manage_public_channel_properties"},
SchemeManaged: true,
}
res1 := <-th.App.Srv.Store.Role().Save(role1)
assert.Nil(t, res1.Err)
role1 = res1.Data.(*model.Role)
defer th.App.Srv.Store.Job().Delete(role1.Id)
res2 := <-th.App.Srv.Store.Role().Save(role2)
assert.Nil(t, res2.Err)
role2 = res2.Data.(*model.Role)
defer th.App.Srv.Store.Job().Delete(role2.Id)
res3 := <-th.App.Srv.Store.Role().Save(role3)
assert.Nil(t, res3.Err)
role3 = res3.Data.(*model.Role)
defer th.App.Srv.Store.Job().Delete(role3.Id)
// Check all three roles can be found.
received, resp := th.Client.GetRolesByNames([]string{role1.Name, role2.Name, role3.Name})
CheckNoError(t, resp)
assert.Contains(t, received, role1)
assert.Contains(t, received, role2)
assert.Contains(t, received, role3)
// Check a list of non-existant roles.
received, resp = th.Client.GetRolesByNames([]string{model.NewId(), model.NewId()})
CheckNoError(t, resp)
// Empty list should error.
_, resp = th.SystemAdminClient.GetRolesByNames([]string{})
CheckBadRequestStatus(t, resp)
// Invalid role name should error.
received, resp = th.Client.GetRolesByNames([]string{model.NewId(), model.NewId(), "!!!!!!"})
CheckBadRequestStatus(t, resp)
// Empty/whitespace rolenames should be ignored.
received, resp = th.Client.GetRolesByNames([]string{model.NewId(), model.NewId(), "", " "})
CheckNoError(t, resp)
}
func TestPatchRole(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
defer th.TearDown()
role := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{"manage_system", "create_public_channel", "manage_slash_commands"},
SchemeManaged: true,
}
res1 := <-th.App.Srv.Store.Role().Save(role)
assert.Nil(t, res1.Err)
role = res1.Data.(*model.Role)
defer th.App.Srv.Store.Job().Delete(role.Id)
patch := &model.RolePatch{
Permissions: &[]string{"manage_system", "create_public_channel", "manage_webhooks"},
}
received, resp := th.SystemAdminClient.PatchRole(role.Id, patch)
CheckNoError(t, resp)
assert.Equal(t, received.Id, role.Id)
assert.Equal(t, received.Name, role.Name)
assert.Equal(t, received.DisplayName, role.DisplayName)
assert.Equal(t, received.Description, role.Description)
assert.EqualValues(t, received.Permissions, []string{"manage_system", "create_public_channel", "manage_webhooks"})
assert.Equal(t, received.SchemeManaged, role.SchemeManaged)
// Check a no-op patch succeeds.
received, resp = th.SystemAdminClient.PatchRole(role.Id, patch)
CheckNoError(t, resp)
received, resp = th.SystemAdminClient.PatchRole("junk", patch)
CheckBadRequestStatus(t, resp)
received, resp = th.Client.PatchRole(model.NewId(), patch)
CheckNotFoundStatus(t, resp)
received, resp = th.Client.PatchRole(role.Id, patch)
CheckForbiddenStatus(t, resp)
// Check a change that the license would not allow.
patch = &model.RolePatch{
Permissions: &[]string{"manage_system", "manage_webhooks"},
}
received, resp = th.SystemAdminClient.PatchRole(role.Id, patch)
CheckNotImplementedStatus(t, resp)
// Add a license.
th.App.SetLicense(model.NewTestLicense())
// Try again, should succeed
received, resp = th.SystemAdminClient.PatchRole(role.Id, patch)
CheckNoError(t, resp)
assert.Equal(t, received.Id, role.Id)
assert.Equal(t, received.Name, role.Name)
assert.Equal(t, received.DisplayName, role.DisplayName)
assert.Equal(t, received.Description, role.Description)
assert.EqualValues(t, received.Permissions, []string{"manage_system", "manage_webhooks"})
assert.Equal(t, received.SchemeManaged, role.SchemeManaged)
}

Просмотреть файл

@@ -69,8 +69,14 @@ func TestCreateTeam(t *testing.T) {
_, resp = Client.CreateTeam(rteam)
CheckUnauthorizedStatus(t, resp)
// Update permission
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableTeamCreation = false })
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.RemovePermissionFromRole(model.PERMISSION_CREATE_TEAM.Id, model.SYSTEM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_CREATE_TEAM.Id, model.SYSTEM_ADMIN_ROLE_ID)
th.LoginBasic()
_, resp = Client.CreateTeam(team)
@@ -1314,16 +1320,18 @@ func TestAddTeamMember(t *testing.T) {
Client.Logout()
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Set the config so that only team admins can add a user to a team.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.LoginBasic()
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
// Test without the EE license to see that the permission restriction is ignored.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Add an EE license.
th.App.SetLicense(model.NewTestLicense())
th.LoginBasic()
// Check that a regular user can't add someone to the team.
@@ -1333,38 +1341,26 @@ func TestAddTeamMember(t *testing.T) {
// Update user to team admin
th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetLicense(model.NewTestLicense())
th.LoginBasic()
// Should work as a team admin.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Change permission level to System Admin
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
// Change permission level to team user
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
// Should not work as team admin.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckForbiddenStatus(t, resp)
// Should work as system admin.
_, resp = th.SystemAdminClient.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
// Change permission level to All
th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
th.LoginBasic()
// Should work as a regular user.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp)
th.LoginBasic()
// by hash and data
Client.Login(otherUser.Email, otherUser.Password)
@@ -1502,16 +1498,18 @@ func TestAddTeamMembers(t *testing.T) {
Client.Logout()
// Check the appropriate permissions are enforced.
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
// Set the config so that only team admins can add a user to a team.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.LoginBasic()
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
// Test without the EE license to see that the permission restriction is ignored.
_, resp = Client.AddTeamMembers(team.Id, userList)
CheckNoError(t, resp)
// Add an EE license.
th.App.SetLicense(model.NewTestLicense())
th.LoginBasic()
// Check that a regular user can't add someone to the team.
@@ -1521,30 +1519,20 @@ func TestAddTeamMembers(t *testing.T) {
// Update user to team admin
th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetLicense(model.NewTestLicense())
th.LoginBasic()
// Should work as a team admin.
_, resp = Client.AddTeamMembers(team.Id, userList)
CheckNoError(t, resp)
// Change permission level to System Admin
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
// Change permission level to team user
th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
// Should not work as team admin.
_, resp = Client.AddTeamMembers(team.Id, userList)
CheckForbiddenStatus(t, resp)
// Should work as system admin.
_, resp = th.SystemAdminClient.AddTeamMembers(team.Id, userList)
CheckNoError(t, resp)
// Change permission level to All
th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense())
th.LoginBasic()
// Should work as a regular user.

Просмотреть файл

@@ -194,10 +194,16 @@ func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("fail - bad permissions")
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
} else {
w.Write([]byte(hook.ToJson()))
}
if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
c.LogAudit("fail - inappropriate permissions")
c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
return
}
w.Write([]byte(hook.ToJson()))
return
}
}
@@ -228,14 +234,20 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("fail - bad permissions")
c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
return
} else {
if err = c.App.DeleteIncomingWebhook(hookId); err != nil {
c.Err = err
return
}
ReturnStatusOK(w)
}
if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
c.LogAudit("fail - inappropriate permissions")
c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
return
}
if err = c.App.DeleteIncomingWebhook(hookId); err != nil {
c.Err = err
return
}
ReturnStatusOK(w)
}
}

Просмотреть файл

@@ -19,10 +19,16 @@ func TestCreateIncomingWebhook(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = true })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
@@ -53,7 +59,7 @@ func TestCreateIncomingWebhook(t *testing.T) {
_, resp = Client.CreateIncomingWebhook(hook)
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
_, resp = Client.CreateIncomingWebhook(hook)
CheckNoError(t, resp)
@@ -75,7 +81,13 @@ func TestGetIncomingWebhooks(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
@@ -126,7 +138,7 @@ func TestGetIncomingWebhooks(t *testing.T) {
_, resp = Client.GetIncomingWebhooks(0, 1000, "")
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
_, resp = Client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
CheckNoError(t, resp)
@@ -148,7 +160,6 @@ func TestGetIncomingWebhook(t *testing.T) {
Client := th.SystemAdminClient
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
var resp *model.Response
var rhook *model.IncomingWebhook
@@ -188,7 +199,6 @@ func TestDeleteIncomingWebhook(t *testing.T) {
Client := th.SystemAdminClient
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
var resp *model.Response
var rhook *model.IncomingWebhook
@@ -240,7 +250,13 @@ func TestCreateOutgoingWebhook(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
@@ -268,7 +284,7 @@ func TestCreateOutgoingWebhook(t *testing.T) {
_, resp = Client.CreateOutgoingWebhook(hook)
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
_, resp = Client.CreateOutgoingWebhook(hook)
CheckNoError(t, resp)
@@ -284,7 +300,12 @@ func TestGetOutgoingWebhooks(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
@@ -352,7 +373,7 @@ func TestGetOutgoingWebhooks(t *testing.T) {
_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
_, resp = Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
CheckNoError(t, resp)
@@ -380,7 +401,6 @@ func TestGetOutgoingWebhook(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
@@ -411,7 +431,13 @@ func TestUpdateIncomingHook(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook1 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
@@ -547,10 +573,11 @@ func TestUpdateIncomingHook(t *testing.T) {
CheckForbiddenStatus(t, resp)
})
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
t.Run("UpdateHookOfSameUser", func(t *testing.T) {
sameUserHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, UserId: th.BasicUser2.Id}
@@ -568,7 +595,8 @@ func TestUpdateIncomingHook(t *testing.T) {
})
})
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
Client.Logout()
th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
@@ -623,7 +651,6 @@ func TestRegenOutgoingHookToken(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
@@ -656,7 +683,12 @@ func TestUpdateOutgoingHook(t *testing.T) {
Client := th.Client
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
defaultRolePermissions := th.SaveDefaultRolePermissions()
defer func() {
th.RestoreDefaultRolePermissions(defaultRolePermissions)
}()
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
createdHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
@@ -729,7 +761,7 @@ func TestUpdateOutgoingHook(t *testing.T) {
CheckForbiddenStatus(t, resp)
})
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats2"}}
@@ -739,7 +771,8 @@ func TestUpdateOutgoingHook(t *testing.T) {
_, resp = Client.UpdateOutgoingWebhook(createdHook2)
CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
Client.Logout()
th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
@@ -813,7 +846,6 @@ func TestDeleteOutgoingHook(t *testing.T) {
Client := th.SystemAdminClient
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
var resp *model.Response
var rhook *model.OutgoingWebhook

Просмотреть файл

@@ -8,6 +8,7 @@ import (
"html/template"
"net"
"net/http"
"reflect"
"strings"
"sync"
"sync/atomic"
@@ -26,6 +27,8 @@ import (
"github.com/mattermost/mattermost-server/utils"
)
const ADVANCED_PERMISSIONS_MIGRATION_KEY = "AdvancedPermissionsMigrationComplete"
type App struct {
goroutineCount int32
goroutineExitSignal chan struct{}
@@ -71,7 +74,6 @@ type App struct {
htmlTemplateWatcher *utils.HTMLTemplateWatcher
sessionCache *utils.Cache
roles map[string]*model.Role
configListenerId string
licenseListenerId string
disableConfigWatch bool
@@ -155,7 +157,6 @@ func New(options ...Option) (outApp *App, outErr error) {
})
app.regenerateClientConfig()
app.setDefaultRolesBasedOnConfig()
l4g.Info(utils.T("api.server.new_server.init.info"))
@@ -196,7 +197,6 @@ func New(options ...Option) (outApp *App, outErr error) {
func (a *App) configOrLicenseListener() {
a.regenerateClientConfig()
a.setDefaultRolesBasedOnConfig()
}
func (a *App) Shutdown() {
@@ -495,3 +495,57 @@ func (a *App) Handle404(w http.ResponseWriter, r *http.Request) {
utils.RenderWebAppError(w, r, err, a.AsymmetricSigningKey())
}
// This function migrates the default built in roles from code/config to the database.
func (a *App) DoAdvancedPermissionsMigration() {
// If the migration is already marked as completed, don't do it again.
if result := <-a.Srv.Store.System().GetByName(ADVANCED_PERMISSIONS_MIGRATION_KEY); result.Err == nil {
return
}
l4g.Info("Migrating roles to database.")
roles := model.MakeDefaultRoles()
roles = utils.SetRolePermissionsFromConfig(roles, a.Config(), a.License() != nil)
allSucceeded := true
for _, role := range roles {
if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
// If this failed for reasons other than the role already existing, don't mark the migration as done.
if result2 := <-a.Srv.Store.Role().GetByName(role.Name); result2.Err != nil {
l4g.Critical("Failed to migrate role to database.")
l4g.Critical(result.Err)
allSucceeded = false
} else {
// If the role already existed, check it is the same and update if not.
fetchedRole := result.Data.(*model.Role)
if !reflect.DeepEqual(fetchedRole.Permissions, role.Permissions) ||
fetchedRole.DisplayName != role.DisplayName ||
fetchedRole.Description != role.Description ||
fetchedRole.SchemeManaged != role.SchemeManaged {
role.Id = fetchedRole.Id
if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
// Role is not the same, but failed to update.
l4g.Critical("Failed to migrate role to database.")
l4g.Critical(result.Err)
allSucceeded = false
}
}
}
}
}
if !allSucceeded {
return
}
system := model.System{
Name: ADVANCED_PERMISSIONS_MIGRATION_KEY,
Value: "true",
}
if result := <-a.Srv.Store.System().Save(&system); result.Err != nil {
l4g.Critical("Failed to mark advanced permissions migration as completed.")
l4g.Critical(result.Err)
}
}

Просмотреть файл

@@ -5,11 +5,11 @@ package app
import (
"flag"
"fmt"
"os"
"testing"
l4g "github.com/alecthomas/log4go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -72,3 +72,346 @@ func TestUpdateConfig(t *testing.T) {
*cfg.ServiceSettings.SiteURL = "foo"
})
}
func TestDoAdvancedPermissionsMigration(t *testing.T) {
th := Setup()
defer th.TearDown()
if testStoreSqlSupplier == nil {
t.Skip("This test requires a TestStore to be run.")
}
th.ResetRoleMigration()
th.App.DoAdvancedPermissionsMigration()
roleNames := []string{
"system_user",
"system_admin",
"team_user",
"team_admin",
"channel_user",
"channel_admin",
"system_post_all",
"system_post_all_public",
"system_user_access_token",
"team_post_all",
"team_post_all_public",
}
roles1, err1 := th.App.GetRolesByNames(roleNames)
assert.Nil(t, err1)
assert.Equal(t, len(roles1), len(roleNames))
expected1 := map[string][]string{
"channel_user": []string{
model.PERMISSION_READ_CHANNEL.Id,
model.PERMISSION_ADD_REACTION.Id,
model.PERMISSION_REMOVE_REACTION.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_EDIT_POST.Id,
},
"channel_admin": []string{
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
},
"team_user": []string{
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
model.PERMISSION_VIEW_TEAM.Id,
model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
model.PERMISSION_INVITE_USER.Id,
model.PERMISSION_ADD_USER_TO_TEAM.Id,
},
"team_post_all": []string{
model.PERMISSION_CREATE_POST.Id,
},
"team_post_all_public": []string{
model.PERMISSION_CREATE_POST_PUBLIC.Id,
},
"team_admin": []string{
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
model.PERMISSION_MANAGE_TEAM.Id,
model.PERMISSION_IMPORT_TEAM.Id,
model.PERMISSION_MANAGE_TEAM_ROLES.Id,
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
model.PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_WEBHOOKS.Id,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
},
"system_user": []string{
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
model.PERMISSION_PERMANENT_DELETE_USER.Id,
model.PERMISSION_CREATE_TEAM.Id,
},
"system_post_all": []string{
model.PERMISSION_CREATE_POST.Id,
},
"system_post_all_public": []string{
model.PERMISSION_CREATE_POST_PUBLIC.Id,
},
"system_user_access_token": []string{
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
},
"system_admin": []string{
model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
model.PERMISSION_MANAGE_SYSTEM.Id,
model.PERMISSION_MANAGE_ROLES.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
model.PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
model.PERMISSION_EDIT_OTHER_USERS.Id,
model.PERMISSION_MANAGE_OAUTH.Id,
model.PERMISSION_INVITE_USER.Id,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
model.PERMISSION_CREATE_TEAM.Id,
model.PERMISSION_ADD_USER_TO_TEAM.Id,
model.PERMISSION_LIST_USERS_WITHOUT_TEAM.Id,
model.PERMISSION_MANAGE_JOBS.Id,
model.PERMISSION_CREATE_POST_PUBLIC.Id,
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
model.PERMISSION_VIEW_TEAM.Id,
model.PERMISSION_READ_CHANNEL.Id,
model.PERMISSION_ADD_REACTION.Id,
model.PERMISSION_REMOVE_REACTION.Id,
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
model.PERMISSION_MANAGE_TEAM.Id,
model.PERMISSION_IMPORT_TEAM.Id,
model.PERMISSION_MANAGE_TEAM_ROLES.Id,
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_WEBHOOKS.Id,
model.PERMISSION_EDIT_POST.Id,
},
}
// Check the migration matches what's expected.
for name, permissions := range expected1 {
role, err := th.App.GetRoleByName(name)
assert.Nil(t, err)
assert.Equal(t, role.Permissions, permissions)
}
// Add a license and change the policy config.
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
}()
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
th.App.SetLicense(model.NewTestLicense())
// Check the migration doesn't change anything if run again.
th.App.DoAdvancedPermissionsMigration()
roles2, err2 := th.App.GetRolesByNames(roleNames)
assert.Nil(t, err2)
assert.Equal(t, len(roles2), len(roleNames))
for name, permissions := range expected1 {
role, err := th.App.GetRoleByName(name)
assert.Nil(t, err)
assert.Equal(t, permissions, role.Permissions)
}
// Reset the database
th.ResetRoleMigration()
// Do the migration again with different policy config settings and a license.
th.App.DoAdvancedPermissionsMigration()
// Check the role permissions.
expected2 := map[string][]string{
"channel_user": []string{
model.PERMISSION_READ_CHANNEL.Id,
model.PERMISSION_ADD_REACTION.Id,
model.PERMISSION_REMOVE_REACTION.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_EDIT_POST.Id,
},
"channel_admin": []string{
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
},
"team_user": []string{
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
model.PERMISSION_VIEW_TEAM.Id,
model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
model.PERMISSION_INVITE_USER.Id,
model.PERMISSION_ADD_USER_TO_TEAM.Id,
},
"team_post_all": []string{
model.PERMISSION_CREATE_POST.Id,
},
"team_post_all_public": []string{
model.PERMISSION_CREATE_POST_PUBLIC.Id,
},
"team_admin": []string{
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
model.PERMISSION_MANAGE_TEAM.Id,
model.PERMISSION_IMPORT_TEAM.Id,
model.PERMISSION_MANAGE_TEAM_ROLES.Id,
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
model.PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_WEBHOOKS.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
},
"system_user": []string{
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
model.PERMISSION_CREATE_GROUP_CHANNEL.Id,
model.PERMISSION_PERMANENT_DELETE_USER.Id,
model.PERMISSION_CREATE_TEAM.Id,
},
"system_post_all": []string{
model.PERMISSION_CREATE_POST.Id,
},
"system_post_all_public": []string{
model.PERMISSION_CREATE_POST_PUBLIC.Id,
},
"system_user_access_token": []string{
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
},
"system_admin": []string{
model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
model.PERMISSION_MANAGE_SYSTEM.Id,
model.PERMISSION_MANAGE_ROLES.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
model.PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
model.PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
model.PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
model.PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
model.PERMISSION_EDIT_OTHER_USERS.Id,
model.PERMISSION_MANAGE_OAUTH.Id,
model.PERMISSION_INVITE_USER.Id,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
model.PERMISSION_CREATE_TEAM.Id,
model.PERMISSION_ADD_USER_TO_TEAM.Id,
model.PERMISSION_LIST_USERS_WITHOUT_TEAM.Id,
model.PERMISSION_MANAGE_JOBS.Id,
model.PERMISSION_CREATE_POST_PUBLIC.Id,
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
model.PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
model.PERMISSION_VIEW_TEAM.Id,
model.PERMISSION_READ_CHANNEL.Id,
model.PERMISSION_ADD_REACTION.Id,
model.PERMISSION_REMOVE_REACTION.Id,
model.PERMISSION_UPLOAD_FILE.Id,
model.PERMISSION_GET_PUBLIC_LINK.Id,
model.PERMISSION_CREATE_POST.Id,
model.PERMISSION_USE_SLASH_COMMANDS.Id,
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
model.PERMISSION_MANAGE_TEAM.Id,
model.PERMISSION_IMPORT_TEAM.Id,
model.PERMISSION_MANAGE_TEAM_ROLES.Id,
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_WEBHOOKS.Id,
model.PERMISSION_EDIT_POST.Id,
},
}
roles3, err3 := th.App.GetRolesByNames(roleNames)
assert.Nil(t, err3)
assert.Equal(t, len(roles3), len(roleNames))
for name, permissions := range expected2 {
role, err := th.App.GetRoleByName(name)
assert.Nil(t, err)
assert.Equal(t, permissions, role.Permissions, fmt.Sprintf("'%v' did not have expected permissions", name))
}
// Remove the license.
th.App.SetLicense(nil)
// Do the migration again.
th.ResetRoleMigration()
th.App.DoAdvancedPermissionsMigration()
// Check the role permissions.
roles4, err4 := th.App.GetRolesByNames(roleNames)
assert.Nil(t, err4)
assert.Equal(t, len(roles4), len(roleNames))
for name, permissions := range expected1 {
role, err := th.App.GetRoleByName(name)
assert.Nil(t, err)
assert.Equal(t, permissions, role.Permissions)
}
}

Просмотреть файл

@@ -13,6 +13,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/einterfaces"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
"github.com/mattermost/mattermost-server/plugin/pluginenv"
@@ -43,12 +44,16 @@ func (*persistentTestStore) Close() {}
var testStoreContainer *storetest.RunningContainer
var testStore *persistentTestStore
var testStoreSqlSupplier *sqlstore.SqlSupplier
var testClusterInterface *FakeClusterInterface
// UseTestStore sets the container and corresponding settings to use for tests. Once the tests are
// complete (e.g. at the end of your TestMain implementation), you should call StopTestStore.
func UseTestStore(container *storetest.RunningContainer, settings *model.SqlSettings) {
testClusterInterface = &FakeClusterInterface{}
testStoreContainer = container
testStore = &persistentTestStore{store.NewLayeredStore(sqlstore.NewSqlSupplier(*settings, nil), nil, nil)}
testStoreSqlSupplier = sqlstore.NewSqlSupplier(*settings, nil)
testStore = &persistentTestStore{store.NewLayeredStore(testStoreSqlSupplier, nil, testClusterInterface)}
}
func StopTestStore() {
@@ -102,6 +107,9 @@ func setupTestHelper(enterprise bool) *TestHelper {
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
th.App.DoAdvancedPermissionsMigration()
th.App.Srv.Store.MarkSystemRanUnitTests()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
@@ -217,6 +225,7 @@ func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post {
UserId: me.BasicUser.Id,
ChannelId: channel.Id,
Message: "message_" + id,
CreateAt: model.GetMillis() - 10000,
}
utils.DisableDebugLogForTest()
@@ -326,3 +335,45 @@ func (me *TestHelper) InstallPlugin(manifest *model.Manifest, hooks plugin.Hooks
panic(err)
}
}
func (me *TestHelper) ResetRoleMigration() {
if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Roles"); err != nil {
panic(err)
}
testClusterInterface.sendClearRoleCacheMessage()
if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Systems where Name = :Name", map[string]interface{}{"Name": ADVANCED_PERMISSIONS_MIGRATION_KEY}); err != nil {
panic(err)
}
}
type FakeClusterInterface struct {
clusterMessageHandler einterfaces.ClusterMessageHandler
}
func (me *FakeClusterInterface) StartInterNodeCommunication() {}
func (me *FakeClusterInterface) StopInterNodeCommunication() {}
func (me *FakeClusterInterface) RegisterClusterMessageHandler(event string, crm einterfaces.ClusterMessageHandler) {
me.clusterMessageHandler = crm
}
func (me *FakeClusterInterface) GetClusterId() string { return "" }
func (me *FakeClusterInterface) IsLeader() bool { return false }
func (me *FakeClusterInterface) GetMyClusterInfo() *model.ClusterInfo { return nil }
func (me *FakeClusterInterface) GetClusterInfos() []*model.ClusterInfo { return nil }
func (me *FakeClusterInterface) SendClusterMessage(cluster *model.ClusterMessage) {}
func (me *FakeClusterInterface) NotifyMsg(buf []byte) {}
func (me *FakeClusterInterface) GetClusterStats() ([]*model.ClusterStats, *model.AppError) {
return nil, nil
}
func (me *FakeClusterInterface) GetLogs(page, perPage int) ([]string, *model.AppError) {
return []string{}, nil
}
func (me *FakeClusterInterface) ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError {
return nil
}
func (me *FakeClusterInterface) sendClearRoleCacheMessage() {
me.clusterMessageHandler(&model.ClusterMessage{
Event: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES,
})
}

Просмотреть файл

@@ -12,7 +12,7 @@ import (
)
func (a *App) SessionHasPermissionTo(session model.Session, permission *model.Permission) bool {
if !a.CheckIfRolesGrantPermission(session.GetUserRoles(), permission.Id) {
if !a.RolesGrantPermission(session.GetUserRoles(), permission.Id) {
a.ClearSessionCacheForUser(session.UserId)
return false
}
@@ -28,12 +28,12 @@ func (a *App) SessionHasPermissionToTeam(session model.Session, teamId string, p
teamMember := session.GetTeamByTeamId(teamId)
if teamMember != nil {
if a.CheckIfRolesGrantPermission(teamMember.GetRoles(), permission.Id) {
if a.RolesGrantPermission(teamMember.GetRoles(), permission.Id) {
return true
}
}
return a.CheckIfRolesGrantPermission(session.GetUserRoles(), permission.Id)
return a.RolesGrantPermission(session.GetUserRoles(), permission.Id)
}
func (a *App) SessionHasPermissionToChannel(session model.Session, channelId string, permission *model.Permission) bool {
@@ -48,7 +48,7 @@ func (a *App) SessionHasPermissionToChannel(session model.Session, channelId str
ids := cmcresult.Data.(map[string]string)
if roles, ok := ids[channelId]; ok {
channelRoles = strings.Fields(roles)
if a.CheckIfRolesGrantPermission(channelRoles, permission.Id) {
if a.RolesGrantPermission(channelRoles, permission.Id) {
return true
}
}
@@ -69,7 +69,7 @@ func (a *App) SessionHasPermissionToChannelByPost(session model.Session, postId
if result := <-a.Srv.Store.Channel().GetMemberForPost(postId, session.UserId); result.Err == nil {
channelMember = result.Data.(*model.ChannelMember)
if a.CheckIfRolesGrantPermission(channelMember.GetRoles(), permission.Id) {
if a.RolesGrantPermission(channelMember.GetRoles(), permission.Id) {
return true
}
}
@@ -119,7 +119,7 @@ func (a *App) HasPermissionTo(askingUserId string, permission *model.Permission)
roles := user.GetRoles()
return a.CheckIfRolesGrantPermission(roles, permission.Id)
return a.RolesGrantPermission(roles, permission.Id)
}
func (a *App) HasPermissionToTeam(askingUserId string, teamId string, permission *model.Permission) bool {
@@ -134,7 +134,7 @@ func (a *App) HasPermissionToTeam(askingUserId string, teamId string, permission
roles := teamMember.GetRoles()
if a.CheckIfRolesGrantPermission(roles, permission.Id) {
if a.RolesGrantPermission(roles, permission.Id) {
return true
}
@@ -149,7 +149,7 @@ func (a *App) HasPermissionToChannel(askingUserId string, channelId string, perm
channelMember, err := a.GetChannelMember(channelId, askingUserId)
if err == nil {
roles := channelMember.GetRoles()
if a.CheckIfRolesGrantPermission(roles, permission.Id) {
if a.RolesGrantPermission(roles, permission.Id) {
return true
}
}
@@ -168,7 +168,7 @@ func (a *App) HasPermissionToChannelByPost(askingUserId string, postId string, p
if result := <-a.Srv.Store.Channel().GetMemberForPost(postId, askingUserId); result.Err == nil {
channelMember = result.Data.(*model.ChannelMember)
if a.CheckIfRolesGrantPermission(channelMember.GetRoles(), permission.Id) {
if a.RolesGrantPermission(channelMember.GetRoles(), permission.Id) {
return true
}
}
@@ -181,17 +181,33 @@ func (a *App) HasPermissionToChannelByPost(askingUserId string, postId string, p
return a.HasPermissionTo(askingUserId, permission)
}
func (a *App) CheckIfRolesGrantPermission(roles []string, permissionId string) bool {
for _, roleId := range roles {
if role := a.Role(roleId); role == nil {
l4g.Debug("Bad role in system " + roleId)
return false
} else {
permissions := role.Permissions
for _, permission := range permissions {
if permission == permissionId {
return true
}
func (a *App) HasPermissionToUser(askingUserId string, userId string) bool {
if askingUserId == userId {
return true
}
if a.HasPermissionTo(askingUserId, model.PERMISSION_EDIT_OTHER_USERS) {
return true
}
return false
}
func (a *App) RolesGrantPermission(roleNames []string, permissionId string) bool {
roles, err := a.GetRolesByNames(roleNames)
if err != nil {
// This should only happen if something is very broken. We can't realistically
// recover the situation, so deny permission and log an error.
l4g.Error("Failed to get roles from database with role names: " + strings.Join(roleNames, ","))
l4g.Error(err)
return false
}
for _, role := range roles {
permissions := role.Permissions
for _, permission := range permissions {
if permission == permissionId {
return true
}
}
}

Просмотреть файл

@@ -18,9 +18,9 @@ func TestCheckIfRolesGrantPermission(t *testing.T) {
permissionId string
shouldGrant bool
}{
{[]string{model.SYSTEM_ADMIN_ROLE_ID}, th.App.Role(model.SYSTEM_ADMIN_ROLE_ID).Permissions[0], true},
{[]string{model.SYSTEM_ADMIN_ROLE_ID}, model.PERMISSION_MANAGE_SYSTEM.Id, true},
{[]string{model.SYSTEM_ADMIN_ROLE_ID}, "non-existant-permission", false},
{[]string{model.CHANNEL_USER_ROLE_ID}, th.App.Role(model.CHANNEL_USER_ROLE_ID).Permissions[0], true},
{[]string{model.CHANNEL_USER_ROLE_ID}, model.PERMISSION_READ_CHANNEL.Id, true},
{[]string{model.CHANNEL_USER_ROLE_ID}, model.PERMISSION_MANAGE_SYSTEM.Id, false},
{[]string{model.SYSTEM_ADMIN_ROLE_ID, model.CHANNEL_USER_ROLE_ID}, model.PERMISSION_MANAGE_SYSTEM.Id, true},
{[]string{model.CHANNEL_USER_ROLE_ID, model.SYSTEM_ADMIN_ROLE_ID}, model.PERMISSION_MANAGE_SYSTEM.Id, true},
@@ -29,7 +29,7 @@ func TestCheckIfRolesGrantPermission(t *testing.T) {
}
for testnum, testcase := range cases {
if th.App.CheckIfRolesGrantPermission(testcase.roles, testcase.permissionId) != testcase.shouldGrant {
if th.App.RolesGrantPermission(testcase.roles, testcase.permissionId) != testcase.shouldGrant {
t.Fatal("Failed test case ", testnum)
}
}

Просмотреть файл

@@ -439,6 +439,10 @@ func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles
return nil, err
}
if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
return nil, err
}
member.Roles = newRoles
if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil {

Просмотреть файл

@@ -249,7 +249,7 @@ func (a *App) trackConfig() {
a.SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{
"enable_user_creation": cfg.TeamSettings.EnableUserCreation,
"enable_team_creation": cfg.TeamSettings.EnableTeamCreation,
"enable_team_creation": *cfg.TeamSettings.EnableTeamCreation,
"restrict_team_invite": *cfg.TeamSettings.RestrictTeamInvite,
"restrict_public_channel_creation": *cfg.TeamSettings.RestrictPublicChannelCreation,
"restrict_private_channel_creation": *cfg.TeamSettings.RestrictPrivateChannelCreation,

Просмотреть файл

@@ -412,10 +412,6 @@ func TestImportValidateUserImportData(t *testing.T) {
}
data.Position = ptrStr("The Boss")
data.Roles = ptrStr("system_user wat")
if err := validateUserImportData(&data); err == nil {
t.Fatal("Validation should have failed due to too unrecognised role.")
}
data.Roles = nil
if err := validateUserImportData(&data); err != nil {
t.Fatal("Validation failed but should have been valid.")
@@ -479,12 +475,6 @@ func TestImportValidateUserTeamsImportData(t *testing.T) {
}
data[0].Name = ptrStr("teamname")
// Invalid Roles
data[0].Roles = ptrStr("wtf")
if err := validateUserTeamsImportData(&data); err == nil {
t.Fatal("Should have failed due to invalid roles.")
}
// Valid (nil roles)
data[0].Roles = nil
if err := validateUserTeamsImportData(&data); err != nil {
@@ -517,12 +507,6 @@ func TestImportValidateUserChannelsImportData(t *testing.T) {
}
data[0].Name = ptrStr("channelname")
// Invalid Roles
data[0].Roles = ptrStr("wtf")
if err := validateUserChannelsImportData(&data); err == nil {
t.Fatal("Should have failed due to invalid roles.")
}
// Valid (nil roles)
data[0].Roles = nil
if err := validateUserChannelsImportData(&data); err != nil {

Просмотреть файл

@@ -113,7 +113,6 @@ func (a *App) License() *model.License {
func (a *App) SetLicense(license *model.License) bool {
defer func() {
a.setDefaultRolesBasedOnConfig()
for _, listener := range a.licenseListeners {
listener()
}

Просмотреть файл

@@ -124,7 +124,7 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo
if a.License() != nil && *a.Config().TeamSettings.ExperimentalTownSquareIsReadOnly &&
!post.IsSystemMessage() &&
channel.Name == model.DEFAULT_CHANNEL &&
!a.CheckIfRolesGrantPermission(user.GetRoles(), model.PERMISSION_MANAGE_SYSTEM.Id) {
!a.RolesGrantPermission(user.GetRoles(), model.PERMISSION_MANAGE_SYSTEM.Id) {
return nil, model.NewAppError("createPost", "api.post.create_post.town_square_read_only", nil, "", http.StatusForbidden)
}
@@ -326,13 +326,6 @@ func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model
} else {
oldPost = result.Data.(*model.PostList).Posts[post.Id]
if a.License() != nil {
if *a.Config().ServiceSettings.AllowEditPost == model.ALLOW_EDIT_POST_NEVER && post.Message != oldPost.Message {
err := model.NewAppError("UpdatePost", "api.post.update_post.permissions_denied.app_error", nil, "", http.StatusForbidden)
return nil, err
}
}
if oldPost == nil {
err := model.NewAppError("UpdatePost", "api.post.update_post.find.app_error", nil, "id="+post.Id, http.StatusBadRequest)
return nil, err
@@ -349,7 +342,7 @@ func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model
}
if a.License() != nil {
if *a.Config().ServiceSettings.AllowEditPost == model.ALLOW_EDIT_POST_TIME_LIMIT && model.GetMillis() > oldPost.CreateAt+int64(*a.Config().ServiceSettings.PostEditTimeLimit*1000) && post.Message != oldPost.Message {
if *a.Config().ServiceSettings.PostEditTimeLimit != -1 && model.GetMillis() > oldPost.CreateAt+int64(*a.Config().ServiceSettings.PostEditTimeLimit*1000) && post.Message != oldPost.Message {
err := model.NewAppError("UpdatePost", "api.post.update_post.permissions_time_limit.app_error", map[string]interface{}{"timeLimit": *a.Config().ServiceSettings.PostEditTimeLimit}, "", http.StatusBadRequest)
return nil, err
}

Просмотреть файл

@@ -48,6 +48,43 @@ func TestUpdatePostEditAt(t *testing.T) {
}
}
func TestUpdatePostTimeLimit(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
post := &model.Post{}
*post = *th.BasicPost
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.PostEditTimeLimit = -1
})
if _, err := th.App.UpdatePost(post, true); err != nil {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.PostEditTimeLimit = 1000000000
})
post.Message = model.NewId()
if _, err := th.App.UpdatePost(post, true); err != nil {
t.Fatal("should allow you to edit the post")
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.PostEditTimeLimit = 1
})
post.Message = model.NewId()
if _, err := th.App.UpdatePost(post, true); err == nil {
t.Fatal("should fail on update old post")
}
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.PostEditTimeLimit = -1
})
}
func TestPostReplyToPostWhereRootPosterLeftChannel(t *testing.T) {
// This test ensures that when replying to a root post made by a user who has since left the channel, the reply
// post completes successfully. This is a regression test for PLT-6523.

Просмотреть файл

@@ -1,17 +1,91 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"reflect"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"net/http"
)
func (a *App) Role(id string) *model.Role {
return a.roles[id]
func (a *App) GetRole(id string) (*model.Role, *model.AppError) {
if result := <-a.Srv.Store.Role().Get(id); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.Role), nil
}
}
func (a *App) setDefaultRolesBasedOnConfig() {
a.roles = utils.DefaultRolesBasedOnConfig(a.Config(), a.License() != nil)
func (a *App) GetRoleByName(name string) (*model.Role, *model.AppError) {
if result := <-a.Srv.Store.Role().GetByName(name); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.Role), nil
}
}
func (a *App) GetRolesByNames(names []string) ([]*model.Role, *model.AppError) {
if result := <-a.Srv.Store.Role().GetByNames(names); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.Role), nil
}
}
func (a *App) PatchRole(role *model.Role, patch *model.RolePatch) (*model.Role, *model.AppError) {
// If patch is a no-op then short-circuit the store.
if patch.Permissions != nil && reflect.DeepEqual(*patch.Permissions, role.Permissions) {
return role, nil
}
role.Patch(patch)
role, err := a.UpdateRole(role)
if err != nil {
return nil, err
}
return role, err
}
func (a *App) UpdateRole(role *model.Role) (*model.Role, *model.AppError) {
if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
return nil, result.Err
} else {
a.sendUpdatedRoleEvent(role)
return role, nil
}
}
func (a *App) CheckRolesExist(roleNames []string) *model.AppError {
roles, err := a.GetRolesByNames(roleNames)
if err != nil {
return err
}
for _, name := range roleNames {
nameFound := false
for _, role := range roles {
if name == role.Name {
nameFound = true
break
}
}
if !nameFound {
return model.NewAppError("CheckRolesExist", "app.role.check_roles_exist.role_not_found", nil, "role="+name, http.StatusBadRequest)
}
}
return nil
}
func (a *App) sendUpdatedRoleEvent(role *model.Role) {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ROLE_UPDATED, "", "", "", nil)
message.Add("role", role.ToJson())
a.Go(func() {
a.Publish(message)
})
}

Просмотреть файл

@@ -160,6 +160,10 @@ func (a *App) UpdateTeamMemberRoles(teamId string, userId string, newRoles strin
return nil, err
}
if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
return nil, err
}
member.Roles = newRoles
if result := <-a.Srv.Store.Team().UpdateMember(member); result.Err != nil {

Просмотреть файл

@@ -1241,6 +1241,10 @@ func (a *App) UpdateUserRoles(userId string, newRoles string, sendWebSocketEvent
return nil, err
}
if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
return nil, err
}
user.Roles = newRoles
uchan := a.Srv.Store.User().Update(user, true)
schan := a.Srv.Store.Session().UpdateRoles(user.Id, newRoles)

Просмотреть файл

@@ -86,6 +86,8 @@ func runServer(configFileLocation string, disableConfigWatch bool, interruptChan
a.LoadLicense()
}
a.DoAdvancedPermissionsMigration()
a.InitPlugins(*a.Config().PluginSettings.Directory, *a.Config().PluginSettings.ClientDirectory, nil)
a.AddConfigListener(func(prevCfg, cfg *model.Config) {
if *cfg.PluginSettings.Enable {

Просмотреть файл

@@ -47,7 +47,7 @@
"RestrictCustomEmojiCreation": "all",
"RestrictPostDelete": "all",
"AllowEditPost": "always",
"PostEditTimeLimit": 300,
"PostEditTimeLimit": -1,
"ExperimentalEnableAuthenticationTransfer": true,
"TimeBetweenUserTypingUpdatesMilliseconds": 5000,
"EnablePostSearch": true,

Просмотреть файл

@@ -47,6 +47,10 @@
"id": "September",
"translation": "September"
},
{
"id": "api.roles.patch_roles.license.error",
"translation": "Your current license does not support advanced permissions."
},
{
"id": "api.admin.add_certificate.no_file.app_error",
"translation": "No file under 'certificate' in request."
@@ -2426,10 +2430,18 @@
"id": "api.templates.email_change_body.info",
"translation": "Your email address for {{.TeamDisplayName}} has been changed to {{.NewEmail}}.<br>If you did not make this change, please contact the system administrator."
},
{
"id": "app.role.check_roles_exist.role_not_found",
"translation": "The provided role does not exist"
},
{
"id": "api.templates.email_change_body.title",
"translation": "You updated your email"
},
{
"id": "store.sql_role.save.invalid_role.app_error",
"translation": "The role was not valid"
},
{
"id": "api.templates.email_change_subject",
"translation": "[{{ .SiteName }}] Your email address has changed"
@@ -6598,6 +6610,26 @@
"id": "store.sql_reaction.save.save.app_error",
"translation": "Unable to save reaction"
},
{
"id": "store.sql_role.save.insert.app_error",
"translation": "Unable to save new role"
},
{
"id": "store.sql_role.save.update.app_error",
"translation": "Unable to update role"
},
{
"id": "store.sql_role.get.app_error",
"translation": "Unable to get role"
},
{
"id": "store.sql_role.get_by_name.app_error",
"translation": "Unable to get role"
},
{
"id": "store.sql_role.get_by_names.app_error",
"translation": "Unable to get roles"
},
{
"id": "store.sql_session.analytics_session_count.app_error",
"translation": "We couldn't count the sessions"

Просмотреть файл

@@ -310,6 +310,10 @@ func (c *Client4) GetJobsRoute() string {
return fmt.Sprintf("/jobs")
}
func (c *Client4) GetRolesRoute() string {
return fmt.Sprintf("/roles")
}
func (c *Client4) GetAnalyticsRoute() string {
return fmt.Sprintf("/analytics")
}
@@ -3263,6 +3267,48 @@ func (c *Client4) CancelJob(jobId string) (bool, *Response) {
}
}
// Roles Section
// GetRole gets a single role by ID.
func (c *Client4) GetRole(id string) (*Role, *Response) {
if r, err := c.DoApiGet(c.GetRolesRoute()+fmt.Sprintf("/%v", id), ""); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
return RoleFromJson(r.Body), BuildResponse(r)
}
}
// GetRoleByName gets a single role by Name.
func (c *Client4) GetRoleByName(name string) (*Role, *Response) {
if r, err := c.DoApiGet(c.GetRolesRoute()+fmt.Sprintf("/name/%v", name), ""); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
return RoleFromJson(r.Body), BuildResponse(r)
}
}
// GetRolesByNames returns a list of roles based on the provided role names.
func (c *Client4) GetRolesByNames(roleNames []string) ([]*Role, *Response) {
if r, err := c.DoApiPost(c.GetRolesRoute()+"/names", ArrayToJson(roleNames)); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
return RoleListFromJson(r.Body), BuildResponse(r)
}
}
// PatchRole partially updates a role in the system. Any missing fields are not updated.
func (c *Client4) PatchRole(roleId string, patch *RolePatch) (*Role, *Response) {
if r, err := c.DoApiPut(c.GetRolesRoute()+fmt.Sprintf("/%v/patch", roleId), patch.ToJson()); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
return RoleFromJson(r.Body), BuildResponse(r)
}
}
// Plugin Section
// UploadPlugin takes an io.Reader stream pointing to the contents of a .tar.gz plugin.

Просмотреть файл

@@ -21,6 +21,7 @@ const (
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL = "inv_channel"
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER = "inv_user"
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER = "clear_session_user"
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES = "inv_roles"
CLUSTER_SEND_BEST_EFFORT = "best_effort"
CLUSTER_SEND_RELIABLE = "reliable"

Просмотреть файл

@@ -424,7 +424,7 @@ func (s *ServiceSettings) SetDefaults() {
}
if s.PostEditTimeLimit == nil {
s.PostEditTimeLimit = NewInt(300)
s.PostEditTimeLimit = NewInt(-1)
}
if s.EnablePreviewFeatures == nil {
@@ -967,7 +967,7 @@ func (s *ThemeSettings) SetDefaults() {
type TeamSettings struct {
SiteName string
MaxUsersPerTeam *int
EnableTeamCreation bool
EnableTeamCreation *bool
EnableUserCreation bool
EnableOpenServer *bool
RestrictCreationToDomains string
@@ -1090,6 +1090,10 @@ func (s *TeamSettings) SetDefaults() {
if s.ExperimentalPrimaryTeam == nil {
s.ExperimentalPrimaryTeam = NewString("")
}
if s.EnableTeamCreation == nil {
s.EnableTeamCreation = NewBool(true)
}
}
type ClientRequirements struct {

Просмотреть файл

@@ -3,17 +3,17 @@
package model
const (
PERMISSION_SCOPE_SYSTEM = "system_scope"
PERMISSION_SCOPE_TEAM = "team_scope"
PERMISSION_SCOPE_CHANNEL = "channel_scope"
)
type Permission struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
}
type Role struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Permissions []string `json:"permissions"`
Scope string `json:"scope"`
}
var PERMISSION_INVITE_USER *Permission
@@ -40,6 +40,9 @@ var PERMISSION_DELETE_PRIVATE_CHANNEL *Permission
var PERMISSION_EDIT_OTHER_USERS *Permission
var PERMISSION_READ_CHANNEL *Permission
var PERMISSION_READ_PUBLIC_CHANNEL *Permission
var PERMISSION_ADD_REACTION *Permission
var PERMISSION_REMOVE_REACTION *Permission
var PERMISSION_REMOVE_OTHERS_REACTIONS *Permission
var PERMISSION_PERMANENT_DELETE_USER *Permission
var PERMISSION_UPLOAD_FILE *Permission
var PERMISSION_GET_PUBLIC_LINK *Permission
@@ -64,446 +67,376 @@ var PERMISSION_CREATE_USER_ACCESS_TOKEN *Permission
var PERMISSION_READ_USER_ACCESS_TOKEN *Permission
var PERMISSION_REVOKE_USER_ACCESS_TOKEN *Permission
// General permission that encompases all system admin functions
// General permission that encompasses all system admin functions
// in the future this could be broken up to allow access to some
// admin functions but not others
var PERMISSION_MANAGE_SYSTEM *Permission
const (
SYSTEM_USER_ROLE_ID = "system_user"
SYSTEM_ADMIN_ROLE_ID = "system_admin"
SYSTEM_POST_ALL_ROLE_ID = "system_post_all"
SYSTEM_POST_ALL_PUBLIC_ROLE_ID = "system_post_all_public"
SYSTEM_USER_ACCESS_TOKEN_ROLE_ID = "system_user_access_token"
TEAM_USER_ROLE_ID = "team_user"
TEAM_ADMIN_ROLE_ID = "team_admin"
TEAM_POST_ALL_ROLE_ID = "team_post_all"
TEAM_POST_ALL_PUBLIC_ROLE_ID = "team_post_all_public"
CHANNEL_USER_ROLE_ID = "channel_user"
CHANNEL_ADMIN_ROLE_ID = "channel_admin"
CHANNEL_GUEST_ROLE_ID = "guest"
)
var ALL_PERMISSIONS []*Permission
func initializePermissions() {
PERMISSION_INVITE_USER = &Permission{
"invite_user",
"authentication.permissions.team_invite_user.name",
"authentication.permissions.team_invite_user.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_ADD_USER_TO_TEAM = &Permission{
"add_user_to_team",
"authentication.permissions.add_user_to_team.name",
"authentication.permissions.add_user_to_team.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_USE_SLASH_COMMANDS = &Permission{
"use_slash_commands",
"authentication.permissions.team_use_slash_commands.name",
"authentication.permissions.team_use_slash_commands.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_MANAGE_SLASH_COMMANDS = &Permission{
"manage_slash_commands",
"authentication.permissions.manage_slash_commands.name",
"authentication.permissions.manage_slash_commands.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS = &Permission{
"manage_others_slash_commands",
"authentication.permissions.manage_others_slash_commands.name",
"authentication.permissions.manage_others_slash_commands.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_CREATE_PUBLIC_CHANNEL = &Permission{
"create_public_channel",
"authentication.permissions.create_public_channel.name",
"authentication.permissions.create_public_channel.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_CREATE_PRIVATE_CHANNEL = &Permission{
"create_private_channel",
"authentication.permissions.create_private_channel.name",
"authentication.permissions.create_private_channel.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS = &Permission{
"manage_public_channel_members",
"authentication.permissions.manage_public_channel_members.name",
"authentication.permissions.manage_public_channel_members.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS = &Permission{
"manage_private_channel_members",
"authentication.permissions.manage_private_channel_members.name",
"authentication.permissions.manage_private_channel_members.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE = &Permission{
"assign_system_admin_role",
"authentication.permissions.assign_system_admin_role.name",
"authentication.permissions.assign_system_admin_role.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_ROLES = &Permission{
"manage_roles",
"authentication.permissions.manage_roles.name",
"authentication.permissions.manage_roles.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_TEAM_ROLES = &Permission{
"manage_team_roles",
"authentication.permissions.manage_team_roles.name",
"authentication.permissions.manage_team_roles.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_MANAGE_CHANNEL_ROLES = &Permission{
"manage_channel_roles",
"authentication.permissions.manage_channel_roles.name",
"authentication.permissions.manage_channel_roles.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_MANAGE_SYSTEM = &Permission{
"manage_system",
"authentication.permissions.manage_system.name",
"authentication.permissions.manage_system.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_CREATE_DIRECT_CHANNEL = &Permission{
"create_direct_channel",
"authentication.permissions.create_direct_channel.name",
"authentication.permissions.create_direct_channel.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_CREATE_GROUP_CHANNEL = &Permission{
"create_group_channel",
"authentication.permissions.create_group_channel.name",
"authentication.permissions.create_group_channel.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES = &Permission{
"manage__publicchannel_properties",
"manage_public_channel_properties",
"authentication.permissions.manage_public_channel_properties.name",
"authentication.permissions.manage_public_channel_properties.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES = &Permission{
"manage_private_channel_properties",
"authentication.permissions.manage_private_channel_properties.name",
"authentication.permissions.manage_private_channel_properties.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_LIST_TEAM_CHANNELS = &Permission{
"list_team_channels",
"authentication.permissions.list_team_channels.name",
"authentication.permissions.list_team_channels.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_JOIN_PUBLIC_CHANNELS = &Permission{
"join_public_channels",
"authentication.permissions.join_public_channels.name",
"authentication.permissions.join_public_channels.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_DELETE_PUBLIC_CHANNEL = &Permission{
"delete_public_channel",
"authentication.permissions.delete_public_channel.name",
"authentication.permissions.delete_public_channel.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_DELETE_PRIVATE_CHANNEL = &Permission{
"delete_private_channel",
"authentication.permissions.delete_private_channel.name",
"authentication.permissions.delete_private_channel.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_EDIT_OTHER_USERS = &Permission{
"edit_other_users",
"authentication.permissions.edit_other_users.name",
"authentication.permissions.edit_other_users.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_READ_CHANNEL = &Permission{
"read_channel",
"authentication.permissions.read_channel.name",
"authentication.permissions.read_channel.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_READ_PUBLIC_CHANNEL = &Permission{
"read_public_channel",
"authentication.permissions.read_public_channel.name",
"authentication.permissions.read_public_channel.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_ADD_REACTION = &Permission{
"add_reaction",
"authentication.permissions.add_reaction.name",
"authentication.permissions.add_reaction.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_REMOVE_REACTION = &Permission{
"remove_reaction",
"authentication.permissions.remove_reaction.name",
"authentication.permissions.remove_reaction.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_REMOVE_OTHERS_REACTIONS = &Permission{
"remove_others_reactions",
"authentication.permissions.remove_others_reactions.name",
"authentication.permissions.remove_others_reactions.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_PERMANENT_DELETE_USER = &Permission{
"permanent_delete_user",
"authentication.permissions.permanent_delete_user.name",
"authentication.permissions.permanent_delete_user.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_UPLOAD_FILE = &Permission{
"upload_file",
"authentication.permissions.upload_file.name",
"authentication.permissions.upload_file.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_GET_PUBLIC_LINK = &Permission{
"get_public_link",
"authentication.permissions.get_public_link.name",
"authentication.permissions.get_public_link.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_WEBHOOKS = &Permission{
"manage_webhooks",
"authentication.permissions.manage_webhooks.name",
"authentication.permissions.manage_webhooks.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_MANAGE_OTHERS_WEBHOOKS = &Permission{
"manage_others_webhooks",
"authentication.permissions.manage_others_webhooks.name",
"authentication.permissions.manage_others_webhooks.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_MANAGE_OAUTH = &Permission{
"manage_oauth",
"authentication.permissions.manage_oauth.name",
"authentication.permissions.manage_oauth.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH = &Permission{
"manage_sytem_wide_oauth",
"authentication.permissions.manage_sytem_wide_oauth.name",
"authentication.permissions.manage_sytem_wide_oauth.description",
"manage_system_wide_oauth",
"authentication.permissions.manage_system_wide_oauth.name",
"authentication.permissions.manage_system_wide_oauth.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_CREATE_POST = &Permission{
"create_post",
"authentication.permissions.create_post.name",
"authentication.permissions.create_post.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_CREATE_POST_PUBLIC = &Permission{
"create_post_public",
"authentication.permissions.create_post_public.name",
"authentication.permissions.create_post_public.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_EDIT_POST = &Permission{
"edit_post",
"authentication.permissions.edit_post.name",
"authentication.permissions.edit_post.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_EDIT_OTHERS_POSTS = &Permission{
"edit_others_posts",
"authentication.permissions.edit_others_posts.name",
"authentication.permissions.edit_others_posts.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_DELETE_POST = &Permission{
"delete_post",
"authentication.permissions.delete_post.name",
"authentication.permissions.delete_post.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_DELETE_OTHERS_POSTS = &Permission{
"delete_others_posts",
"authentication.permissions.delete_others_posts.name",
"authentication.permissions.delete_others_posts.description",
PERMISSION_SCOPE_CHANNEL,
}
PERMISSION_REMOVE_USER_FROM_TEAM = &Permission{
"remove_user_from_team",
"authentication.permissions.remove_user_from_team.name",
"authentication.permissions.remove_user_from_team.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_CREATE_TEAM = &Permission{
"create_team",
"authentication.permissions.create_team.name",
"authentication.permissions.create_team.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_TEAM = &Permission{
"manage_team",
"authentication.permissions.manage_team.name",
"authentication.permissions.manage_team.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_IMPORT_TEAM = &Permission{
"import_team",
"authentication.permissions.import_team.name",
"authentication.permissions.import_team.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_VIEW_TEAM = &Permission{
"view_team",
"authentication.permissions.view_team.name",
"authentication.permissions.view_team.description",
PERMISSION_SCOPE_TEAM,
}
PERMISSION_LIST_USERS_WITHOUT_TEAM = &Permission{
"list_users_without_team",
"authentication.permissions.list_users_without_team.name",
"authentication.permissions.list_users_without_team.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_CREATE_USER_ACCESS_TOKEN = &Permission{
"create_user_access_token",
"authentication.permissions.create_user_access_token.name",
"authentication.permissions.create_user_access_token.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_READ_USER_ACCESS_TOKEN = &Permission{
"read_user_access_token",
"authentication.permissions.read_user_access_token.name",
"authentication.permissions.read_user_access_token.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_REVOKE_USER_ACCESS_TOKEN = &Permission{
"revoke_user_access_token",
"authentication.permissions.revoke_user_access_token.name",
"authentication.permissions.revoke_user_access_token.description",
PERMISSION_SCOPE_SYSTEM,
}
PERMISSION_MANAGE_JOBS = &Permission{
"manage_jobs",
"authentication.permisssions.manage_jobs.name",
"authentication.permisssions.manage_jobs.description",
}
}
var DefaultRoles map[string]*Role
func initializeDefaultRoles() {
DefaultRoles = make(map[string]*Role)
DefaultRoles[CHANNEL_USER_ROLE_ID] = &Role{
"channel_user",
"authentication.roles.channel_user.name",
"authentication.roles.channel_user.description",
[]string{
PERMISSION_READ_CHANNEL.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
PERMISSION_UPLOAD_FILE.Id,
PERMISSION_GET_PUBLIC_LINK.Id,
PERMISSION_CREATE_POST.Id,
PERMISSION_EDIT_POST.Id,
PERMISSION_USE_SLASH_COMMANDS.Id,
},
PERMISSION_SCOPE_SYSTEM,
}
DefaultRoles[CHANNEL_ADMIN_ROLE_ID] = &Role{
"channel_admin",
"authentication.roles.channel_admin.name",
"authentication.roles.channel_admin.description",
[]string{
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
},
}
DefaultRoles[CHANNEL_GUEST_ROLE_ID] = &Role{
"guest",
"authentication.roles.global_guest.name",
"authentication.roles.global_guest.description",
[]string{},
}
DefaultRoles[TEAM_USER_ROLE_ID] = &Role{
"team_user",
"authentication.roles.team_user.name",
"authentication.roles.team_user.description",
[]string{
PERMISSION_LIST_TEAM_CHANNELS.Id,
PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
PERMISSION_READ_PUBLIC_CHANNEL.Id,
PERMISSION_VIEW_TEAM.Id,
},
}
DefaultRoles[TEAM_POST_ALL_ROLE_ID] = &Role{
"team_post_all",
"authentication.roles.team_post_all.name",
"authentication.roles.team_post_all.description",
[]string{
PERMISSION_CREATE_POST.Id,
},
}
DefaultRoles[TEAM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
"team_post_all_public",
"authentication.roles.team_post_all_public.name",
"authentication.roles.team_post_all_public.description",
[]string{
PERMISSION_CREATE_POST_PUBLIC.Id,
},
}
DefaultRoles[TEAM_ADMIN_ROLE_ID] = &Role{
"team_admin",
"authentication.roles.team_admin.name",
"authentication.roles.team_admin.description",
[]string{
PERMISSION_EDIT_OTHERS_POSTS.Id,
PERMISSION_REMOVE_USER_FROM_TEAM.Id,
PERMISSION_MANAGE_TEAM.Id,
PERMISSION_IMPORT_TEAM.Id,
PERMISSION_MANAGE_TEAM_ROLES.Id,
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
PERMISSION_MANAGE_SLASH_COMMANDS.Id,
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
PERMISSION_MANAGE_WEBHOOKS.Id,
},
}
DefaultRoles[SYSTEM_USER_ROLE_ID] = &Role{
"system_user",
"authentication.roles.global_user.name",
"authentication.roles.global_user.description",
[]string{
PERMISSION_CREATE_DIRECT_CHANNEL.Id,
PERMISSION_CREATE_GROUP_CHANNEL.Id,
PERMISSION_PERMANENT_DELETE_USER.Id,
},
}
DefaultRoles[SYSTEM_POST_ALL_ROLE_ID] = &Role{
"system_post_all",
"authentication.roles.system_post_all.name",
"authentication.roles.system_post_all.description",
[]string{
PERMISSION_CREATE_POST.Id,
},
}
DefaultRoles[SYSTEM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
"system_post_all_public",
"authentication.roles.system_post_all_public.name",
"authentication.roles.system_post_all_public.description",
[]string{
PERMISSION_CREATE_POST_PUBLIC.Id,
},
}
DefaultRoles[SYSTEM_USER_ACCESS_TOKEN_ROLE_ID] = &Role{
"system_user_access_token",
"authentication.roles.system_user_access_token.name",
"authentication.roles.system_user_access_token.description",
[]string{
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
},
}
DefaultRoles[SYSTEM_ADMIN_ROLE_ID] = &Role{
"system_admin",
"authentication.roles.global_admin.name",
"authentication.roles.global_admin.description",
// System admins can do anything channel and team admins can do
// plus everything members of teams and channels can do to all teams
// and channels on the system
append(
append(
append(
append(
[]string{
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
PERMISSION_MANAGE_SYSTEM.Id,
PERMISSION_MANAGE_ROLES.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
PERMISSION_EDIT_OTHER_USERS.Id,
PERMISSION_MANAGE_OAUTH.Id,
PERMISSION_INVITE_USER.Id,
PERMISSION_DELETE_POST.Id,
PERMISSION_DELETE_OTHERS_POSTS.Id,
PERMISSION_CREATE_TEAM.Id,
PERMISSION_ADD_USER_TO_TEAM.Id,
PERMISSION_LIST_USERS_WITHOUT_TEAM.Id,
PERMISSION_MANAGE_JOBS.Id,
PERMISSION_CREATE_POST_PUBLIC.Id,
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
},
DefaultRoles[TEAM_USER_ROLE_ID].Permissions...,
),
DefaultRoles[CHANNEL_USER_ROLE_ID].Permissions...,
),
DefaultRoles[TEAM_ADMIN_ROLE_ID].Permissions...,
),
DefaultRoles[CHANNEL_ADMIN_ROLE_ID].Permissions...,
),
ALL_PERMISSIONS = []*Permission{
PERMISSION_INVITE_USER,
PERMISSION_ADD_USER_TO_TEAM,
PERMISSION_USE_SLASH_COMMANDS,
PERMISSION_MANAGE_SLASH_COMMANDS,
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS,
PERMISSION_CREATE_PUBLIC_CHANNEL,
PERMISSION_CREATE_PRIVATE_CHANNEL,
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS,
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS,
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE,
PERMISSION_MANAGE_ROLES,
PERMISSION_MANAGE_TEAM_ROLES,
PERMISSION_MANAGE_CHANNEL_ROLES,
PERMISSION_CREATE_DIRECT_CHANNEL,
PERMISSION_CREATE_GROUP_CHANNEL,
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES,
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES,
PERMISSION_LIST_TEAM_CHANNELS,
PERMISSION_JOIN_PUBLIC_CHANNELS,
PERMISSION_DELETE_PUBLIC_CHANNEL,
PERMISSION_DELETE_PRIVATE_CHANNEL,
PERMISSION_EDIT_OTHER_USERS,
PERMISSION_READ_CHANNEL,
PERMISSION_READ_PUBLIC_CHANNEL,
PERMISSION_ADD_REACTION,
PERMISSION_REMOVE_REACTION,
PERMISSION_REMOVE_OTHERS_REACTIONS,
PERMISSION_PERMANENT_DELETE_USER,
PERMISSION_UPLOAD_FILE,
PERMISSION_GET_PUBLIC_LINK,
PERMISSION_MANAGE_WEBHOOKS,
PERMISSION_MANAGE_OTHERS_WEBHOOKS,
PERMISSION_MANAGE_OAUTH,
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH,
PERMISSION_CREATE_POST,
PERMISSION_CREATE_POST_PUBLIC,
PERMISSION_EDIT_POST,
PERMISSION_EDIT_OTHERS_POSTS,
PERMISSION_DELETE_POST,
PERMISSION_DELETE_OTHERS_POSTS,
PERMISSION_REMOVE_USER_FROM_TEAM,
PERMISSION_CREATE_TEAM,
PERMISSION_MANAGE_TEAM,
PERMISSION_IMPORT_TEAM,
PERMISSION_VIEW_TEAM,
PERMISSION_LIST_USERS_WITHOUT_TEAM,
PERMISSION_MANAGE_JOBS,
PERMISSION_CREATE_USER_ACCESS_TOKEN,
PERMISSION_READ_USER_ACCESS_TOKEN,
PERMISSION_REVOKE_USER_ACCESS_TOKEN,
PERMISSION_MANAGE_SYSTEM,
}
}
func init() {
initializePermissions()
initializeDefaultRoles()
}

18
model/permission_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,18 @@
package model
import (
"testing"
"github.com/stretchr/testify/assert"
)
// This is a test to ensure that we don't accidentally add more permissions than can fit
// in the database column for role permissions.
func TestPermissionsLength(t *testing.T) {
permissionsString := ""
for _, permission := range ALL_PERMISSIONS {
permissionsString += " " + permission.Id
}
assert.True(t, len(permissionsString) < 4096)
}

350
model/role.go Обычный файл
Просмотреть файл

@@ -0,0 +1,350 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
import (
"encoding/json"
"io"
"strings"
)
const (
SYSTEM_USER_ROLE_ID = "system_user"
SYSTEM_ADMIN_ROLE_ID = "system_admin"
SYSTEM_POST_ALL_ROLE_ID = "system_post_all"
SYSTEM_POST_ALL_PUBLIC_ROLE_ID = "system_post_all_public"
SYSTEM_USER_ACCESS_TOKEN_ROLE_ID = "system_user_access_token"
TEAM_USER_ROLE_ID = "team_user"
TEAM_ADMIN_ROLE_ID = "team_admin"
TEAM_POST_ALL_ROLE_ID = "team_post_all"
TEAM_POST_ALL_PUBLIC_ROLE_ID = "team_post_all_public"
CHANNEL_USER_ROLE_ID = "channel_user"
CHANNEL_ADMIN_ROLE_ID = "channel_admin"
ROLE_NAME_MAX_LENGTH = 64
ROLE_DISPLAY_NAME_MAX_LENGTH = 128
ROLE_DESCRIPTION_MAX_LENGTH = 1024
)
type Role struct {
Id string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
Permissions []string `json:"permissions"`
SchemeManaged bool `json:"scheme_managed"`
}
type RolePatch struct {
Permissions *[]string `json:"permissions"`
}
func (role *Role) ToJson() string {
b, _ := json.Marshal(role)
return string(b)
}
func RoleFromJson(data io.Reader) *Role {
var role *Role
json.NewDecoder(data).Decode(&role)
return role
}
func RoleListToJson(r []*Role) string {
b, _ := json.Marshal(r)
return string(b)
}
func RoleListFromJson(data io.Reader) []*Role {
var roles []*Role
json.NewDecoder(data).Decode(&roles)
return roles
}
func (r *RolePatch) ToJson() string {
b, _ := json.Marshal(r)
return string(b)
}
func RolePatchFromJson(data io.Reader) *RolePatch {
var rolePatch *RolePatch
json.NewDecoder(data).Decode(&rolePatch)
return rolePatch
}
func (o *Role) Patch(patch *RolePatch) {
if patch.Permissions != nil {
o.Permissions = *patch.Permissions
}
}
// Returns an array of permissions that are in either role.Permissions
// or patch.Permissions, but not both.
func PermissionsChangedByPatch(role *Role, patch *RolePatch) []string {
var result []string
if patch.Permissions == nil {
return result
}
roleMap := make(map[string]bool)
patchMap := make(map[string]bool)
for _, permission := range role.Permissions {
roleMap[permission] = true
}
for _, permission := range *patch.Permissions {
patchMap[permission] = true
}
for _, permission := range role.Permissions {
if !patchMap[permission] {
result = append(result, permission)
}
}
for _, permission := range *patch.Permissions {
if !roleMap[permission] {
result = append(result, permission)
}
}
return result
}
func (role *Role) IsValid() bool {
if len(role.Id) != 26 {
return false
}
return role.IsValidWithoutId()
}
func (role *Role) IsValidWithoutId() bool {
if !IsValidRoleName(role.Name) {
return false
}
if len(role.DisplayName) == 0 || len(role.DisplayName) > ROLE_DISPLAY_NAME_MAX_LENGTH {
return false
}
if len(role.Description) > ROLE_DESCRIPTION_MAX_LENGTH {
return false
}
for _, permission := range role.Permissions {
permissionValidated := false
for _, p := range ALL_PERMISSIONS {
if permission == p.Id {
permissionValidated = true
break
}
}
if !permissionValidated {
return false
}
}
return true
}
func IsValidRoleName(roleName string) bool {
if len(roleName) <= 0 || len(roleName) > ROLE_NAME_MAX_LENGTH {
return false
}
if strings.TrimLeft(roleName, "abcdefghijklmnopqrstuvwxyz0123456789_") != "" {
return false
}
return true
}
func MakeDefaultRoles() map[string]*Role {
roles := make(map[string]*Role)
roles[CHANNEL_USER_ROLE_ID] = &Role{
Name: "channel_user",
DisplayName: "authentication.roles.channel_user.name",
Description: "authentication.roles.channel_user.description",
Permissions: []string{
PERMISSION_READ_CHANNEL.Id,
PERMISSION_ADD_REACTION.Id,
PERMISSION_REMOVE_REACTION.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
PERMISSION_UPLOAD_FILE.Id,
PERMISSION_GET_PUBLIC_LINK.Id,
PERMISSION_CREATE_POST.Id,
PERMISSION_USE_SLASH_COMMANDS.Id,
},
SchemeManaged: true,
}
roles[CHANNEL_ADMIN_ROLE_ID] = &Role{
Name: "channel_admin",
DisplayName: "authentication.roles.channel_admin.name",
Description: "authentication.roles.channel_admin.description",
Permissions: []string{
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
},
SchemeManaged: true,
}
roles[TEAM_USER_ROLE_ID] = &Role{
Name: "team_user",
DisplayName: "authentication.roles.team_user.name",
Description: "authentication.roles.team_user.description",
Permissions: []string{
PERMISSION_LIST_TEAM_CHANNELS.Id,
PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
PERMISSION_READ_PUBLIC_CHANNEL.Id,
PERMISSION_VIEW_TEAM.Id,
},
SchemeManaged: true,
}
roles[TEAM_POST_ALL_ROLE_ID] = &Role{
Name: "team_post_all",
DisplayName: "authentication.roles.team_post_all.name",
Description: "authentication.roles.team_post_all.description",
Permissions: []string{
PERMISSION_CREATE_POST.Id,
},
SchemeManaged: true,
}
roles[TEAM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
Name: "team_post_all_public",
DisplayName: "authentication.roles.team_post_all_public.name",
Description: "authentication.roles.team_post_all_public.description",
Permissions: []string{
PERMISSION_CREATE_POST_PUBLIC.Id,
},
SchemeManaged: true,
}
roles[TEAM_ADMIN_ROLE_ID] = &Role{
Name: "team_admin",
DisplayName: "authentication.roles.team_admin.name",
Description: "authentication.roles.team_admin.description",
Permissions: []string{
PERMISSION_EDIT_OTHERS_POSTS.Id,
PERMISSION_REMOVE_USER_FROM_TEAM.Id,
PERMISSION_MANAGE_TEAM.Id,
PERMISSION_IMPORT_TEAM.Id,
PERMISSION_MANAGE_TEAM_ROLES.Id,
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
PERMISSION_MANAGE_SLASH_COMMANDS.Id,
PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS.Id,
PERMISSION_MANAGE_WEBHOOKS.Id,
},
SchemeManaged: true,
}
roles[SYSTEM_USER_ROLE_ID] = &Role{
Name: "system_user",
DisplayName: "authentication.roles.global_user.name",
Description: "authentication.roles.global_user.description",
Permissions: []string{
PERMISSION_CREATE_DIRECT_CHANNEL.Id,
PERMISSION_CREATE_GROUP_CHANNEL.Id,
PERMISSION_PERMANENT_DELETE_USER.Id,
},
SchemeManaged: true,
}
roles[SYSTEM_POST_ALL_ROLE_ID] = &Role{
Name: "system_post_all",
DisplayName: "authentication.roles.system_post_all.name",
Description: "authentication.roles.system_post_all.description",
Permissions: []string{
PERMISSION_CREATE_POST.Id,
},
SchemeManaged: true,
}
roles[SYSTEM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
Name: "system_post_all_public",
DisplayName: "authentication.roles.system_post_all_public.name",
Description: "authentication.roles.system_post_all_public.description",
Permissions: []string{
PERMISSION_CREATE_POST_PUBLIC.Id,
},
SchemeManaged: true,
}
roles[SYSTEM_USER_ACCESS_TOKEN_ROLE_ID] = &Role{
Name: "system_user_access_token",
DisplayName: "authentication.roles.system_user_access_token.name",
Description: "authentication.roles.system_user_access_token.description",
Permissions: []string{
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
},
SchemeManaged: true,
}
roles[SYSTEM_ADMIN_ROLE_ID] = &Role{
Name: "system_admin",
DisplayName: "authentication.roles.global_admin.name",
Description: "authentication.roles.global_admin.description",
// System admins can do anything channel and team admins can do
// plus everything members of teams and channels can do to all teams
// and channels on the system
Permissions: append(
append(
append(
append(
[]string{
PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
PERMISSION_MANAGE_SYSTEM.Id,
PERMISSION_MANAGE_ROLES.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id,
PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
PERMISSION_DELETE_PUBLIC_CHANNEL.Id,
PERMISSION_CREATE_PUBLIC_CHANNEL.Id,
PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id,
PERMISSION_DELETE_PRIVATE_CHANNEL.Id,
PERMISSION_CREATE_PRIVATE_CHANNEL.Id,
PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
PERMISSION_MANAGE_OTHERS_WEBHOOKS.Id,
PERMISSION_EDIT_OTHER_USERS.Id,
PERMISSION_MANAGE_OAUTH.Id,
PERMISSION_INVITE_USER.Id,
PERMISSION_DELETE_POST.Id,
PERMISSION_DELETE_OTHERS_POSTS.Id,
PERMISSION_CREATE_TEAM.Id,
PERMISSION_ADD_USER_TO_TEAM.Id,
PERMISSION_LIST_USERS_WITHOUT_TEAM.Id,
PERMISSION_MANAGE_JOBS.Id,
PERMISSION_CREATE_POST_PUBLIC.Id,
PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
PERMISSION_REMOVE_OTHERS_REACTIONS.Id,
},
roles[TEAM_USER_ROLE_ID].Permissions...,
),
roles[CHANNEL_USER_ROLE_ID].Permissions...,
),
roles[TEAM_ADMIN_ROLE_ID].Permissions...,
),
roles[CHANNEL_ADMIN_ROLE_ID].Permissions...,
),
SchemeManaged: true,
}
return roles
}

Просмотреть файл

@@ -432,7 +432,7 @@ func IsValidUserRoles(userRoles string) bool {
roles := strings.Fields(userRoles)
for _, r := range roles {
if !isValidRole(r) {
if !IsValidRoleName(r) {
return false
}
}
@@ -445,11 +445,6 @@ func IsValidUserRoles(userRoles string) bool {
return true
}
func isValidRole(roleId string) bool {
_, ok := DefaultRoles[roleId]
return ok
}
// Make sure you acually want to use this function. In context.go there are functions to check permissions
// This function should not be used to check permissions.
func (u *User) IsInRole(inRole string) bool {

Просмотреть файл

@@ -287,11 +287,11 @@ func TestCleanUsername(t *testing.T) {
func TestRoles(t *testing.T) {
if IsValidUserRoles("admin") {
if !IsValidUserRoles("team_user") {
t.Fatal()
}
if IsValidUserRoles("junk") {
if IsValidUserRoles("system_admin") {
t.Fatal()
}

Просмотреть файл

@@ -44,6 +44,7 @@ const (
WEBSOCKET_EVENT_CHANNEL_VIEWED = "channel_viewed"
WEBSOCKET_EVENT_PLUGIN_ACTIVATED = "plugin_activated" // EXPERIMENTAL - SUBJECT TO CHANGE
WEBSOCKET_EVENT_PLUGIN_DEACTIVATED = "plugin_deactivated" // EXPERIMENTAL - SUBJECT TO CHANGE
WEBSOCKET_EVENT_ROLE_UPDATED = "role_updated"
WEBSOCKET_EVENT_LICENSE_CHANGED = "license_changed"
WEBSOCKET_EVENT_CONFIG_CHANGED = "config_changed"
)

Просмотреть файл

@@ -23,6 +23,7 @@ type LayeredStoreDatabaseLayer interface {
type LayeredStore struct {
TmpContext context.Context
ReactionStore ReactionStore
RoleStore RoleStore
DatabaseLayer LayeredStoreDatabaseLayer
LocalCacheLayer *LocalCacheSupplier
RedisLayer *RedisSupplier
@@ -37,6 +38,7 @@ func NewLayeredStore(db LayeredStoreDatabaseLayer, metrics einterfaces.MetricsIn
}
store.ReactionStore = &LayeredReactionStore{store}
store.RoleStore = &LayeredRoleStore{store}
// Setup the chain
if ENABLE_EXPERIMENTAL_REDIS {
@@ -161,6 +163,10 @@ func (s *LayeredStore) Plugin() PluginStore {
return s.DatabaseLayer.Plugin()
}
func (s *LayeredStore) Role() RoleStore {
return s.RoleStore
}
func (s *LayeredStore) MarkSystemRanUnitTests() {
s.DatabaseLayer.MarkSystemRanUnitTests()
}
@@ -218,3 +224,31 @@ func (s *LayeredReactionStore) PermanentDeleteBatch(endTime int64, limit int64)
return supplier.ReactionPermanentDeleteBatch(s.TmpContext, endTime, limit)
})
}
type LayeredRoleStore struct {
*LayeredStore
}
func (s *LayeredRoleStore) Save(role *model.Role) StoreChannel {
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
return supplier.RoleSave(s.TmpContext, role)
})
}
func (s *LayeredRoleStore) Get(roleId string) StoreChannel {
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
return supplier.RoleGet(s.TmpContext, roleId)
})
}
func (s *LayeredRoleStore) GetByName(name string) StoreChannel {
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
return supplier.RoleGetByName(s.TmpContext, name)
})
}
func (s *LayeredRoleStore) GetByNames(names []string) StoreChannel {
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
return supplier.RoleGetByNames(s.TmpContext, names)
})
}

Просмотреть файл

@@ -29,4 +29,10 @@ type LayeredStoreSupplier interface {
ReactionGetForPost(ctx context.Context, postId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
ReactionDeleteAllWithEmojiName(ctx context.Context, emojiName string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
ReactionPermanentDeleteBatch(ctx context.Context, endTime int64, limit int64, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
// Roles
RoleSave(ctx context.Context, role *model.Role, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
RoleGet(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
RoleGetByName(ctx context.Context, name string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
RoleGetByNames(ctx context.Context, names []string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
}

Просмотреть файл

@@ -13,7 +13,10 @@ import (
const (
REACTION_CACHE_SIZE = 20000
REACTION_CACHE_SEC = 1800 // 30 minutes
REACTION_CACHE_SEC = 30 * 60
ROLE_CACHE_SIZE = 20000
ROLE_CACHE_SEC = 30 * 60
CLEAR_CACHE_MESSAGE_DATA = ""
)
@@ -21,6 +24,7 @@ const (
type LocalCacheSupplier struct {
next LayeredStoreSupplier
reactionCache *utils.Cache
roleCache *utils.Cache
metrics einterfaces.MetricsInterface
cluster einterfaces.ClusterInterface
}
@@ -28,12 +32,14 @@ type LocalCacheSupplier struct {
func NewLocalCacheSupplier(metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface) *LocalCacheSupplier {
supplier := &LocalCacheSupplier{
reactionCache: utils.NewLruWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS),
roleCache: utils.NewLruWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES),
metrics: metrics,
cluster: cluster,
}
if cluster != nil {
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS, supplier.handleClusterInvalidateReaction)
cluster.RegisterClusterMessageHandler(model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES, supplier.handleClusterInvalidateRole)
}
return supplier

70
store/local_cache_supplier_roles.go Обычный файл
Просмотреть файл

@@ -0,0 +1,70 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package store
import (
"context"
"github.com/mattermost/mattermost-server/model"
)
func (s *LocalCacheSupplier) handleClusterInvalidateRole(msg *model.ClusterMessage) {
if msg.Data == CLEAR_CACHE_MESSAGE_DATA {
s.roleCache.Purge()
} else {
s.roleCache.Remove(msg.Data)
}
}
func (s *LocalCacheSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
if len(role.Id) != 0 {
defer s.doInvalidateCacheCluster(s.roleCache, role.Name)
}
return s.Next().RoleSave(ctx, role, hints...)
}
func (s *LocalCacheSupplier) RoleGet(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// Roles are cached by name, as that is most commonly how they are looked up.
// This means that no caching is supported on roles being looked up by ID.
return s.Next().RoleGet(ctx, roleId, hints...)
}
func (s *LocalCacheSupplier) RoleGetByName(ctx context.Context, name string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
if result := s.doStandardReadCache(ctx, s.roleCache, name, hints...); result != nil {
return result
}
result := s.Next().RoleGetByName(ctx, name, hints...)
s.doStandardAddToCache(ctx, s.roleCache, name, result, hints...)
return result
}
func (s *LocalCacheSupplier) RoleGetByNames(ctx context.Context, roleNames []string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
var foundRoles []*model.Role
var rolesToQuery []string
for _, roleName := range roleNames {
if result := s.doStandardReadCache(ctx, s.roleCache, roleName, hints...); result != nil {
foundRoles = append(foundRoles, result.Data.(*model.Role))
} else {
rolesToQuery = append(rolesToQuery, roleName)
}
}
result := s.Next().RoleGetByNames(ctx, rolesToQuery, hints...)
if result.Data != nil {
rolesFound := result.Data.([]*model.Role)
for _, role := range rolesFound {
res := NewSupplierResult()
res.Data = role
s.doStandardAddToCache(ctx, s.roleCache, role.Name, res, hints...)
}
result.Data = append(foundRoles, result.Data.([]*model.Role)...)
}
return result
}

Просмотреть файл

@@ -5,14 +5,12 @@ package store
import (
"bytes"
"context"
"encoding/gob"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/go-redis/redis"
"github.com/mattermost/mattermost-server/model"
)
const REDIS_EXPIRY_TIME = 30 * time.Minute
@@ -87,48 +85,3 @@ func (s *RedisSupplier) SetChainNext(next LayeredStoreSupplier) {
func (s *RedisSupplier) Next() LayeredStoreSupplier {
return s.next
}
func (s *RedisSupplier) ReactionSave(ctx context.Context, reaction *model.Reaction, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
if err := s.client.Del("reactions:" + reaction.PostId).Err(); err != nil {
l4g.Error("Redis failed to remove key reactions:" + reaction.PostId + " Error: " + err.Error())
}
return s.Next().ReactionSave(ctx, reaction, hints...)
}
func (s *RedisSupplier) ReactionDelete(ctx context.Context, reaction *model.Reaction, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
if err := s.client.Del("reactions:" + reaction.PostId).Err(); err != nil {
l4g.Error("Redis failed to remove key reactions:" + reaction.PostId + " Error: " + err.Error())
}
return s.Next().ReactionDelete(ctx, reaction, hints...)
}
func (s *RedisSupplier) ReactionGetForPost(ctx context.Context, postId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
var resultdata []*model.Reaction
found, err := s.load("reactions:"+postId, &resultdata)
if found {
result := NewSupplierResult()
result.Data = resultdata
return result
}
if err != nil {
l4g.Error("Redis encountered an error on read: " + err.Error())
}
result := s.Next().ReactionGetForPost(ctx, postId, hints...)
if err := s.save("reactions:"+postId, result.Data, REDIS_EXPIRY_TIME); err != nil {
l4g.Error("Redis encountered and error on write: " + err.Error())
}
return result
}
func (s *RedisSupplier) ReactionDeleteAllWithEmojiName(ctx context.Context, emojiName string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// Ignoring this. It's probably OK to have the emoji slowly expire from Redis.
return s.Next().ReactionDeleteAllWithEmojiName(ctx, emojiName, hints...)
}
func (s *RedisSupplier) ReactionPermanentDeleteBatch(ctx context.Context, endTime int64, limit int64, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// Ignoring this. It's probably OK to have the emoji slowly expire from Redis.
return s.Next().ReactionPermanentDeleteBatch(ctx, endTime, limit, hints...)
}

57
store/redis_supplier_reactions.go Обычный файл
Просмотреть файл

@@ -0,0 +1,57 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package store
import (
"context"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/model"
)
func (s *RedisSupplier) ReactionSave(ctx context.Context, reaction *model.Reaction, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
if err := s.client.Del("reactions:" + reaction.PostId).Err(); err != nil {
l4g.Error("Redis failed to remove key reactions:" + reaction.PostId + " Error: " + err.Error())
}
return s.Next().ReactionSave(ctx, reaction, hints...)
}
func (s *RedisSupplier) ReactionDelete(ctx context.Context, reaction *model.Reaction, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
if err := s.client.Del("reactions:" + reaction.PostId).Err(); err != nil {
l4g.Error("Redis failed to remove key reactions:" + reaction.PostId + " Error: " + err.Error())
}
return s.Next().ReactionDelete(ctx, reaction, hints...)
}
func (s *RedisSupplier) ReactionGetForPost(ctx context.Context, postId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
var resultdata []*model.Reaction
found, err := s.load("reactions:"+postId, &resultdata)
if found {
result := NewSupplierResult()
result.Data = resultdata
return result
}
if err != nil {
l4g.Error("Redis encountered an error on read: " + err.Error())
}
result := s.Next().ReactionGetForPost(ctx, postId, hints...)
if err := s.save("reactions:"+postId, result.Data, REDIS_EXPIRY_TIME); err != nil {
l4g.Error("Redis encountered and error on write: " + err.Error())
}
return result
}
func (s *RedisSupplier) ReactionDeleteAllWithEmojiName(ctx context.Context, emojiName string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// Ignoring this. It's probably OK to have the emoji slowly expire from Redis.
return s.Next().ReactionDeleteAllWithEmojiName(ctx, emojiName, hints...)
}
func (s *RedisSupplier) ReactionPermanentDeleteBatch(ctx context.Context, endTime int64, limit int64, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// Ignoring this. It's probably OK to have the emoji slowly expire from Redis.
return s.Next().ReactionPermanentDeleteBatch(ctx, endTime, limit, hints...)
}

89
store/redis_supplier_roles.go Обычный файл
Просмотреть файл

@@ -0,0 +1,89 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package store
import (
"context"
"fmt"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/model"
)
func (s *RedisSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
key := buildRedisKeyForRoleName(role.Name)
if err := s.client.Del(key).Err(); err != nil {
l4g.Error("Redis failed to remove key " + key + " Error: " + err.Error())
}
return s.Next().RoleSave(ctx, role, hints...)
}
func (s *RedisSupplier) RoleGet(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// Roles are cached by name, as that is most commonly how they are looked up.
// This means that no caching is supported on roles being looked up by ID.
return s.Next().RoleGet(ctx, roleId, hints...)
}
func (s *RedisSupplier) RoleGetByName(ctx context.Context, name string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
key := buildRedisKeyForRoleName(name)
var role *model.Role
found, err := s.load(key, &role)
if err != nil {
l4g.Error("Redis encountered an error on read: " + err.Error())
} else if found {
result := NewSupplierResult()
result.Data = role
return result
}
result := s.Next().RoleGetByName(ctx, name, hints...)
if result.Err == nil {
if err := s.save(key, result.Data, REDIS_EXPIRY_TIME); err != nil {
l4g.Error("Redis encountered and error on write: " + err.Error())
}
}
return result
}
func (s *RedisSupplier) RoleGetByNames(ctx context.Context, roleNames []string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
var foundRoles []*model.Role
var rolesToQuery []string
for _, roleName := range roleNames {
var role *model.Role
found, err := s.load(buildRedisKeyForRoleName(roleName), &role)
if err == nil && found {
foundRoles = append(foundRoles, role)
} else {
rolesToQuery = append(rolesToQuery, roleName)
if err != nil {
l4g.Error("Redis encountered an error on read: " + err.Error())
}
}
}
result := s.Next().RoleGetByNames(ctx, rolesToQuery, hints...)
if result.Err == nil {
rolesFound := result.Data.([]*model.Role)
for _, role := range rolesFound {
if err := s.save(buildRedisKeyForRoleName(role.Name), role, REDIS_EXPIRY_TIME); err != nil {
l4g.Error("Redis encountered and error on write: " + err.Error())
}
}
result.Data = append(foundRoles, result.Data.([]*model.Role)...)
}
return result
}
func buildRedisKeyForRoleName(roleName string) string {
return fmt.Sprintf("roles:%s", roleName)
}

14
store/sqlstore/role_store_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,14 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package sqlstore
import (
"testing"
"github.com/mattermost/mattermost-server/store/storetest"
)
func TestRoleStore(t *testing.T) {
StoreTest(t, storetest.TestRoleStore)
}

175
store/sqlstore/role_supplier.go Обычный файл
Просмотреть файл

@@ -0,0 +1,175 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package sqlstore
import (
"context"
"database/sql"
"fmt"
"net/http"
"strings"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
)
type Role struct {
Id string
Name string
DisplayName string
Description string
CreateAt int64
UpdateAt int64
DeleteAt int64
Permissions string
SchemeManaged bool
}
func NewRoleFromModel(role *model.Role) *Role {
permissionsMap := make(map[string]bool)
permissions := ""
for _, permission := range role.Permissions {
if !permissionsMap[permission] {
permissions += fmt.Sprintf(" %v", permission)
permissionsMap[permission] = true
}
}
return &Role{
Id: role.Id,
Name: role.Name,
DisplayName: role.DisplayName,
Description: role.Description,
CreateAt: role.CreateAt,
UpdateAt: role.UpdateAt,
DeleteAt: role.DeleteAt,
Permissions: permissions,
SchemeManaged: role.SchemeManaged,
}
}
func (role Role) ToModel() *model.Role {
return &model.Role{
Id: role.Id,
Name: role.Name,
DisplayName: role.DisplayName,
Description: role.Description,
CreateAt: role.CreateAt,
UpdateAt: role.UpdateAt,
DeleteAt: role.DeleteAt,
Permissions: strings.Fields(role.Permissions),
SchemeManaged: role.SchemeManaged,
}
}
func initSqlSupplierRoles(sqlStore SqlStore) {
for _, db := range sqlStore.GetAllConns() {
table := db.AddTableWithName(Role{}, "Roles").SetKeys(false, "Id")
table.ColMap("Name").SetMaxSize(64).SetUnique(true)
table.ColMap("DisplayName").SetMaxSize(128)
table.ColMap("Description").SetMaxSize(1024)
table.ColMap("Permissions").SetMaxSize(4096)
}
}
func (s *SqlSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
result := store.NewSupplierResult()
// Check the role is valid before proceeding.
if !role.IsValidWithoutId() {
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.invalid_role.app_error", nil, "", http.StatusBadRequest)
return result
}
dbRole := NewRoleFromModel(role)
if len(dbRole.Id) == 0 {
dbRole.Id = model.NewId()
dbRole.CreateAt = model.GetMillis()
dbRole.UpdateAt = dbRole.CreateAt
if err := s.GetMaster().Insert(dbRole); err != nil {
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError)
}
} else {
dbRole.UpdateAt = model.GetMillis()
if rowsChanged, err := s.GetMaster().Update(dbRole); err != nil {
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, err.Error(), http.StatusInternalServerError)
} else if rowsChanged != 1 {
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, "no record to update", http.StatusInternalServerError)
}
}
result.Data = dbRole.ToModel()
return result
}
func (s *SqlSupplier) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
result := store.NewSupplierResult()
var dbRole Role
if err := s.GetReplica().SelectOne(&dbRole, "SELECT * from Roles WHERE Id = :Id", map[string]interface{}{"Id": roleId}); err != nil {
if err == sql.ErrNoRows {
result.Err = model.NewAppError("SqlRoleStore.Get", "store.sql_role.get.app_error", nil, "Id="+roleId+", "+err.Error(), http.StatusNotFound)
} else {
result.Err = model.NewAppError("SqlRoleStore.Get", "store.sql_role.get.app_error", nil, err.Error(), http.StatusInternalServerError)
}
}
result.Data = dbRole.ToModel()
return result
}
func (s *SqlSupplier) RoleGetByName(ctx context.Context, name string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
result := store.NewSupplierResult()
var dbRole Role
if err := s.GetReplica().SelectOne(&dbRole, "SELECT * from Roles WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil {
if err == sql.ErrNoRows {
result.Err = model.NewAppError("SqlRoleStore.GetByName", "store.sql_role.get_by_name.app_error", nil, "name="+name+",err="+err.Error(), http.StatusNotFound)
} else {
result.Err = model.NewAppError("SqlRoleStore.GetByName", "store.sql_role.get_by_name.app_error", nil, "name="+name+",err="+err.Error(), http.StatusInternalServerError)
}
}
result.Data = dbRole.ToModel()
return result
}
func (s *SqlSupplier) RoleGetByNames(ctx context.Context, names []string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
result := store.NewSupplierResult()
var dbRoles []*Role
if len(names) == 0 {
result.Data = []*model.Role{}
return result
}
var searchPlaceholders []string
var parameters = map[string]interface{}{}
for i, value := range names {
searchPlaceholders = append(searchPlaceholders, fmt.Sprintf(":Name%d", i))
parameters[fmt.Sprintf("Name%d", i)] = value
}
searchTerm := "Name IN (" + strings.Join(searchPlaceholders, ", ") + ")"
if _, err := s.GetReplica().Select(&dbRoles, "SELECT * from Roles WHERE "+searchTerm, parameters); err != nil {
result.Err = model.NewAppError("SqlRoleStore.GetByNames", "store.sql_role.get_by_names.app_error", nil, err.Error(), http.StatusInternalServerError)
}
var roles []*model.Role
for _, dbRole := range dbRoles {
roles = append(roles, dbRole.ToModel())
}
result.Data = roles
return result
}

Просмотреть файл

@@ -87,4 +87,5 @@ type SqlStore interface {
Job() store.JobStore
Plugin() store.PluginStore
UserAccessToken() store.UserAccessTokenStore
Role() store.RoleStore
}

Просмотреть файл

@@ -86,6 +86,7 @@ type SqlSupplierOldStores struct {
userAccessToken store.UserAccessTokenStore
plugin store.PluginStore
channelMemberHistory store.ChannelMemberHistoryStore
role store.RoleStore
}
type SqlSupplier struct {
@@ -135,6 +136,7 @@ func NewSqlSupplier(settings model.SqlSettings, metrics einterfaces.MetricsInter
supplier.oldStores.plugin = NewSqlPluginStore(supplier)
initSqlSupplierReactions(supplier)
initSqlSupplierRoles(supplier)
err := supplier.GetMaster().CreateTablesIfNotExists()
if err != nil {
@@ -811,6 +813,10 @@ func (ss *SqlSupplier) Plugin() store.PluginStore {
return ss.oldStores.plugin
}
func (ss *SqlSupplier) Role() store.RoleStore {
return ss.oldStores.role
}
func (ss *SqlSupplier) DropAllTables() {
ss.master.TruncateTables()
}

Просмотреть файл

@@ -374,6 +374,10 @@ func UpgradeDatabaseToVersion48(sqlStore SqlStore) {
}
func UpgradeDatabaseToVersion49(sqlStore SqlStore) {
// This version of Mattermost includes an App-Layer migration which migrates from hard-coded roles configured by
// a number of parameters in `config.json` to a `Roles` table in the database. The migration code can be seen
// in the file `app/app.go` in the function `DoAdvancedPermissionsMigration()`.
//TODO: Uncomment the following condition when version 4.9.0 is released
//if shouldPerformUpgrade(sqlStore, VERSION_4_8_0, VERSION_4_9_0) {
sqlStore.CreateColumnIfNotExists("Teams", "LastTeamIconUpdate", "bigint", "bigint", "0")

Просмотреть файл

@@ -61,6 +61,7 @@ type Store interface {
Status() StatusStore
FileInfo() FileInfoStore
Reaction() ReactionStore
Role() RoleStore
Job() JobStore
UserAccessToken() UserAccessTokenStore
ChannelMemberHistory() ChannelMemberHistoryStore
@@ -469,3 +470,10 @@ type PluginStore interface {
Get(pluginId, key string) StoreChannel
Delete(pluginId, key string) StoreChannel
}
type RoleStore interface {
Save(role *model.Role) StoreChannel
Get(roleId string) StoreChannel
GetByName(name string) StoreChannel
GetByNames(names []string) StoreChannel
}

Просмотреть файл

@@ -416,6 +416,114 @@ func (_m *LayeredStoreDatabaseLayer) ReactionSave(ctx context.Context, reaction
return r0
}
// Role provides a mock function with given fields:
func (_m *LayeredStoreDatabaseLayer) Role() store.RoleStore {
ret := _m.Called()
var r0 store.RoleStore
if rf, ok := ret.Get(0).(func() store.RoleStore); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.RoleStore)
}
}
return r0
}
// RoleGet provides a mock function with given fields: ctx, roleId, hints
func (_m *LayeredStoreDatabaseLayer) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, roleId)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, roleId, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// RoleGetByName provides a mock function with given fields: ctx, name, hints
func (_m *LayeredStoreDatabaseLayer) RoleGetByName(ctx context.Context, name string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, name)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, name, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// RoleGetByNames provides a mock function with given fields: ctx, names, hints
func (_m *LayeredStoreDatabaseLayer) RoleGetByNames(ctx context.Context, names []string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, names)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, []string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, names, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// RoleSave provides a mock function with given fields: ctx, role, hints
func (_m *LayeredStoreDatabaseLayer) RoleSave(ctx context.Context, role *model.Role, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, role)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, *model.Role, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, role, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// Session provides a mock function with given fields:
func (_m *LayeredStoreDatabaseLayer) Session() store.SessionStore {
ret := _m.Called()

Просмотреть файл

@@ -145,6 +145,98 @@ func (_m *LayeredStoreSupplier) ReactionSave(ctx context.Context, reaction *mode
return r0
}
// RoleGet provides a mock function with given fields: ctx, roleId, hints
func (_m *LayeredStoreSupplier) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, roleId)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, roleId, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// RoleGetByName provides a mock function with given fields: ctx, name, hints
func (_m *LayeredStoreSupplier) RoleGetByName(ctx context.Context, name string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, name)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, name, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// RoleGetByNames provides a mock function with given fields: ctx, names, hints
func (_m *LayeredStoreSupplier) RoleGetByNames(ctx context.Context, names []string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, names)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, []string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, names, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// RoleSave provides a mock function with given fields: ctx, role, hints
func (_m *LayeredStoreSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
for _i := range hints {
_va[_i] = hints[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, role)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *store.LayeredStoreSupplierResult
if rf, ok := ret.Get(0).(func(context.Context, *model.Role, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
r0 = rf(ctx, role, hints...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
}
}
return r0
}
// SetChainNext provides a mock function with given fields: _a0
func (_m *LayeredStoreSupplier) SetChainNext(_a0 store.LayeredStoreSupplier) {
_m.Called(_a0)

78
store/storetest/mocks/RoleStore.go Обычный файл
Просмотреть файл

@@ -0,0 +1,78 @@
// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
package mocks
import mock "github.com/stretchr/testify/mock"
import model "github.com/mattermost/mattermost-server/model"
import store "github.com/mattermost/mattermost-server/store"
// RoleStore is an autogenerated mock type for the RoleStore type
type RoleStore struct {
mock.Mock
}
// Get provides a mock function with given fields: roleId
func (_m *RoleStore) Get(roleId string) store.StoreChannel {
ret := _m.Called(roleId)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
r0 = rf(roleId)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// GetByName provides a mock function with given fields: name
func (_m *RoleStore) GetByName(name string) store.StoreChannel {
ret := _m.Called(name)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
r0 = rf(name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// GetByNames provides a mock function with given fields: names
func (_m *RoleStore) GetByNames(names []string) store.StoreChannel {
ret := _m.Called(names)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func([]string) store.StoreChannel); ok {
r0 = rf(names)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}
// Save provides a mock function with given fields: role
func (_m *RoleStore) Save(role *model.Role) store.StoreChannel {
ret := _m.Called(role)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(*model.Role) store.StoreChannel); ok {
r0 = rf(role)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
}
}
return r0
}

Просмотреть файл

@@ -538,6 +538,22 @@ func (_m *SqlStore) RenameColumnIfExists(tableName string, oldColumnName string,
return r0
}
// Role provides a mock function with given fields:
func (_m *SqlStore) Role() store.RoleStore {
ret := _m.Called()
var r0 store.RoleStore
if rf, ok := ret.Get(0).(func() store.RoleStore); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.RoleStore)
}
}
return r0
}
// Session provides a mock function with given fields:
func (_m *SqlStore) Session() store.SessionStore {
ret := _m.Called()

Просмотреть файл

@@ -283,6 +283,22 @@ func (_m *Store) Reaction() store.ReactionStore {
return r0
}
// Role provides a mock function with given fields:
func (_m *Store) Role() store.RoleStore {
ret := _m.Called()
var r0 store.RoleStore
if rf, ok := ret.Get(0).(func() store.RoleStore); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.RoleStore)
}
}
return r0
}
// Session provides a mock function with given fields:
func (_m *Store) Session() store.SessionStore {
ret := _m.Called()

244
store/storetest/role_store.go Обычный файл
Просмотреть файл

@@ -0,0 +1,244 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package storetest
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
)
func TestRoleStore(t *testing.T, ss store.Store) {
t.Run("Save", func(t *testing.T) { testRoleStoreSave(t, ss) })
t.Run("Get", func(t *testing.T) { testRoleStoreGet(t, ss) })
t.Run("GetByName", func(t *testing.T) { testRoleStoreGetByName(t, ss) })
t.Run("GetNames", func(t *testing.T) { testRoleStoreGetByNames(t, ss) })
}
func testRoleStoreSave(t *testing.T, ss store.Store) {
// Save a new role.
r1 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
res1 := <-ss.Role().Save(r1)
assert.Nil(t, res1.Err)
d1 := res1.Data.(*model.Role)
assert.Len(t, d1.Id, 26)
assert.Equal(t, r1.Name, d1.Name)
assert.Equal(t, r1.DisplayName, d1.DisplayName)
assert.Equal(t, r1.Description, d1.Description)
assert.Equal(t, r1.Permissions, d1.Permissions)
assert.Equal(t, r1.SchemeManaged, d1.SchemeManaged)
// Change the role permissions and update.
d1.Permissions = []string{
"invite_user",
"add_user_to_team",
"delete_public_channel",
}
res2 := <-ss.Role().Save(d1)
assert.Nil(t, res2.Err)
d2 := res2.Data.(*model.Role)
assert.Len(t, d2.Id, 26)
assert.Equal(t, r1.Name, d2.Name)
assert.Equal(t, r1.DisplayName, d2.DisplayName)
assert.Equal(t, r1.Description, d2.Description)
assert.Equal(t, d1.Permissions, d2.Permissions)
assert.Equal(t, r1.SchemeManaged, d2.SchemeManaged)
// Try saving one with an invalid ID set.
r3 := &model.Role{
Id: model.NewId(),
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
res3 := <-ss.Role().Save(r3)
assert.NotNil(t, res3.Err)
// Try saving one with a duplicate "name" field.
r4 := &model.Role{
Name: r1.Name,
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
res4 := <-ss.Role().Save(r4)
assert.NotNil(t, res4.Err)
}
func testRoleStoreGet(t *testing.T, ss store.Store) {
// Save a role to test with.
r1 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
res1 := <-ss.Role().Save(r1)
assert.Nil(t, res1.Err)
d1 := res1.Data.(*model.Role)
assert.Len(t, d1.Id, 26)
// Get a valid role
res2 := <-ss.Role().Get(d1.Id)
assert.Nil(t, res2.Err)
d2 := res1.Data.(*model.Role)
assert.Equal(t, d1.Id, d2.Id)
assert.Equal(t, r1.Name, d2.Name)
assert.Equal(t, r1.DisplayName, d2.DisplayName)
assert.Equal(t, r1.Description, d2.Description)
assert.Equal(t, r1.Permissions, d2.Permissions)
assert.Equal(t, r1.SchemeManaged, d2.SchemeManaged)
// Get an invalid role
res3 := <-ss.Role().Get(model.NewId())
assert.NotNil(t, res3.Err)
}
func testRoleStoreGetByName(t *testing.T, ss store.Store) {
// Save a role to test with.
r1 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
res1 := <-ss.Role().Save(r1)
assert.Nil(t, res1.Err)
d1 := res1.Data.(*model.Role)
assert.Len(t, d1.Id, 26)
// Get a valid role
res2 := <-ss.Role().GetByName(d1.Name)
assert.Nil(t, res2.Err)
d2 := res1.Data.(*model.Role)
assert.Equal(t, d1.Id, d2.Id)
assert.Equal(t, r1.Name, d2.Name)
assert.Equal(t, r1.DisplayName, d2.DisplayName)
assert.Equal(t, r1.Description, d2.Description)
assert.Equal(t, r1.Permissions, d2.Permissions)
assert.Equal(t, r1.SchemeManaged, d2.SchemeManaged)
// Get an invalid role
res3 := <-ss.Role().GetByName(model.NewId())
assert.NotNil(t, res3.Err)
}
func testRoleStoreGetByNames(t *testing.T, ss store.Store) {
// Save some roles to test with.
r1 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
r2 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"read_channel",
"create_public_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
r3 := &model.Role{
Name: model.NewId(),
DisplayName: model.NewId(),
Description: model.NewId(),
Permissions: []string{
"invite_user",
"delete_private_channel",
"add_user_to_team",
},
SchemeManaged: false,
}
res1 := <-ss.Role().Save(r1)
assert.Nil(t, res1.Err)
d1 := res1.Data.(*model.Role)
assert.Len(t, d1.Id, 26)
res2 := <-ss.Role().Save(r2)
assert.Nil(t, res2.Err)
d2 := res2.Data.(*model.Role)
assert.Len(t, d2.Id, 26)
res3 := <-ss.Role().Save(r3)
assert.Nil(t, res3.Err)
d3 := res3.Data.(*model.Role)
assert.Len(t, d3.Id, 26)
// Get two valid roles.
n4 := []string{r1.Name, r2.Name}
res4 := <-ss.Role().GetByNames(n4)
assert.Nil(t, res4.Err)
roles4 := res4.Data.([]*model.Role)
assert.Len(t, roles4, 2)
assert.Contains(t, roles4, d1)
assert.Contains(t, roles4, d2)
assert.NotContains(t, roles4, d3)
// Get two invalid roles.
n5 := []string{model.NewId(), model.NewId()}
res5 := <-ss.Role().GetByNames(n5)
assert.Nil(t, res5.Err)
roles5 := res5.Data.([]*model.Role)
assert.Len(t, roles5, 0)
// Get one valid one and one invalid one.
n6 := []string{r1.Name, model.NewId()}
res6 := <-ss.Role().GetByNames(n6)
assert.Nil(t, res6.Err)
roles6 := res6.Data.([]*model.Role)
assert.Len(t, roles6, 1)
assert.Contains(t, roles6, d1)
assert.NotContains(t, roles6, d2)
assert.NotContains(t, roles6, d3)
}

Просмотреть файл

@@ -43,6 +43,7 @@ type Store struct {
UserAccessTokenStore mocks.UserAccessTokenStore
PluginStore mocks.PluginStore
ChannelMemberHistoryStore mocks.ChannelMemberHistoryStore
RoleStore mocks.RoleStore
}
func (s *Store) Team() store.TeamStore { return &s.TeamStore }
@@ -68,6 +69,7 @@ func (s *Store) Reaction() store.ReactionStore { return &s.React
func (s *Store) Job() store.JobStore { return &s.JobStore }
func (s *Store) UserAccessToken() store.UserAccessTokenStore { return &s.UserAccessTokenStore }
func (s *Store) Plugin() store.PluginStore { return &s.PluginStore }
func (s *Store) Role() store.RoleStore { return &s.RoleStore }
func (s *Store) ChannelMemberHistory() store.ChannelMemberHistoryStore {
return &s.ChannelMemberHistoryStore
}
@@ -104,5 +106,6 @@ func (s *Store) AssertExpectations(t mock.TestingT) bool {
&s.UserAccessTokenStore,
&s.ChannelMemberHistoryStore,
&s.PluginStore,
&s.RoleStore,
)
}

Просмотреть файл

@@ -7,14 +7,7 @@ import (
"github.com/mattermost/mattermost-server/model"
)
func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*model.Role {
roles := make(map[string]*model.Role)
for id, role := range model.DefaultRoles {
copy := &model.Role{}
*copy = *role
roles[id] = copy
}
func SetRolePermissionsFromConfig(roles map[string]*model.Role, cfg *model.Config, isLicensed bool) map[string]*model.Role {
if isLicensed {
switch *cfg.TeamSettings.RestrictPublicChannelCreation {
case model.PERMISSIONS_ALL:
@@ -222,8 +215,8 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
model.PERMISSION_ADD_USER_TO_TEAM.Id,
)
} else if *cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_ALL {
roles[model.SYSTEM_USER_ROLE_ID].Permissions = append(
roles[model.SYSTEM_USER_ROLE_ID].Permissions,
roles[model.TEAM_USER_ROLE_ID].Permissions = append(
roles[model.TEAM_USER_ROLE_ID].Permissions,
model.PERMISSION_INVITE_USER.Id,
model.PERMISSION_ADD_USER_TO_TEAM.Id,
)
@@ -243,11 +236,6 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
roles[model.CHANNEL_USER_ROLE_ID].Permissions,
model.PERMISSION_DELETE_POST.Id,
)
roles[model.CHANNEL_ADMIN_ROLE_ID].Permissions = append(
roles[model.CHANNEL_ADMIN_ROLE_ID].Permissions,
model.PERMISSION_DELETE_POST.Id,
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
)
roles[model.TEAM_ADMIN_ROLE_ID].Permissions = append(
roles[model.TEAM_ADMIN_ROLE_ID].Permissions,
model.PERMISSION_DELETE_POST.Id,
@@ -272,12 +260,35 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
)
}
if cfg.TeamSettings.EnableTeamCreation {
if *cfg.TeamSettings.EnableTeamCreation {
roles[model.SYSTEM_USER_ROLE_ID].Permissions = append(
roles[model.SYSTEM_USER_ROLE_ID].Permissions,
model.PERMISSION_CREATE_TEAM.Id,
)
}
if isLicensed {
switch *cfg.ServiceSettings.AllowEditPost {
case model.ALLOW_EDIT_POST_ALWAYS, model.ALLOW_EDIT_POST_TIME_LIMIT:
roles[model.CHANNEL_USER_ROLE_ID].Permissions = append(
roles[model.CHANNEL_USER_ROLE_ID].Permissions,
model.PERMISSION_EDIT_POST.Id,
)
roles[model.SYSTEM_ADMIN_ROLE_ID].Permissions = append(
roles[model.SYSTEM_ADMIN_ROLE_ID].Permissions,
model.PERMISSION_EDIT_POST.Id,
)
}
} else {
roles[model.CHANNEL_USER_ROLE_ID].Permissions = append(
roles[model.CHANNEL_USER_ROLE_ID].Permissions,
model.PERMISSION_EDIT_POST.Id,
)
roles[model.SYSTEM_ADMIN_ROLE_ID].Permissions = append(
roles[model.SYSTEM_ADMIN_ROLE_ID].Permissions,
model.PERMISSION_EDIT_POST.Id,
)
}
return roles
}

133
utils/authorization_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,133 @@
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
import (
"encoding/json"
"fmt"
"io/ioutil"
"reflect"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/model"
)
type RoleState struct {
RoleName string `json:"roleName"`
Permission string `json:"permission"`
ShouldHave bool `json:"shouldHave"`
}
func mockConfig() *model.Config {
config := model.Config{}
config.SetDefaults()
return &config
}
func mapping() (map[string]map[string][]RoleState, error) {
policiesRolesMapping := make(map[string]map[string][]RoleState)
raw, err := ioutil.ReadFile("./policies-roles-mapping.json")
if err != nil {
return policiesRolesMapping, err
}
var f map[string]interface{}
err = json.Unmarshal(raw, &f)
if err != nil {
return policiesRolesMapping, err
}
for policyName, value := range f {
capitalizedName := fmt.Sprintf("%v%v", strings.ToUpper(policyName[:1]), policyName[1:])
policiesRolesMapping[capitalizedName] = make(map[string][]RoleState)
for policyValue, roleStatesMappings := range value.(map[string]interface{}) {
var roleStates []RoleState
for _, roleStateMapping := range roleStatesMappings.([]interface{}) {
roleStateMappingJSON, _ := json.Marshal(roleStateMapping)
var roleState RoleState
_ = json.Unmarshal(roleStateMappingJSON, &roleState)
roleStates = append(roleStates, roleState)
}
policiesRolesMapping[capitalizedName][policyValue] = roleStates
}
}
return policiesRolesMapping, nil
}
func TestSetRolePermissionsFromConfig(t *testing.T) {
mapping, err := mapping()
if err != nil {
require.NoError(t, err)
}
for policyName, v := range mapping {
for policyValue, rolesMappings := range v {
config := mockConfig()
updateConfig(config, policyName, policyValue)
roles := model.MakeDefaultRoles()
SetRolePermissionsFromConfig(roles, config, true)
for _, roleMappingItem := range rolesMappings {
role := roles[roleMappingItem.RoleName]
permission := roleMappingItem.Permission
hasPermission := roleHasPermission(role, permission)
if (roleMappingItem.ShouldHave && !hasPermission) || (!roleMappingItem.ShouldHave && hasPermission) {
wording := "not to"
if roleMappingItem.ShouldHave {
wording = "to"
}
t.Errorf("Expected '%v' %v have '%v' permission when '%v' is set to '%v'.", role.Name, wording, permission, policyName, policyValue)
}
}
}
}
}
func updateConfig(config *model.Config, key string, value string) {
v := reflect.ValueOf(config.ServiceSettings)
field := v.FieldByName(key)
if !field.IsValid() {
v = reflect.ValueOf(config.TeamSettings)
field = v.FieldByName(key)
}
switch value {
case "true", "false":
b, _ := strconv.ParseBool(value)
field.Elem().SetBool(b)
default:
field.Elem().SetString(value)
}
}
func roleHasPermission(role *model.Role, permission string) bool {
for _, p := range role.Permissions {
if p == permission {
return true
}
}
return false
}

Просмотреть файл

@@ -337,8 +337,8 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["SiteURL"] = strings.TrimRight(*c.ServiceSettings.SiteURL, "/")
props["WebsocketURL"] = strings.TrimRight(*c.ServiceSettings.WebsocketURL, "/")
props["SiteName"] = c.TeamSettings.SiteName
props["EnableTeamCreation"] = strconv.FormatBool(*c.TeamSettings.EnableTeamCreation)
props["EnableAPIv3"] = strconv.FormatBool(*c.ServiceSettings.EnableAPIv3)
props["EnableTeamCreation"] = strconv.FormatBool(c.TeamSettings.EnableTeamCreation)
props["EnableUserCreation"] = strconv.FormatBool(c.TeamSettings.EnableUserCreation)
props["EnableOpenServer"] = strconv.FormatBool(*c.TeamSettings.EnableOpenServer)
props["RestrictDirectMessage"] = *c.TeamSettings.RestrictDirectMessage

532
utils/policies-roles-mapping.json Обычный файл
Просмотреть файл

@@ -0,0 +1,532 @@
{
"restrictTeamInvite": {
"all": [
{
"roleName": "team_user",
"permission": "invite_user",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "invite_user",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "invite_user",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "invite_user",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "invite_user",
"shouldHave": false
}
]
},
"restrictPublicChannelCreation": {
"all": [
{
"roleName": "team_user",
"permission": "create_public_channel",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "create_public_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "create_public_channel",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "create_public_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "create_public_channel",
"shouldHave": false
}
]
},
"restrictPrivateChannelCreation": {
"all": [
{
"roleName": "team_user",
"permission": "create_private_channel",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "create_private_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "create_private_channel",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "create_private_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "create_private_channel",
"shouldHave": false
}
]
},
"restrictPublicChannelManagement": {
"all": [
{
"roleName": "team_user",
"permission": "manage_public_channel_properties",
"shouldHave": true
}
],
"channel_admin": [
{
"roleName": "team_user",
"permission": "manage_public_channel_properties",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_public_channel_properties",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "manage_public_channel_properties",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "manage_public_channel_properties",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_public_channel_properties",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "manage_public_channel_properties",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "manage_public_channel_properties",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_public_channel_properties",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "manage_public_channel_properties",
"shouldHave": false
}
]
},
"restrictPublicChannelDeletion": {
"all": [
{
"roleName": "team_user",
"permission": "delete_public_channel",
"shouldHave": true
}
],
"channel_admin": [
{
"roleName": "team_user",
"permission": "delete_public_channel",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "delete_public_channel",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "delete_public_channel",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "delete_public_channel",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "delete_public_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_public_channel",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "delete_public_channel",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "delete_public_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_public_channel",
"shouldHave": false
}
]
},
"restrictPrivateChannelManagement": {
"all": [
{
"roleName": "team_user",
"permission": "manage_private_channel_properties",
"shouldHave": true
}
],
"channel_admin": [
{
"roleName": "team_user",
"permission": "manage_private_channel_properties",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_private_channel_properties",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "manage_private_channel_properties",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "manage_private_channel_properties",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_private_channel_properties",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "manage_private_channel_properties",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "manage_private_channel_properties",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_private_channel_properties",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "manage_private_channel_properties",
"shouldHave": false
}
]
},
"restrictPrivateChannelManageMembers": {
"all": [
{
"roleName": "channel_user",
"permission": "manage_private_channel_members",
"shouldHave": true
}
],
"channel_admin": [
{
"roleName": "channel_user",
"permission": "manage_private_channel_members",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_private_channel_members",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "manage_private_channel_members",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "channel_user",
"permission": "manage_private_channel_members",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_private_channel_members",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "manage_private_channel_members",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "channel_user",
"permission": "manage_private_channel_members",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "manage_private_channel_members",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "manage_private_channel_members",
"shouldHave": false
}
]
},
"restrictPrivateChannelDeletion": {
"all": [
{
"roleName": "team_user",
"permission": "delete_private_channel",
"shouldHave": true
}
],
"channel_admin": [
{
"roleName": "team_user",
"permission": "delete_private_channel",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "delete_private_channel",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "delete_private_channel",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "team_user",
"permission": "delete_private_channel",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "delete_private_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_private_channel",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "team_user",
"permission": "delete_private_channel",
"shouldHave": false
},
{
"roleName": "channel_admin",
"permission": "delete_private_channel",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_private_channel",
"shouldHave": false
}
]
},
"allowEditPost": {
"always": [
{
"roleName": "channel_user",
"permission": "edit_post",
"shouldHave": true
},
{
"roleName": "system_admin",
"permission": "edit_post",
"shouldHave": true
}
],
"never": [
{
"roleName": "channel_user",
"permission": "edit_post",
"shouldHave": false
},
{
"roleName": "system_admin",
"permission": "edit_post",
"shouldHave": false
}
]
},
"restrictPostDelete": {
"all": [
{
"roleName": "channel_user",
"permission": "delete_post",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "delete_post",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "delete_others_posts",
"shouldHave": true
}
],
"team_admin": [
{
"roleName": "channel_user",
"permission": "delete_post",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_post",
"shouldHave": true
},
{
"roleName": "team_admin",
"permission": "delete_others_posts",
"shouldHave": true
}
],
"system_admin": [
{
"roleName": "channel_user",
"permission": "delete_post",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_post",
"shouldHave": false
},
{
"roleName": "team_admin",
"permission": "delete_others_posts",
"shouldHave": false
}
]
},
"enableTeamCreation": {
"true": [
{
"roleName": "system_user",
"permission": "create_team",
"shouldHave": true
}
],
"false": [
{
"roleName": "system_user",
"permission": "create_team",
"shouldHave": false
}
]
},
"enableOnlyAdminIntegrations": {
"true": [
{
"roleName": "team_user",
"permission": "manage_webhooks",
"shouldHave": false
},
{
"roleName": "team_user",
"permission": "manage_slash_commands",
"shouldHave": false
},
{
"roleName": "system_user",
"permission": "manage_oauth",
"shouldHave": false
}
],
"false": [
{
"roleName": "team_user",
"permission": "manage_webhooks",
"shouldHave": true
},
{
"roleName": "team_user",
"permission": "manage_slash_commands",
"shouldHave": true
},
{
"roleName": "system_user",
"permission": "manage_oauth",
"shouldHave": true
}
]
}
}

Просмотреть файл

@@ -55,6 +55,8 @@ func Setup() *app.App {
URL = fmt.Sprintf("http://localhost:%v", a.Srv.ListenAddr.Port)
ApiClient = model.NewClient(URL)
a.DoAdvancedPermissionsMigration()
a.Srv.Store.MarkSystemRanUnitTests()
a.UpdateConfig(func(cfg *model.Config) {