diff options
author | George Goldberg <george@gberg.me> | 2018-08-23 11:48:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-23 11:48:57 +0100 |
commit | 8bbee74ed811e7aa8167ad7cea6d05042a90f446 (patch) | |
tree | 44fda1e000262a78b92a1fa57c1655eced59c2a1 | |
parent | dc4d009c78fdbeaf58d61a92eba58cac86ed6ffa (diff) | |
download | chat-8bbee74ed811e7aa8167ad7cea6d05042a90f446.tar.gz chat-8bbee74ed811e7aa8167ad7cea6d05042a90f446.tar.bz2 chat-8bbee74ed811e7aa8167ad7cea6d05042a90f446.zip |
MM-11348: Add telemetry for advanced permissions. (#9249)
-rw-r--r-- | app/diagnostics.go | 164 | ||||
-rw-r--r-- | i18n/en.json | 4 | ||||
-rw-r--r-- | store/sqlstore/team_store.go | 11 | ||||
-rw-r--r-- | store/store.go | 1 | ||||
-rw-r--r-- | store/storetest/mocks/TeamStore.go | 16 | ||||
-rw-r--r-- | store/storetest/team_store.go | 62 |
6 files changed, 226 insertions, 32 deletions
diff --git a/app/diagnostics.go b/app/diagnostics.go index 91341c310..6726b8140 100644 --- a/app/diagnostics.go +++ b/app/diagnostics.go @@ -6,46 +6,51 @@ package app import ( "path/filepath" "runtime" + "strings" + + "github.com/segmentio/analytics-go" "github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/model" - "github.com/segmentio/analytics-go" ) const ( SEGMENT_KEY = "fwb7VPbFeQ7SKp3wHm1RzFUuXZudqVok" - TRACK_CONFIG_SERVICE = "config_service" - TRACK_CONFIG_TEAM = "config_team" - TRACK_CONFIG_CLIENT_REQ = "config_client_requirements" - TRACK_CONFIG_SQL = "config_sql" - TRACK_CONFIG_LOG = "config_log" - TRACK_CONFIG_FILE = "config_file" - TRACK_CONFIG_RATE = "config_rate" - TRACK_CONFIG_EXTENSION = "config_extension" - TRACK_CONFIG_EMAIL = "config_email" - TRACK_CONFIG_PRIVACY = "config_privacy" - TRACK_CONFIG_THEME = "config_theme" - TRACK_CONFIG_OAUTH = "config_oauth" - TRACK_CONFIG_LDAP = "config_ldap" - TRACK_CONFIG_COMPLIANCE = "config_compliance" - TRACK_CONFIG_LOCALIZATION = "config_localization" - TRACK_CONFIG_SAML = "config_saml" - TRACK_CONFIG_PASSWORD = "config_password" - TRACK_CONFIG_CLUSTER = "config_cluster" - TRACK_CONFIG_METRICS = "config_metrics" - TRACK_CONFIG_WEBRTC = "config_webrtc" - TRACK_CONFIG_SUPPORT = "config_support" - TRACK_CONFIG_NATIVEAPP = "config_nativeapp" - TRACK_CONFIG_EXPERIMENTAL = "config_experimental" - TRACK_CONFIG_ANALYTICS = "config_analytics" - TRACK_CONFIG_ANNOUNCEMENT = "config_announcement" - TRACK_CONFIG_ELASTICSEARCH = "config_elasticsearch" - TRACK_CONFIG_PLUGIN = "config_plugin" - TRACK_CONFIG_DATA_RETENTION = "config_data_retention" - TRACK_CONFIG_MESSAGE_EXPORT = "config_message_export" - TRACK_CONFIG_DISPLAY = "config_display" - TRACK_CONFIG_TIMEZONE = "config_timezone" + TRACK_CONFIG_SERVICE = "config_service" + TRACK_CONFIG_TEAM = "config_team" + TRACK_CONFIG_CLIENT_REQ = "config_client_requirements" + TRACK_CONFIG_SQL = "config_sql" + TRACK_CONFIG_LOG = "config_log" + TRACK_CONFIG_FILE = "config_file" + TRACK_CONFIG_RATE = "config_rate" + TRACK_CONFIG_EXTENSION = "config_extension" + TRACK_CONFIG_EMAIL = "config_email" + TRACK_CONFIG_PRIVACY = "config_privacy" + TRACK_CONFIG_THEME = "config_theme" + TRACK_CONFIG_OAUTH = "config_oauth" + TRACK_CONFIG_LDAP = "config_ldap" + TRACK_CONFIG_COMPLIANCE = "config_compliance" + TRACK_CONFIG_LOCALIZATION = "config_localization" + TRACK_CONFIG_SAML = "config_saml" + TRACK_CONFIG_PASSWORD = "config_password" + TRACK_CONFIG_CLUSTER = "config_cluster" + TRACK_CONFIG_METRICS = "config_metrics" + TRACK_CONFIG_WEBRTC = "config_webrtc" + TRACK_CONFIG_SUPPORT = "config_support" + TRACK_CONFIG_NATIVEAPP = "config_nativeapp" + TRACK_CONFIG_EXPERIMENTAL = "config_experimental" + TRACK_CONFIG_ANALYTICS = "config_analytics" + TRACK_CONFIG_ANNOUNCEMENT = "config_announcement" + TRACK_CONFIG_ELASTICSEARCH = "config_elasticsearch" + TRACK_CONFIG_PLUGIN = "config_plugin" + TRACK_CONFIG_DATA_RETENTION = "config_data_retention" + TRACK_CONFIG_MESSAGE_EXPORT = "config_message_export" + TRACK_CONFIG_DISPLAY = "config_display" + TRACK_CONFIG_TIMEZONE = "config_timezone" + TRACK_PERMISSIONS_GENERAL = "permissions_general" + TRACK_PERMISSIONS_SYSTEM_SCHEME = "permissions_system_scheme" + TRACK_PERMISSIONS_TEAM_SCHEMES = "permissions_team_schemes" TRACK_ACTIVITY = "activity" TRACK_LICENSE = "license" @@ -63,6 +68,7 @@ func (a *App) SendDailyDiagnostics() { a.trackLicense() a.trackPlugins() a.trackServer() + a.trackPermissions() } } @@ -650,3 +656,97 @@ func (a *App) trackServer() { a.SendDiagnostic(TRACK_SERVER, data) } + +func (a *App) trackPermissions() { + phase1Complete := false + if ph1res := <-a.Srv.Store.System().GetByName(ADVANCED_PERMISSIONS_MIGRATION_KEY); ph1res.Err == nil { + phase1Complete = true + } + + phase2Complete := false + if ph2res := <-a.Srv.Store.System().GetByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2); ph2res.Err == nil { + phase2Complete = true + } + + a.SendDiagnostic(TRACK_PERMISSIONS_GENERAL, map[string]interface{}{ + "phase_1_migration_complete": phase1Complete, + "phase_2_migration_complete": phase2Complete, + }) + + systemAdminPermissions := "" + if role, err := a.GetRoleByName(model.SYSTEM_ADMIN_ROLE_ID); err == nil { + systemAdminPermissions = strings.Join(role.Permissions, " ") + } + + systemUserPermissions := "" + if role, err := a.GetRoleByName(model.SYSTEM_USER_ROLE_ID); err == nil { + systemUserPermissions = strings.Join(role.Permissions, " ") + } + + teamAdminPermissions := "" + if role, err := a.GetRoleByName(model.TEAM_ADMIN_ROLE_ID); err == nil { + teamAdminPermissions = strings.Join(role.Permissions, " ") + } + + teamUserPermissions := "" + if role, err := a.GetRoleByName(model.TEAM_USER_ROLE_ID); err == nil { + teamUserPermissions = strings.Join(role.Permissions, " ") + } + + channelAdminPermissions := "" + if role, err := a.GetRoleByName(model.CHANNEL_ADMIN_ROLE_ID); err == nil { + channelAdminPermissions = strings.Join(role.Permissions, " ") + } + + channelUserPermissions := "" + if role, err := a.GetRoleByName(model.CHANNEL_USER_ROLE_ID); err == nil { + systemAdminPermissions = strings.Join(role.Permissions, " ") + } + + a.SendDiagnostic(TRACK_PERMISSIONS_SYSTEM_SCHEME, map[string]interface{}{ + "system_admin_permissions": systemAdminPermissions, + "system_user_permissions": systemUserPermissions, + "team_admin_permissions": teamAdminPermissions, + "team_user_permissions": teamUserPermissions, + "channel_admin_permissions": channelAdminPermissions, + "channel_user_permissions": channelUserPermissions, + }) + + if schemes, err := a.GetSchemes(model.SCHEME_SCOPE_TEAM, 0, 100); err == nil { + for _, scheme := range schemes { + teamAdminPermissions := "" + if role, err := a.GetRoleByName(scheme.DefaultTeamAdminRole); err == nil { + teamAdminPermissions = strings.Join(role.Permissions, " ") + } + + teamUserPermissions := "" + if role, err := a.GetRoleByName(scheme.DefaultTeamUserRole); err == nil { + teamUserPermissions = strings.Join(role.Permissions, " ") + } + + channelAdminPermissions := "" + if role, err := a.GetRoleByName(scheme.DefaultChannelAdminRole); err == nil { + channelAdminPermissions = strings.Join(role.Permissions, " ") + } + + channelUserPermissions := "" + if role, err := a.GetRoleByName(scheme.DefaultChannelUserRole); err == nil { + systemAdminPermissions = strings.Join(role.Permissions, " ") + } + + var count int64 = 0 + if res := <-a.Srv.Store.Team().AnalyticsGetTeamCountForScheme(scheme.Id); res.Err == nil { + count = res.Data.(int64) + } + + a.SendDiagnostic(TRACK_PERMISSIONS_TEAM_SCHEMES, map[string]interface{}{ + "scheme_id": scheme.Id, + "team_admin_permissions": teamAdminPermissions, + "team_user_permissions": teamUserPermissions, + "channel_admin_permissions": channelAdminPermissions, + "channel_user_permissions": channelUserPermissions, + "team_count": count, + }) + } + } +} diff --git a/i18n/en.json b/i18n/en.json index fb63aeeb2..7d192b88a 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -156,6 +156,10 @@ "translation": "The channel has been archived or deleted" }, { + "id": "store.sql_team.analytics_get_team_count_for_scheme.app_error", + "translation": "We couldn't get the channel count for the scheme." + }, + { "id": "api.channel.delete_channel.type.invalid", "translation": "Cannot delete direct or group message channels" }, diff --git a/store/sqlstore/team_store.go b/store/sqlstore/team_store.go index 4277a0ba2..d9e33df76 100644 --- a/store/sqlstore/team_store.go +++ b/store/sqlstore/team_store.go @@ -913,3 +913,14 @@ func (s SqlTeamStore) ClearAllCustomRoleAssignments() store.StoreChannel { } }) } + +func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) store.StoreChannel { + return store.Do(func(result *store.StoreResult) { + count, err := s.GetReplica().SelectInt("SELECT count(*) FROM Teams WHERE SchemeId = :SchemeId AND DeleteAt = 0", map[string]interface{}{"SchemeId": schemeId}) + if err != nil { + result.Err = model.NewAppError("SqlTeamStore.AnalyticsGetTeamCountForScheme", "store.sql_team.analytics_get_team_count_for_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError) + return + } + result.Data = count + }) +} diff --git a/store/store.go b/store/store.go index 89adce188..34ba08091 100644 --- a/store/store.go +++ b/store/store.go @@ -110,6 +110,7 @@ type TeamStore interface { MigrateTeamMembers(fromTeamId string, fromUserId string) StoreChannel ResetAllTeamSchemes() StoreChannel ClearAllCustomRoleAssignments() StoreChannel + AnalyticsGetTeamCountForScheme(schemeId string) StoreChannel } type ChannelStore interface { diff --git a/store/storetest/mocks/TeamStore.go b/store/storetest/mocks/TeamStore.go index db5cb658f..8e27e3c05 100644 --- a/store/storetest/mocks/TeamStore.go +++ b/store/storetest/mocks/TeamStore.go @@ -13,6 +13,22 @@ type TeamStore struct { mock.Mock } +// AnalyticsGetTeamCountForScheme provides a mock function with given fields: schemeId +func (_m *TeamStore) AnalyticsGetTeamCountForScheme(schemeId string) store.StoreChannel { + ret := _m.Called(schemeId) + + var r0 store.StoreChannel + if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { + r0 = rf(schemeId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(store.StoreChannel) + } + } + + return r0 +} + // AnalyticsTeamCount provides a mock function with given fields: func (_m *TeamStore) AnalyticsTeamCount() store.StoreChannel { ret := _m.Called() diff --git a/store/storetest/team_store.go b/store/storetest/team_store.go index 2840f2965..ede1a91d3 100644 --- a/store/storetest/team_store.go +++ b/store/storetest/team_store.go @@ -44,6 +44,7 @@ func TestTeamStore(t *testing.T, ss store.Store) { t.Run("MigrateTeamMembers", func(t *testing.T) { testTeamStoreMigrateTeamMembers(t, ss) }) t.Run("ResetAllTeamSchemes", func(t *testing.T) { testResetAllTeamSchemes(t, ss) }) t.Run("ClearAllCustomRoleAssignments", func(t *testing.T) { testTeamStoreClearAllCustomRoleAssignments(t, ss) }) + t.Run("AnalyticsGetTeamCountForScheme", func(t *testing.T) { testTeamStoreAnalyticsGetTeamCountForScheme(t, ss) }) } func testTeamStoreSave(t *testing.T, ss store.Store) { @@ -1265,3 +1266,64 @@ func testTeamStoreClearAllCustomRoleAssignments(t *testing.T, ss store.Store) { require.Nil(t, r4.Err) assert.Equal(t, "", r4.Data.(*model.TeamMember).Roles) } + +func testTeamStoreAnalyticsGetTeamCountForScheme(t *testing.T, ss store.Store) { + s1 := &model.Scheme{ + DisplayName: model.NewId(), + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + s1 = (<-ss.Scheme().Save(s1)).Data.(*model.Scheme) + + count1 := (<-ss.Team().AnalyticsGetTeamCountForScheme(s1.Id)).Data.(int64) + assert.Equal(t, int64(0), count1) + + t1 := &model.Team{ + Name: model.NewId(), + DisplayName: model.NewId(), + Email: MakeEmail(), + Type: model.TEAM_OPEN, + SchemeId: &s1.Id, + } + t1 = (<-ss.Team().Save(t1)).Data.(*model.Team) + + count2 := (<-ss.Team().AnalyticsGetTeamCountForScheme(s1.Id)).Data.(int64) + assert.Equal(t, int64(1), count2) + + t2 := &model.Team{ + Name: model.NewId(), + DisplayName: model.NewId(), + Email: MakeEmail(), + Type: model.TEAM_OPEN, + SchemeId: &s1.Id, + } + t2 = (<-ss.Team().Save(t2)).Data.(*model.Team) + + count3 := (<-ss.Team().AnalyticsGetTeamCountForScheme(s1.Id)).Data.(int64) + assert.Equal(t, int64(2), count3) + + t3 := &model.Team{ + Name: model.NewId(), + DisplayName: model.NewId(), + Email: MakeEmail(), + Type: model.TEAM_OPEN, + } + t3 = (<-ss.Team().Save(t3)).Data.(*model.Team) + + count4 := (<-ss.Team().AnalyticsGetTeamCountForScheme(s1.Id)).Data.(int64) + assert.Equal(t, int64(2), count4) + + t4 := &model.Team{ + Name: model.NewId(), + DisplayName: model.NewId(), + Email: MakeEmail(), + Type: model.TEAM_OPEN, + SchemeId: &s1.Id, + DeleteAt: model.GetMillis(), + } + t4 = (<-ss.Team().Save(t4)).Data.(*model.Team) + + count5 := (<-ss.Team().AnalyticsGetTeamCountForScheme(s1.Id)).Data.(int64) + assert.Equal(t, int64(2), count5) +} |