From 1f34e8ba2e6aaec06d850c19377bb2277fdee5e0 Mon Sep 17 00:00:00 2001 From: Martin Kraft Date: Wed, 13 Jul 2022 03:38:07 -0400 Subject: [PATCH] MM-44351: Creates new Custom Group Admin system role. (#20573) * MM-44351: Creates new Custom Group Admin system role. * MM-44351: Adds missing test mock. * MM-44351: Adds missing mocks. --- app/migrations.go | 32 +++++++++++++++++++ model/role.go | 37 +++++++++++++++------ services/telemetry/telemetry.go | 48 ++++++++++++++++++---------- services/telemetry/telemetry_test.go | 2 ++ testlib/store.go | 1 + 5 files changed, 94 insertions(+), 26 deletions(-) diff --git a/app/migrations.go b/app/migrations.go index 69d81e847b..aba545c443 100644 --- a/app/migrations.go +++ b/app/migrations.go @@ -15,6 +15,7 @@ import ( const EmojisPermissionsMigrationKey = "EmojisPermissionsMigrationComplete" const GuestRolesCreationMigrationKey = "GuestRolesCreationMigrationComplete" const SystemConsoleRolesCreationMigrationKey = "SystemConsoleRolesCreationMigrationComplete" +const CustomGroupAdminRoleCreationMigrationKey = "CustomGroupAdminRoleCreationMigrationComplete" const ContentExtractionConfigDefaultTrueMigrationKey = "ContentExtractionConfigDefaultTrueMigrationComplete" const PlaybookRolesCreationMigrationKey = "PlaybookRolesCreationMigrationComplete" const FirstAdminSetupCompleteKey = model.SystemFirstAdminSetupComplete @@ -290,6 +291,36 @@ func (s *Server) doSystemConsoleRolesCreationMigration() { } } +func (s *Server) doCustomGroupAdminRoleCreationMigration() { + // If the migration is already marked as completed, don't do it again. + if _, err := s.Store.System().GetByName(CustomGroupAdminRoleCreationMigrationKey); err == nil { + return + } + + roles := model.MakeDefaultRoles() + + allSucceeded := true + if _, err := s.Store.Role().GetByName(context.Background(), model.SystemCustomGroupAdminRoleId); err != nil { + if _, err := s.Store.Role().Save(roles[model.SystemCustomGroupAdminRoleId]); err != nil { + mlog.Critical("Failed to create new role.", mlog.Err(err), mlog.String("role", model.SystemCustomGroupAdminRoleId)) + allSucceeded = false + } + } + + if !allSucceeded { + return + } + + system := model.System{ + Name: CustomGroupAdminRoleCreationMigrationKey, + Value: "true", + } + + if err := s.Store.System().Save(&system); err != nil { + mlog.Critical("Failed to mark custom group admin role creation migration as completed.", mlog.Err(err)) + } +} + func (s *Server) doContentExtractionConfigDefaultTrueMigration() { // If the migration is already marked as completed, don't do it again. if _, err := s.Store.System().GetByName(ContentExtractionConfigDefaultTrueMigrationKey); err == nil { @@ -516,6 +547,7 @@ func (s *Server) doAppMigrations() { s.doEmojisPermissionsMigration() s.doGuestRolesCreationMigration() s.doSystemConsoleRolesCreationMigration() + s.doCustomGroupAdminRoleCreationMigration() // This migration always must be the last, because can be based on previous // migrations. For example, it needs the guest roles migration. err := s.doPermissionsMigrations() diff --git a/model/role.go b/model/role.go index 081e7b68b8..82d07fb075 100644 --- a/model/role.go +++ b/model/role.go @@ -13,6 +13,7 @@ var SysconsoleAncillaryPermissions map[string][]*Permission var SystemManagerDefaultPermissions []string var SystemUserManagerDefaultPermissions []string var SystemReadOnlyAdminDefaultPermissions []string +var SystemCustomGroupAdminDefaultPermissions []string var BuiltInSchemeManagedRoleIDs []string @@ -340,25 +341,34 @@ func init() { PermissionSysconsoleWriteIntegrationsCors.Id, } + SystemCustomGroupAdminDefaultPermissions = []string{ + PermissionCreateCustomGroup.Id, + PermissionEditCustomGroup.Id, + PermissionDeleteCustomGroup.Id, + PermissionManageCustomGroupMembers.Id, + } + // Add the ancillary permissions to each system role SystemUserManagerDefaultPermissions = AddAncillaryPermissions(SystemUserManagerDefaultPermissions) SystemReadOnlyAdminDefaultPermissions = AddAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions) SystemManagerDefaultPermissions = AddAncillaryPermissions(SystemManagerDefaultPermissions) + SystemCustomGroupAdminDefaultPermissions = AddAncillaryPermissions(SystemCustomGroupAdminDefaultPermissions) } type RoleType string type RoleScope string const ( - SystemGuestRoleId = "system_guest" - SystemUserRoleId = "system_user" - SystemAdminRoleId = "system_admin" - SystemPostAllRoleId = "system_post_all" - SystemPostAllPublicRoleId = "system_post_all_public" - SystemUserAccessTokenRoleId = "system_user_access_token" - SystemUserManagerRoleId = "system_user_manager" - SystemReadOnlyAdminRoleId = "system_read_only_admin" - SystemManagerRoleId = "system_manager" + SystemGuestRoleId = "system_guest" + SystemUserRoleId = "system_user" + SystemAdminRoleId = "system_admin" + SystemPostAllRoleId = "system_post_all" + SystemPostAllPublicRoleId = "system_post_all_public" + SystemUserAccessTokenRoleId = "system_user_access_token" + SystemUserManagerRoleId = "system_user_manager" + SystemReadOnlyAdminRoleId = "system_read_only_admin" + SystemManagerRoleId = "system_manager" + SystemCustomGroupAdminRoleId = "system_custom_group_admin" TeamGuestRoleId = "team_guest" TeamUserRoleId = "team_user" @@ -983,6 +993,15 @@ func MakeDefaultRoles() map[string]*Role { BuiltIn: true, } + roles[SystemCustomGroupAdminRoleId] = &Role{ + Name: "system_custom_group_admin", + DisplayName: "authentication.roles.system_custom_group_admin.name", + Description: "authentication.roles.system_custom_group_admin.description", + Permissions: SystemCustomGroupAdminDefaultPermissions, + SchemeManaged: false, + BuiltIn: true, + } + allPermissionIDs := []string{} for _, permission := range AllPermissions { allPermissionIDs = append(allPermissionIDs, permission.Id) diff --git a/services/telemetry/telemetry.go b/services/telemetry/telemetry.go index d499394c59..f979cf938f 100644 --- a/services/telemetry/telemetry.go +++ b/services/telemetry/telemetry.go @@ -1038,24 +1038,38 @@ func (ts *TelemetryService) trackPermissions() { systemReadOnlyAdminCount = 0 } + systemCustomGroupAdminPermissions := "" + systemCustomGroupAdminPermissionsModified := false + if role, err := ts.srv.GetRoleByName(context.Background(), model.SystemCustomGroupAdminRoleId); err == nil { + systemCustomGroupAdminPermissionsModified = len(model.PermissionsChangedByPatch(role, &model.RolePatch{Permissions: &model.SystemReadOnlyAdminDefaultPermissions})) > 0 + systemCustomGroupAdminPermissions = strings.Join(role.Permissions, " ") + } + systemCustomGroupAdminCount, countErr := ts.dbStore.User().Count(model.UserCountOptions{Roles: []string{model.SystemCustomGroupAdminRoleId}}) + if countErr != nil { + systemCustomGroupAdminCount = 0 + } + ts.SendTelemetry(TrackPermissionsSystemScheme, map[string]any{ - "system_admin_permissions": systemAdminPermissions, - "system_user_permissions": systemUserPermissions, - "system_manager_permissions": systemManagerPermissions, - "system_user_manager_permissions": systemUserManagerPermissions, - "system_read_only_admin_permissions": systemReadOnlyAdminPermissions, - "team_admin_permissions": teamAdminPermissions, - "team_user_permissions": teamUserPermissions, - "team_guest_permissions": teamGuestPermissions, - "channel_admin_permissions": channelAdminPermissions, - "channel_user_permissions": channelUserPermissions, - "channel_guest_permissions": channelGuestPermissions, - "system_manager_permissions_modified": systemManagerPermissionsModified, - "system_manager_count": systemManagerCount, - "system_user_manager_permissions_modified": systemUserManagerPermissionsModified, - "system_user_manager_count": systemUserManagerCount, - "system_read_only_admin_permissions_modified": systemReadOnlyAdminPermissionsModified, - "system_read_only_admin_count": systemReadOnlyAdminCount, + "system_admin_permissions": systemAdminPermissions, + "system_user_permissions": systemUserPermissions, + "system_manager_permissions": systemManagerPermissions, + "system_user_manager_permissions": systemUserManagerPermissions, + "system_read_only_admin_permissions": systemReadOnlyAdminPermissions, + "team_admin_permissions": teamAdminPermissions, + "team_user_permissions": teamUserPermissions, + "team_guest_permissions": teamGuestPermissions, + "channel_admin_permissions": channelAdminPermissions, + "channel_user_permissions": channelUserPermissions, + "channel_guest_permissions": channelGuestPermissions, + "system_manager_permissions_modified": systemManagerPermissionsModified, + "system_manager_count": systemManagerCount, + "system_user_manager_permissions_modified": systemUserManagerPermissionsModified, + "system_user_manager_count": systemUserManagerCount, + "system_read_only_admin_permissions_modified": systemReadOnlyAdminPermissionsModified, + "system_read_only_admin_count": systemReadOnlyAdminCount, + "system_custom_group_admin_permissions": systemCustomGroupAdminPermissions, + "system_custom_group_admin_permissions_modified": systemCustomGroupAdminPermissionsModified, + "system_custom_group_admin_count": systemCustomGroupAdminCount, }) if schemes, err := ts.srv.GetSchemes(model.SchemeScopeTeam, 0, 100); err == nil { diff --git a/services/telemetry/telemetry_test.go b/services/telemetry/telemetry_test.go index 2367b8d20a..cd5d0626aa 100644 --- a/services/telemetry/telemetry_test.go +++ b/services/telemetry/telemetry_test.go @@ -179,6 +179,7 @@ func initializeMocks(cfg *model.Config, cloudLicense bool) (*mocks.ServerIface, serverIfaceMock.On("GetRoleByName", context.Background(), "system_user_manager").Return(&model.Role{Permissions: []string{"sum-test1", "sum-test2"}}, nil) serverIfaceMock.On("GetRoleByName", context.Background(), "system_manager").Return(&model.Role{Permissions: []string{"sm-test1", "sm-test2"}}, nil) serverIfaceMock.On("GetRoleByName", context.Background(), "system_read_only_admin").Return(&model.Role{Permissions: []string{"sra-test1", "sra-test2"}}, nil) + serverIfaceMock.On("GetRoleByName", context.Background(), "system_custom_group_admin").Return(&model.Role{Permissions: []string{"scga-test1", "scga-test2"}}, nil) serverIfaceMock.On("GetRoleByName", context.Background(), "team_admin").Return(&model.Role{Permissions: []string{"ta-test1", "ta-test2"}}, nil) serverIfaceMock.On("GetRoleByName", context.Background(), "team_user").Return(&model.Role{Permissions: []string{"tu-test1", "tu-test2"}}, nil) serverIfaceMock.On("GetRoleByName", context.Background(), "team_guest").Return(&model.Role{Permissions: []string{"tg-test1", "tg-test2"}}, nil) @@ -204,6 +205,7 @@ func initializeMocks(cfg *model.Config, cloudLicense bool) (*mocks.ServerIface, userStore.On("Count", model.UserCountOptions{Roles: []string{model.SystemManagerRoleId}}).Return(int64(5), nil) userStore.On("Count", model.UserCountOptions{Roles: []string{model.SystemUserManagerRoleId}}).Return(int64(10), nil) userStore.On("Count", model.UserCountOptions{Roles: []string{model.SystemReadOnlyAdminRoleId}}).Return(int64(15), nil) + userStore.On("Count", model.UserCountOptions{Roles: []string{model.SystemCustomGroupAdminRoleId}}).Return(int64(15), nil) userStore.On("AnalyticsGetGuestCount").Return(int64(11), nil) userStore.On("AnalyticsActiveCount", mock.Anything, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false, ExcludeRegularUsers: false, TeamId: "", ViewRestrictions: nil}).Return(int64(5), nil) userStore.On("AnalyticsGetInactiveUsersCount").Return(int64(8), nil) diff --git a/testlib/store.go b/testlib/store.go index dcb20e39a3..5566989362 100644 --- a/testlib/store.go +++ b/testlib/store.go @@ -68,6 +68,7 @@ func GetMockStoreForSetupFunctions() *mocks.Store { systemStore.On("GetByName", model.MigrationKeyAddPlaybooksPermissions).Return(&model.System{Name: model.MigrationKeyAddPlaybooksPermissions, Value: "true"}, nil) systemStore.On("GetByName", model.MigrationKeyAddCustomUserGroupsPermissions).Return(&model.System{Name: model.MigrationKeyAddCustomUserGroupsPermissions, Value: "true"}, nil) systemStore.On("GetByName", model.MigrationKeyAddPlayboosksManageRolesPermissions).Return(&model.System{Name: model.MigrationKeyAddPlayboosksManageRolesPermissions, Value: "true"}, nil) + systemStore.On("GetByName", "CustomGroupAdminRoleCreationMigrationComplete").Return(&model.System{Name: model.MigrationKeyAddPlayboosksManageRolesPermissions, Value: "true"}, nil) systemStore.On("InsertIfExists", mock.AnythingOfType("*model.System")).Return(&model.System{}, nil).Once() systemStore.On("Save", mock.AnythingOfType("*model.System")).Return(nil)