From 6a58834f34050a3c1fe71923150156b144c41101 Mon Sep 17 00:00:00 2001 From: Farhan Munshi <3207297+fmunshi@users.noreply.github.com> Date: Tue, 15 Sep 2020 14:21:32 -0400 Subject: [PATCH] [MM-28475] Add server telemetry for the new system roles (#15437) * MM-28475 Add server telemetry for the new system roles * Move system roles to permissions_system_scheme table * Add testing mocks --- model/role.go | 144 +++++++++++++++------------ services/telemetry/telemetry.go | 59 +++++++++-- services/telemetry/telemetry_test.go | 6 ++ 3 files changed, 136 insertions(+), 73 deletions(-) diff --git a/model/role.go b/model/role.go index 5a8e923f45..c4b40d7dd7 100644 --- a/model/role.go +++ b/model/role.go @@ -11,6 +11,9 @@ import ( // SysconsoleAncillaryPermissions maps the non-sysconsole permissions required by each sysconsole view. var SysconsoleAncillaryPermissions map[string][]*Permission +var SystemManagerDefaultPermissions []string +var SystemUserManagerDefaultPermissions []string +var SystemReadOnlyAdminDefaultPermissions []string var BuiltInSchemeManagedRoleIDs []string @@ -97,6 +100,59 @@ func init() { PERMISSION_EDIT_BRAND, }, } + + SystemUserManagerDefaultPermissions = []string{ + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, + } + + SystemReadOnlyAdminDefaultPermissions = []string{ + PERMISSION_SYSCONSOLE_READ_ABOUT.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, + PERMISSION_SYSCONSOLE_READ_SITE.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, + PERMISSION_SYSCONSOLE_READ_PLUGINS.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id, + } + + SystemManagerDefaultPermissions = []string{ + PERMISSION_SYSCONSOLE_READ_ABOUT.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, + PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id, + PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id, + PERMISSION_SYSCONSOLE_READ_SITE.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, + PERMISSION_SYSCONSOLE_READ_PLUGINS.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id, + } + + // Add the ancillary permissions to each system role + SystemUserManagerDefaultPermissions = addAncillaryPermissions(SystemUserManagerDefaultPermissions) + SystemReadOnlyAdminDefaultPermissions = addAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions) + SystemManagerDefaultPermissions = addAncillaryPermissions(SystemManagerDefaultPermissions) } type RoleType string @@ -652,85 +708,32 @@ func MakeDefaultRoles() map[string]*Role { } roles[SYSTEM_USER_MANAGER_ROLE_ID] = &Role{ - Name: "system_user_manager", - DisplayName: "authentication.roles.system_user_manager.name", - Description: "authentication.roles.system_user_manager.description", - Permissions: []string{ - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id, - PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, - }, + Name: "system_user_manager", + DisplayName: "authentication.roles.system_user_manager.name", + Description: "authentication.roles.system_user_manager.description", + Permissions: SystemUserManagerDefaultPermissions, SchemeManaged: false, BuiltIn: true, } roles[SYSTEM_READ_ONLY_ADMIN_ROLE_ID] = &Role{ - Name: "system_read_only_admin", - DisplayName: "authentication.roles.system_read_only_admin.name", - Description: "authentication.roles.system_read_only_admin.description", - Permissions: []string{ - PERMISSION_SYSCONSOLE_READ_ABOUT.Id, - PERMISSION_SYSCONSOLE_READ_REPORTING.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id, - PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, - PERMISSION_SYSCONSOLE_READ_SITE.Id, - PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, - PERMISSION_SYSCONSOLE_READ_PLUGINS.Id, - PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, - PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id, - }, + Name: "system_read_only_admin", + DisplayName: "authentication.roles.system_read_only_admin.name", + Description: "authentication.roles.system_read_only_admin.description", + Permissions: SystemReadOnlyAdminDefaultPermissions, SchemeManaged: false, BuiltIn: true, } roles[SYSTEM_MANAGER_ROLE_ID] = &Role{ - Name: "system_manager", - DisplayName: "authentication.roles.system_manager.name", - Description: "authentication.roles.system_manager.description", - Permissions: []string{ - PERMISSION_SYSCONSOLE_READ_ABOUT.Id, - PERMISSION_SYSCONSOLE_READ_REPORTING.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, - PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id, - PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS.Id, - PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, - PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id, - PERMISSION_SYSCONSOLE_READ_SITE.Id, - PERMISSION_SYSCONSOLE_WRITE_SITE.Id, - PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, - PERMISSION_SYSCONSOLE_READ_PLUGINS.Id, - PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, - PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id, - }, + Name: "system_manager", + DisplayName: "authentication.roles.system_manager.name", + Description: "authentication.roles.system_manager.description", + Permissions: SystemManagerDefaultPermissions, SchemeManaged: false, BuiltIn: true, } - // Add the ancillary permissions to each new system role - for _, role := range []*Role{roles[SYSTEM_USER_MANAGER_ROLE_ID], roles[SYSTEM_READ_ONLY_ADMIN_ROLE_ID], roles[SYSTEM_MANAGER_ROLE_ID]} { - for _, rolePermission := range role.Permissions { - if ancillaryPermissions, ok := SysconsoleAncillaryPermissions[rolePermission]; ok { - for _, ancillaryPermission := range ancillaryPermissions { - role.Permissions = append(role.Permissions, ancillaryPermission.Id) - } - } - } - } - allPermissionIDs := []string{} for _, permission := range AllPermissions { allPermissionIDs = append(allPermissionIDs, permission.Id) @@ -750,3 +753,14 @@ func MakeDefaultRoles() map[string]*Role { return roles } + +func addAncillaryPermissions(permissions []string) []string { + for _, permission := range permissions { + if ancillaryPermissions, ok := SysconsoleAncillaryPermissions[permission]; ok { + for _, ancillaryPermission := range ancillaryPermissions { + permissions = append(permissions, ancillaryPermission.Id) + } + } + } + return permissions +} diff --git a/services/telemetry/telemetry.go b/services/telemetry/telemetry.go index a92e88f9ce..9487203e8b 100644 --- a/services/telemetry/telemetry.go +++ b/services/telemetry/telemetry.go @@ -67,6 +67,7 @@ const ( TRACK_PERMISSIONS_GENERAL = "permissions_general" TRACK_PERMISSIONS_SYSTEM_SCHEME = "permissions_system_scheme" TRACK_PERMISSIONS_TEAM_SCHEMES = "permissions_team_schemes" + TRACK_PERMISSIONS_SYSTEM_ROLES = "permissions_system_roles" TRACK_ELASTICSEARCH = "elasticsearch" TRACK_GROUPS = "groups" TRACK_CHANNEL_MODERATION = "channel_moderation" @@ -925,15 +926,57 @@ func (ts *TelemetryService) trackPermissions() { channelGuestPermissions = strings.Join(role.Permissions, " ") } + systemManagerPermissions := "" + systemManagerPermissionsModified := false + if role, err := ts.srv.GetRoleByName(model.SYSTEM_MANAGER_ROLE_ID); err == nil { + systemManagerPermissionsModified = len(model.PermissionsChangedByPatch(role, &model.RolePatch{Permissions: &model.SystemManagerDefaultPermissions})) > 0 + systemManagerPermissions = strings.Join(role.Permissions, " ") + } + systemManagerCount, countErr := ts.dbStore.User().Count(model.UserCountOptions{Roles: []string{model.SYSTEM_MANAGER_ROLE_ID}}) + if countErr != nil { + systemManagerCount = 0 + } + + systemUserManagerPermissions := "" + systemUserManagerPermissionsModified := false + if role, err := ts.srv.GetRoleByName(model.SYSTEM_USER_MANAGER_ROLE_ID); err == nil { + systemUserManagerPermissionsModified = len(model.PermissionsChangedByPatch(role, &model.RolePatch{Permissions: &model.SystemUserManagerDefaultPermissions})) > 0 + systemUserManagerPermissions = strings.Join(role.Permissions, " ") + } + systemUserManagerCount, countErr := ts.dbStore.User().Count(model.UserCountOptions{Roles: []string{model.SYSTEM_USER_MANAGER_ROLE_ID}}) + if countErr != nil { + systemManagerCount = 0 + } + + systemReadOnlyAdminPermissions := "" + systemReadOnlyAdminPermissionsModified := false + if role, err := ts.srv.GetRoleByName(model.SYSTEM_READ_ONLY_ADMIN_ROLE_ID); err == nil { + systemReadOnlyAdminPermissionsModified = len(model.PermissionsChangedByPatch(role, &model.RolePatch{Permissions: &model.SystemReadOnlyAdminDefaultPermissions})) > 0 + systemReadOnlyAdminPermissions = strings.Join(role.Permissions, " ") + } + systemReadOnlyAdminCount, countErr := ts.dbStore.User().Count(model.UserCountOptions{Roles: []string{model.SYSTEM_READ_ONLY_ADMIN_ROLE_ID}}) + if countErr != nil { + systemReadOnlyAdminCount = 0 + } + ts.sendTelemetry(TRACK_PERMISSIONS_SYSTEM_SCHEME, map[string]interface{}{ - "system_admin_permissions": systemAdminPermissions, - "system_user_permissions": systemUserPermissions, - "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_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, }) if schemes, err := ts.srv.GetSchemes(model.SCHEME_SCOPE_TEAM, 0, 100); err == nil { diff --git a/services/telemetry/telemetry_test.go b/services/telemetry/telemetry_test.go index a3a9655b12..136d4f226c 100644 --- a/services/telemetry/telemetry_test.go +++ b/services/telemetry/telemetry_test.go @@ -56,6 +56,9 @@ func initializeMocks(cfg *model.Config) (*mocks.ServerIface, *storeMocks.Store, serverIfaceMock.On("License").Return(model.NewTestLicense(), nil) serverIfaceMock.On("GetRoleByName", "system_admin").Return(&model.Role{Permissions: []string{"sa-test1", "sa-test2"}}, nil) serverIfaceMock.On("GetRoleByName", "system_user").Return(&model.Role{Permissions: []string{"su-test1", "su-test2"}}, nil) + serverIfaceMock.On("GetRoleByName", "system_user_manager").Return(&model.Role{Permissions: []string{"sum-test1", "sum-test2"}}, nil) + serverIfaceMock.On("GetRoleByName", "system_manager").Return(&model.Role{Permissions: []string{"sm-test1", "sm-test2"}}, nil) + serverIfaceMock.On("GetRoleByName", "system_read_only_admin").Return(&model.Role{Permissions: []string{"sra-test1", "sra-test2"}}, nil) serverIfaceMock.On("GetRoleByName", "team_admin").Return(&model.Role{Permissions: []string{"ta-test1", "ta-test2"}}, nil) serverIfaceMock.On("GetRoleByName", "team_user").Return(&model.Role{Permissions: []string{"tu-test1", "tu-test2"}}, nil) serverIfaceMock.On("GetRoleByName", "team_guest").Return(&model.Role{Permissions: []string{"tg-test1", "tg-test2"}}, nil) @@ -78,6 +81,9 @@ func initializeMocks(cfg *model.Config) (*mocks.ServerIface, *storeMocks.Store, userStore := storeMocks.UserStore{} userStore.On("Count", model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: true, ExcludeRegularUsers: false, TeamId: "", ViewRestrictions: nil}).Return(int64(10), nil) userStore.On("Count", model.UserCountOptions{IncludeBotAccounts: true, IncludeDeleted: false, ExcludeRegularUsers: true, TeamId: "", ViewRestrictions: nil}).Return(int64(100), nil) + userStore.On("Count", model.UserCountOptions{Roles: []string{model.SYSTEM_MANAGER_ROLE_ID}}).Return(int64(5), nil) + userStore.On("Count", model.UserCountOptions{Roles: []string{model.SYSTEM_USER_MANAGER_ROLE_ID}}).Return(int64(10), nil) + userStore.On("Count", model.UserCountOptions{Roles: []string{model.SYSTEM_READ_ONLY_ADMIN_ROLE_ID}}).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)