XYZ-37: Advanced Permissions Phase 1 Backend. (#8159)

* XYZ-13: Update Permission and Role structs to new design.

* XYZ-10: Role store.

* XYZ-9/XYZ-44: Roles API endpoints and WebSocket message.

* XYZ-8: Switch server permissions checks to store backed roles.

* XYZ-58: Proper validation of roles where required.

* XYZ-11/XYZ-55: Migration to store backed roles from policy config.

* XYZ-37: Update unit tests to work with database roles.

* XYZ-56: Remove the "guest" role.

* Changes to SetDefaultRolesFromConfig.

* Short-circuit the store if nothing has changed.

* Address first round of review comments.

* Address second round of review comments.
Этот коммит содержится в:
George Goldberg
2018-02-06 15:34:08 +00:00
коммит произвёл GitHub
родитель 1c7f25773a
Коммит e1cd646135
59 изменённых файлов: 2960 добавлений и 1712 удалений

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

@@ -25,8 +25,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}
@@ -92,8 +100,8 @@ func TestCreateIncomingHook(t *testing.T) {
t.Fatal(err)
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
// 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)
@@ -132,8 +140,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -216,8 +228,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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}
@@ -239,8 +252,8 @@ func TestUpdateIncomingHook(t *testing.T) {
})
})
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
Client.Logout()
th.UpdateUserToTeamAdmin(user2, team)
@@ -323,8 +336,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -350,8 +370,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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)
@@ -375,8 +395,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -409,8 +436,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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")
@@ -446,8 +473,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 })
th.App.SetDefaultRolesBasedOnConfig()
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"}}
@@ -517,8 +551,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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)
@@ -550,8 +584,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -577,8 +618,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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)
@@ -608,8 +649,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -682,16 +730,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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 })
th.App.SetDefaultRolesBasedOnConfig()
// Revoke permission from regular users.
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
Client.Logout()
th.LinkUserToTeam(user3, team)
@@ -778,8 +827,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -812,8 +868,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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")
@@ -847,8 +903,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 })
th.App.SetDefaultRolesBasedOnConfig()
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)
@@ -882,8 +945,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 })
th.App.SetDefaultRolesBasedOnConfig()
// 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)
@@ -969,10 +1032,8 @@ func TestIncomingWebhooks(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = disableTownSquareReadOnly })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })
th.App.SetDefaultRolesBasedOnConfig()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()