MM-11348: Add telemetry for advanced permissions. (#9249)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
dc4d009c78
Коммит
8bbee74ed8
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,10 @@
|
||||
"id": "api.channel.delete_channel.deleted.app_error",
|
||||
"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"
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ type TeamStore interface {
|
||||
MigrateTeamMembers(fromTeamId string, fromUserId string) StoreChannel
|
||||
ResetAllTeamSchemes() StoreChannel
|
||||
ClearAllCustomRoleAssignments() StoreChannel
|
||||
AnalyticsGetTeamCountForScheme(schemeId string) StoreChannel
|
||||
}
|
||||
|
||||
type ChannelStore interface {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user