diff --git a/api4/bleve.go b/api4/bleve.go index 1171442d21..0d2177bd40 100644 --- a/api4/bleve.go +++ b/api4/bleve.go @@ -18,8 +18,8 @@ func purgeBleveIndexes(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("purgeBleveIndexes", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_PURGE_BLEVE_INDEXES) { + c.SetPermissionError(model.PERMISSION_PURGE_BLEVE_INDEXES) return } diff --git a/api4/bleve_test.go b/api4/bleve_test.go index 481908f7e8..adc94c1ea5 100644 --- a/api4/bleve_test.go +++ b/api4/bleve_test.go @@ -19,7 +19,7 @@ func TestBlevePurgeIndexes(t *testing.T) { }) t.Run("as system user with write experimental permission", func(t *testing.T) { - th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_PURGE_BLEVE_INDEXES.Id, model.SYSTEM_USER_ROLE_ID) defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL.Id, model.SYSTEM_USER_ROLE_ID) _, resp := th.Client.PurgeBleveIndexes() CheckOKStatus(t, resp) diff --git a/api4/cluster.go b/api4/cluster.go index 7e2b7f60f5..84fb8754fa 100644 --- a/api4/cluster.go +++ b/api4/cluster.go @@ -14,8 +14,8 @@ func (api *API) InitCluster() { } func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY) { + c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY) return } diff --git a/api4/compliance.go b/api4/compliance.go index e5142dff70..e0457cd3bd 100644 --- a/api4/compliance.go +++ b/api4/compliance.go @@ -30,8 +30,8 @@ func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("createComplianceReport", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB) { + c.SetPermissionError(model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB) return } @@ -53,8 +53,8 @@ func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) } func getComplianceReports(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB) { + c.SetPermissionError(model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB) return } @@ -80,8 +80,8 @@ func getComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("getComplianceReport", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB) { + c.SetPermissionError(model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB) return } @@ -108,8 +108,8 @@ func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request defer c.LogAuditRec(auditRec) auditRec.AddMeta("compliance_id", c.Params.ReportId) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT) { + c.SetPermissionError(model.PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT) return } diff --git a/api4/config.go b/api4/config.go index ebc56bc2d9..2d8e774aaf 100644 --- a/api4/config.go +++ b/api4/config.go @@ -78,8 +78,8 @@ func configReload(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("configReload", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionToAny(*c.App.Session(), model.SysconsoleReadPermissions) { - c.SetPermissionError(model.SysconsoleReadPermissions...) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_RELOAD_CONFIG) { + c.SetPermissionError(model.PERMISSION_RELOAD_CONFIG) return } @@ -193,12 +193,11 @@ func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) { } func getEnvironmentConfig(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) - return - } - - envConfig := c.App.GetEnvironmentConfig() + // Only return the environment variables for the subsections which the client is + // allowed to see + envConfig := c.App.GetEnvironmentConfig(func(structField reflect.StructField) bool { + return readFilter(c, structField) + }) w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.Write([]byte(model.StringInterfaceToJson(envConfig))) diff --git a/api4/config_test.go b/api4/config_test.go index 3ab59eeba0..66962549f9 100644 --- a/api4/config_test.go +++ b/api4/config_test.go @@ -77,8 +77,8 @@ func TestGetConfigWithAccessTag(t *testing.T) { th.Client.Login(th.BasicUser.Username, th.BasicUser.Password) // add read sysconsole environment config - th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, model.SYSTEM_USER_ROLE_ID) - defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id, model.SYSTEM_USER_ROLE_ID) + defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id, model.SYSTEM_USER_ROLE_ID) cfg, resp := th.Client.GetConfig() CheckNoError(t, resp) @@ -268,8 +268,8 @@ func TestUpdateConfigWithoutManageSystemPermission(t *testing.T) { th.Client.Login(th.BasicUser.Username, th.BasicUser.Password) // add read sysconsole integrations config - th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, model.SYSTEM_USER_ROLE_ID) - defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, model.SYSTEM_USER_ROLE_ID) + defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, model.SYSTEM_USER_ROLE_ID) t.Run("sysconsole read permission does not provides config write access", func(t *testing.T) { // should be readable because has a sysconsole read permission @@ -289,8 +289,8 @@ func TestUpdateConfigWithoutManageSystemPermission(t *testing.T) { originalValue := *cfg.ServiceSettings.AllowCorsFrom // add the wrong write permission - th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT.Id, model.SYSTEM_USER_ROLE_ID) - defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE.Id, model.SYSTEM_USER_ROLE_ID) + defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE.Id, model.SYSTEM_USER_ROLE_ID) // try update a config value allowed by sysconsole WRITE integrations mockVal := model.NewId() @@ -299,7 +299,7 @@ func TestUpdateConfigWithoutManageSystemPermission(t *testing.T) { CheckNoError(t, resp) // ensure the config setting was not updated - cfg, resp = th.Client.GetConfig() + cfg, resp = th.SystemAdminClient.GetConfig() CheckNoError(t, resp) assert.Equal(t, *cfg.ServiceSettings.AllowCorsFrom, originalValue) }) @@ -309,8 +309,10 @@ func TestUpdateConfigWithoutManageSystemPermission(t *testing.T) { cfg, resp := th.SystemAdminClient.GetConfig() CheckNoError(t, resp) - th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id, model.SYSTEM_USER_ROLE_ID) - defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS.Id, model.SYSTEM_USER_ROLE_ID) + defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id, model.SYSTEM_USER_ROLE_ID) + defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id, model.SYSTEM_USER_ROLE_ID) // try update a config value allowed by sysconsole WRITE integrations mockVal := model.NewId() @@ -477,15 +479,17 @@ func TestGetEnvironmentConfig(t *testing.T) { TeamAdminClient := th.CreateClient() th.LoginTeamAdminWithClient(TeamAdminClient) - _, resp := TeamAdminClient.GetEnvironmentConfig() - CheckForbiddenStatus(t, resp) + envConfig, resp := TeamAdminClient.GetEnvironmentConfig() + CheckNoError(t, resp) + require.Empty(t, envConfig) }) t.Run("as regular user", func(t *testing.T) { Client := th.Client - _, resp := Client.GetEnvironmentConfig() - CheckForbiddenStatus(t, resp) + envConfig, resp := Client.GetEnvironmentConfig() + CheckNoError(t, resp) + require.Empty(t, envConfig) }) t.Run("as not-regular user", func(t *testing.T) { diff --git a/api4/elasticsearch.go b/api4/elasticsearch.go index 5fe590f36b..dd129a979d 100644 --- a/api4/elasticsearch.go +++ b/api4/elasticsearch.go @@ -21,8 +21,10 @@ func testElasticsearch(c *Context, w http.ResponseWriter, r *http.Request) { cfg = c.App.Config() } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) + // PERMISSION_TEST_ELASTICSEARCH is an ancillary permission of PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH, + // which should prevent read-only managers from password sniffing + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_TEST_ELASTICSEARCH) { + c.SetPermissionError(model.PERMISSION_TEST_ELASTICSEARCH) return } @@ -31,14 +33,6 @@ func testElasticsearch(c *Context, w http.ResponseWriter, r *http.Request) { return } - // no sniffing for ports or passwords - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) { - if (*cfg.ElasticsearchSettings.ConnectionUrl != *c.App.Config().ElasticsearchSettings.ConnectionUrl) || (*cfg.ElasticsearchSettings.Password != model.FAKE_SETTING) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) - return - } - } - if err := c.App.TestElasticsearch(cfg); err != nil { c.Err = err return @@ -51,8 +45,8 @@ func purgeElasticsearchIndexes(c *Context, w http.ResponseWriter, r *http.Reques auditRec := c.MakeAuditRecord("purgeElasticsearchIndexes", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_PURGE_ELASTICSEARCH_INDEXES) { + c.SetPermissionError(model.PERMISSION_PURGE_ELASTICSEARCH_INDEXES) return } diff --git a/api4/job.go b/api4/job.go index fb849cf311..428f1a007f 100644 --- a/api4/job.go +++ b/api4/job.go @@ -11,6 +11,7 @@ import ( "github.com/mattermost/mattermost-server/v5/audit" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/shared/mlog" ) func (api *API) InitJob() { @@ -28,17 +29,22 @@ func getJob(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_JOBS) { - c.SetPermissionError(model.PERMISSION_READ_JOBS) - return - } - job, err := c.App.GetJob(c.Params.JobId) if err != nil { c.Err = err return } + hasPermission, permissionRequired := c.App.SessionHasPermissionToReadJob(*c.App.Session(), job.Type) + if permissionRequired == nil { + c.Err = model.NewAppError("getJob", "api.job.retrieve.nopermissions", nil, "", http.StatusBadRequest) + return + } + if !hasPermission { + c.SetPermissionError(permissionRequired) + return + } + w.Write([]byte(job.ToJson())) } @@ -105,8 +111,14 @@ func createJob(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) auditRec.AddMeta("job", job) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_JOBS) { - c.SetPermissionError(model.PERMISSION_MANAGE_JOBS) + hasPermission, permissionRequired := c.App.SessionHasPermissionToCreateJob(*c.App.Session(), job) + if permissionRequired == nil { + c.Err = model.NewAppError("unableToCreateJob", "api.job.unable_to_create_job.incorrect_job_type", nil, "", http.StatusBadRequest) + return + } + + if !hasPermission { + c.SetPermissionError(permissionRequired) return } @@ -128,12 +140,23 @@ func getJobs(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_JOBS) { - c.SetPermissionError(model.PERMISSION_READ_JOBS) + var validJobTypes []string + for _, jobType := range model.ALL_JOB_TYPES { + hasPermission, permissionRequired := c.App.SessionHasPermissionToReadJob(*c.App.Session(), jobType) + if permissionRequired == nil { + mlog.Warn("The job types of a job you are trying to retrieve does not contain permissions", mlog.String("jobType", jobType)) + continue + } + if hasPermission { + validJobTypes = append(validJobTypes, jobType) + } + } + if len(validJobTypes) == 0 { + c.SetPermissionError() return } - jobs, err := c.App.GetJobsPage(c.Params.Page, c.Params.PerPage) + jobs, err := c.App.GetJobsByTypesPage(validJobTypes, c.Params.Page, c.Params.PerPage) if err != nil { c.Err = err return @@ -148,8 +171,13 @@ func getJobsByType(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_JOBS) { - c.SetPermissionError(model.PERMISSION_READ_JOBS) + hasPermission, permissionRequired := c.App.SessionHasPermissionToReadJob(*c.App.Session(), c.Params.JobType) + if permissionRequired == nil { + c.Err = model.NewAppError("getJobsByType", "api.job.retrieve.nopermissions", nil, "", http.StatusBadRequest) + return + } + if !hasPermission { + c.SetPermissionError(permissionRequired) return } @@ -172,8 +200,21 @@ func cancelJob(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) auditRec.AddMeta("job_id", c.Params.JobId) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_JOBS) { - c.SetPermissionError(model.PERMISSION_MANAGE_JOBS) + job, err := c.App.GetJob(c.Params.JobId) + if err != nil { + c.Err = err + return + } + + // if permission to create, permission to cancel, same permission + hasPermission, permissionRequired := c.App.SessionHasPermissionToCreateJob(*c.App.Session(), job) + if permissionRequired == nil { + c.Err = model.NewAppError("unableToCancelJob", "api.job.unable_to_create_job.incorrect_job_type", nil, "", http.StatusBadRequest) + return + } + + if !hasPermission { + c.SetPermissionError(permissionRequired) return } diff --git a/api4/job_test.go b/api4/job_test.go index 9fdf12f1f6..76201397c0 100644 --- a/api4/job_test.go +++ b/api4/job_test.go @@ -26,7 +26,7 @@ func TestCreateJob(t *testing.T) { } _, resp := th.SystemManagerClient.CreateJob(job) - require.Nil(t, resp.Error) + CheckForbiddenStatus(t, resp) received, resp := th.SystemAdminClient.CreateJob(job) require.Nil(t, resp.Error) @@ -40,6 +40,7 @@ func TestCreateJob(t *testing.T) { _, resp = th.SystemAdminClient.CreateJob(job) CheckBadRequestStatus(t, resp) + job.Type = model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING _, resp = th.Client.CreateJob(job) CheckForbiddenStatus(t, resp) } @@ -51,6 +52,7 @@ func TestGetJob(t *testing.T) { job := &model.Job{ Id: model.NewId(), Status: model.JOB_STATUS_PENDING, + Type: model.JOB_TYPE_MESSAGE_EXPORT, } _, err := th.App.Srv().Store.Job().Save(job) require.NoError(t, err) @@ -77,7 +79,7 @@ func TestGetJobs(t *testing.T) { th := Setup(t) defer th.TearDown() - jobType := model.NewId() + jobType := model.JOB_TYPE_DATA_RETENTION t0 := model.GetMillis() jobs := []*model.Job{ @@ -124,7 +126,7 @@ func TestGetJobsByType(t *testing.T) { th := Setup(t) defer th.TearDown() - jobType := model.NewId() + jobType := model.JOB_TYPE_DATA_RETENTION jobs := []*model.Job{ { @@ -177,7 +179,7 @@ func TestGetJobsByType(t *testing.T) { _, resp = th.Client.GetJobsByType(jobType, 0, 60) CheckForbiddenStatus(t, resp) - _, resp = th.SystemManagerClient.GetJobsByType(model.JOB_TYPE_MESSAGE_EXPORT, 0, 60) + _, resp = th.SystemManagerClient.GetJobsByType(model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING, 0, 60) require.Nil(t, resp.Error) } @@ -273,20 +275,21 @@ func TestCancelJob(t *testing.T) { th := Setup(t) defer th.TearDown() + jobType := model.JOB_TYPE_MESSAGE_EXPORT jobs := []*model.Job{ { Id: model.NewId(), - Type: model.NewId(), + Type: jobType, Status: model.JOB_STATUS_PENDING, }, { Id: model.NewId(), - Type: model.NewId(), + Type: jobType, Status: model.JOB_STATUS_IN_PROGRESS, }, { Id: model.NewId(), - Type: model.NewId(), + Type: jobType, Status: model.JOB_STATUS_SUCCESS, }, } @@ -310,5 +313,5 @@ func TestCancelJob(t *testing.T) { CheckInternalErrorStatus(t, resp) _, resp = th.SystemAdminClient.CancelJob(model.NewId()) - CheckInternalErrorStatus(t, resp) + CheckNotFoundStatus(t, resp) } diff --git a/api4/ldap.go b/api4/ldap.go index 69f867b8fd..3013bcb54a 100644 --- a/api4/ldap.go +++ b/api4/ldap.go @@ -50,8 +50,8 @@ func syncLdap(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("syncLdap", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_LDAP_SYNC_JOB) { + c.SetPermissionError(model.PERMISSION_CREATE_LDAP_SYNC_JOB) return } @@ -67,8 +67,8 @@ func testLdap(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_TEST_LDAP) { + c.SetPermissionError(model.PERMISSION_TEST_LDAP) return } @@ -319,8 +319,8 @@ func parseLdapCertificateRequest(r *http.Request, maxFileSize int64) (*multipart } func addLdapPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { - c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_ADD_LDAP_PUBLIC_CERT) { + c.SetPermissionError(model.PERMISSION_ADD_LDAP_PUBLIC_CERT) return } @@ -343,8 +343,8 @@ func addLdapPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request } func addLdapPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { - c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_ADD_LDAP_PRIVATE_CERT) { + c.SetPermissionError(model.PERMISSION_ADD_LDAP_PRIVATE_CERT) return } @@ -367,8 +367,8 @@ func addLdapPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Reques } func removeLdapPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { - c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REMOVE_LDAP_PUBLIC_CERT) { + c.SetPermissionError(model.PERMISSION_REMOVE_LDAP_PUBLIC_CERT) return } @@ -385,8 +385,8 @@ func removeLdapPublicCertificate(c *Context, w http.ResponseWriter, r *http.Requ } func removeLdapPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { - c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REMOVE_LDAP_PRIVATE_CERT) { + c.SetPermissionError(model.PERMISSION_REMOVE_LDAP_PRIVATE_CERT) return } diff --git a/api4/license.go b/api4/license.go index 89d23d658c..5a6c434728 100644 --- a/api4/license.go +++ b/api4/license.go @@ -38,7 +38,7 @@ func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) { var clientLicense map[string]string - if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ABOUT) { + if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_LICENSE_INFORMATION) { clientLicense = c.App.Srv().ClientLicense() } else { clientLicense = c.App.Srv().GetSanitizedClientLicense() @@ -52,8 +52,8 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) c.LogAudit("attempt") - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_LICENSE_INFORMATION) { + c.SetPermissionError(model.PERMISSION_MANAGE_LICENSE_INFORMATION) return } @@ -118,8 +118,8 @@ func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) c.LogAudit("attempt") - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_LICENSE_INFORMATION) { + c.SetPermissionError(model.PERMISSION_MANAGE_LICENSE_INFORMATION) return } @@ -144,8 +144,8 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) c.LogAudit("attempt") - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_LICENSE_INFORMATION) { + c.SetPermissionError(model.PERMISSION_MANAGE_LICENSE_INFORMATION) return } @@ -213,8 +213,8 @@ func requestRenewalLink(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) c.LogAudit("attempt") - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_LICENSE_INFORMATION) { + c.SetPermissionError(model.PERMISSION_MANAGE_LICENSE_INFORMATION) return } diff --git a/api4/role.go b/api4/role.go index 0ce9ddc4a4..40fe4fcb67 100644 --- a/api4/role.go +++ b/api4/role.go @@ -162,6 +162,11 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { return } } + + ancillaryPermissions := model.AddAncillaryPermissions(*patch.Permissions) + *patch.Permissions = append(*patch.Permissions, ancillaryPermissions...) + + *patch.Permissions = model.UniqueStrings(*patch.Permissions) } if c.App.Srv().License() != nil && isGuest && !*c.App.Srv().License().Features.GuestAccountsPermissions { diff --git a/api4/saml.go b/api4/saml.go index d6aa0c9cda..eef2f46941 100644 --- a/api4/saml.go +++ b/api4/saml.go @@ -62,8 +62,8 @@ func parseSamlCertificateRequest(r *http.Request, maxFileSize int64) (*multipart } func addSamlPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_ADD_SAML_PUBLIC_CERT) { + c.SetPermissionError(model.PERMISSION_ADD_SAML_PUBLIC_CERT) return } @@ -86,8 +86,8 @@ func addSamlPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request } func addSamlPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_ADD_SAML_PRIVATE_CERT) { + c.SetPermissionError(model.PERMISSION_ADD_SAML_PRIVATE_CERT) return } @@ -110,8 +110,8 @@ func addSamlPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Reques } func addSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_ADD_SAML_IDP_CERT) { + c.SetPermissionError(model.PERMISSION_ADD_SAML_IDP_CERT) return } @@ -163,8 +163,8 @@ func addSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) { } func removeSamlPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REMOVE_SAML_PUBLIC_CERT) { + c.SetPermissionError(model.PERMISSION_REMOVE_SAML_PUBLIC_CERT) return } @@ -181,8 +181,8 @@ func removeSamlPublicCertificate(c *Context, w http.ResponseWriter, r *http.Requ } func removeSamlPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REMOVE_SAML_PRIVATE_CERT) { + c.SetPermissionError(model.PERMISSION_REMOVE_SAML_PRIVATE_CERT) return } @@ -199,8 +199,8 @@ func removeSamlPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Req } func removeSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_REMOVE_SAML_IDP_CERT) { + c.SetPermissionError(model.PERMISSION_REMOVE_SAML_IDP_CERT) return } @@ -217,8 +217,8 @@ func removeSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request } func getSamlCertificateStatus(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_GET_SAML_CERT_STATUS) { + c.SetPermissionError(model.PERMISSION_GET_SAML_CERT_STATUS) return } @@ -227,8 +227,8 @@ func getSamlCertificateStatus(c *Context, w http.ResponseWriter, r *http.Request } func getSamlMetadataFromIdp(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_GET_SAML_METADATA_FROM_IDP) { + c.SetPermissionError(model.PERMISSION_GET_SAML_METADATA_FROM_IDP) return } diff --git a/api4/system.go b/api4/system.go index a401331313..e5cf34298a 100644 --- a/api4/system.go +++ b/api4/system.go @@ -195,8 +195,8 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) { cfg = c.App.Config() } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_TEST_EMAIL) { + c.SetPermissionError(model.PERMISSION_TEST_EMAIL) return } @@ -215,8 +215,8 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) { } func testSiteURL(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_TEST_SITE_URL) { + c.SetPermissionError(model.PERMISSION_TEST_SITE_URL) return } @@ -232,11 +232,6 @@ func testSiteURL(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) && siteURL != *c.App.Config().ServiceSettings.SiteURL { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) - return - } - err := c.App.TestSiteURL(siteURL) if err != nil { c.Err = err @@ -250,8 +245,8 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("getAudits", audit.Fail) defer c.LogAuditRec(auditRec) - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_AUDITS) { + c.SetPermissionError(model.PERMISSION_READ_AUDITS) return } @@ -269,8 +264,8 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) { } func databaseRecycle(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_RECYCLE_DATABASE_CONNECTIONS) { + c.SetPermissionError(model.PERMISSION_RECYCLE_DATABASE_CONNECTIONS) return } @@ -289,8 +284,8 @@ func databaseRecycle(c *Context, w http.ResponseWriter, r *http.Request) { } func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_INVALIDATE_CACHES) { + c.SetPermissionError(model.PERMISSION_INVALIDATE_CACHES) return } @@ -323,8 +318,8 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) { return } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_REPORTING) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_REPORTING) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_GET_LOGS) { + c.SetPermissionError(model.PERMISSION_GET_LOGS) return } @@ -386,12 +381,8 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) { name = "standard" } - permissions := []*model.Permission{ - model.PERMISSION_SYSCONSOLE_READ_REPORTING, - model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS, - } - if !c.App.SessionHasPermissionToAny(*c.App.Session(), permissions) { - c.SetPermissionError(permissions...) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_GET_ANALYTICS) { + c.SetPermissionError(model.PERMISSION_GET_ANALYTICS) return } @@ -430,8 +421,8 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) { cfg = c.App.Config() } - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_TEST_S3) { + c.SetPermissionError(model.PERMISSION_TEST_S3) return } diff --git a/api4/team.go b/api4/team.go index 78a381ae49..258d93a73b 100644 --- a/api4/team.go +++ b/api4/team.go @@ -1396,8 +1396,8 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) { } func invalidateAllEmailInvites(c *Context, w http.ResponseWriter, r *http.Request) { - if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) { - c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION) + if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_INVALIDATE_EMAIL_INVITE) { + c.SetPermissionError(model.PERMISSION_INVALIDATE_EMAIL_INVITE) return } diff --git a/api4/team_test.go b/api4/team_test.go index 045576b7fe..ce3e4f1455 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -3321,8 +3321,8 @@ func TestInvalidateAllEmailInvites(t *testing.T) { }) t.Run("OK when request performed by system user with requisite system permission", func(t *testing.T) { - th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION.Id, model.SYSTEM_USER_ROLE_ID) - defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION.Id, model.SYSTEM_USER_ROLE_ID) + th.AddPermissionToRole(model.PERMISSION_INVALIDATE_EMAIL_INVITE.Id, model.SYSTEM_USER_ROLE_ID) + defer th.RemovePermissionFromRole(model.PERMISSION_INVALIDATE_EMAIL_INVITE.Id, model.SYSTEM_USER_ROLE_ID) ok, res := th.Client.InvalidateEmailInvites() require.Equal(t, true, ok) CheckOKStatus(t, res) diff --git a/app/app_iface.go b/app/app_iface.go index acfed49d46..1106609ffc 100644 --- a/app/app_iface.go +++ b/app/app_iface.go @@ -14,6 +14,7 @@ import ( "mime/multipart" "net/http" "net/url" + "reflect" "time" "github.com/dyatlov/go-opengraph/opengraph" @@ -159,7 +160,8 @@ type AppIface interface { // and the API route for custom ones. Errors if not found or if custom and deleted. GetEmojiStaticUrl(emojiName string) (string, *model.AppError) // GetEnvironmentConfig returns a map of configuration keys whose values have been overridden by an environment variable. - GetEnvironmentConfig() map[string]interface{} + // If filter is not nil and returns false for a struct field, that field will be omitted. + GetEnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} // GetFilteredUsersStats is used to get a count of users based on the set of filters supported by UserCountOptions. GetFilteredUsersStats(options *model.UserCountOptions) (*model.UsersStats, *model.AppError) // GetGroupsByTeam returns the paged list and the total count of group associated to the given team. @@ -511,7 +513,7 @@ type AppIface interface { DoUploadFileExpectModification(now time.Time, rawTeamId string, rawChannelId string, rawUserId string, rawFilename string, data []byte) (*model.FileInfo, []byte, *model.AppError) DownloadFromURL(downloadURL string) ([]byte, error) EnableUserAccessToken(token *model.UserAccessToken) *model.AppError - EnvironmentConfig() map[string]interface{} + EnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} ExportPermissions(w io.Writer) error FetchSamlMetadataFromIdp(url string) ([]byte, *model.AppError) FileBackend() (filestore.FileBackend, *model.AppError) @@ -615,6 +617,8 @@ type AppIface interface { GetJobs(offset int, limit int) ([]*model.Job, *model.AppError) GetJobsByType(jobType string, offset int, limit int) ([]*model.Job, *model.AppError) GetJobsByTypePage(jobType string, page int, perPage int) ([]*model.Job, *model.AppError) + GetJobsByTypes(jobTypes []string, offset int, limit int) ([]*model.Job, *model.AppError) + GetJobsByTypesPage(jobType []string, page int, perPage int) ([]*model.Job, *model.AppError) GetJobsPage(page int, perPage int) ([]*model.Job, *model.AppError) GetLatestTermsOfService() (*model.TermsOfService, *model.AppError) GetLogs(page, perPage int) ([]string, *model.AppError) @@ -948,6 +952,8 @@ type AppIface interface { SessionHasPermissionToCategory(session model.Session, userID, teamID, categoryId string) bool SessionHasPermissionToChannel(session model.Session, channelID string, permission *model.Permission) bool SessionHasPermissionToChannelByPost(session model.Session, postID string, permission *model.Permission) bool + SessionHasPermissionToCreateJob(session model.Session, job *model.Job) (bool, *model.Permission) + SessionHasPermissionToReadJob(session model.Session, jobType string) (bool, *model.Permission) SessionHasPermissionToTeam(session model.Session, teamID string, permission *model.Permission) bool SessionHasPermissionToUser(session model.Session, userID string) bool SessionHasPermissionToUserOrBot(session model.Session, userID string) bool diff --git a/app/config.go b/app/config.go index 6b31517590..3c5a5404fa 100644 --- a/app/config.go +++ b/app/config.go @@ -14,6 +14,7 @@ import ( "fmt" "net/http" "net/url" + "reflect" "strconv" "time" @@ -38,12 +39,12 @@ func (a *App) Config() *model.Config { return a.Srv().Config() } -func (s *Server) EnvironmentConfig() map[string]interface{} { - return s.configStore.GetEnvironmentOverrides() +func (s *Server) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} { + return s.configStore.GetEnvironmentOverridesWithFilter(filter) } -func (a *App) EnvironmentConfig() map[string]interface{} { - return a.Srv().EnvironmentConfig() +func (a *App) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} { + return a.Srv().EnvironmentConfig(filter) } func (s *Server) UpdateConfig(f func(*model.Config)) { @@ -398,8 +399,9 @@ func (a *App) GetSanitizedConfig() *model.Config { } // GetEnvironmentConfig returns a map of configuration keys whose values have been overridden by an environment variable. -func (a *App) GetEnvironmentConfig() map[string]interface{} { - return a.EnvironmentConfig() +// If filter is not nil and returns false for a struct field, that field will be omitted. +func (a *App) GetEnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} { + return a.EnvironmentConfig(filter) } // SaveConfig replaces the active configuration, optionally notifying cluster peers. diff --git a/app/job.go b/app/job.go index c1388aff4f..0ec7a2f6de 100644 --- a/app/job.go +++ b/app/job.go @@ -52,6 +52,18 @@ func (a *App) GetJobsByType(jobType string, offset int, limit int) ([]*model.Job return jobs, nil } +func (a *App) GetJobsByTypesPage(jobType []string, page int, perPage int) ([]*model.Job, *model.AppError) { + return a.GetJobsByTypes(jobType, page*perPage, perPage) +} + +func (a *App) GetJobsByTypes(jobTypes []string, offset int, limit int) ([]*model.Job, *model.AppError) { + jobs, err := a.Srv().Store.Job().GetAllByTypesPage(jobTypes, offset, limit) + if err != nil { + return nil, model.NewAppError("GetJobsByType", "app.job.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) + } + return jobs, nil +} + func (a *App) CreateJob(job *model.Job) (*model.Job, *model.AppError) { return a.Srv().Jobs.CreateJob(job.Type, job.Data) } @@ -59,3 +71,64 @@ func (a *App) CreateJob(job *model.Job) (*model.Job, *model.AppError) { func (a *App) CancelJob(jobId string) *model.AppError { return a.Srv().Jobs.RequestCancellation(jobId) } + +func (a *App) SessionHasPermissionToCreateJob(session model.Session, job *model.Job) (bool, *model.Permission) { + switch job.Type { + case model.JOB_TYPE_BLEVE_POST_INDEXING: + return a.SessionHasPermissionTo(session, model.PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB), model.PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB + case model.JOB_TYPE_DATA_RETENTION: + return a.SessionHasPermissionTo(session, model.PERMISSION_CREATE_DATA_RETENTION_JOB), model.PERMISSION_CREATE_DATA_RETENTION_JOB + case model.JOB_TYPE_MESSAGE_EXPORT: + return a.SessionHasPermissionTo(session, model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB), model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB + case model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING: + return a.SessionHasPermissionTo(session, model.PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB), model.PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB + case model.JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION: + return a.SessionHasPermissionTo(session, model.PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB), model.PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB + case model.JOB_TYPE_LDAP_SYNC: + return a.SessionHasPermissionTo(session, model.PERMISSION_CREATE_LDAP_SYNC_JOB), model.PERMISSION_CREATE_LDAP_SYNC_JOB + case + model.JOB_TYPE_MIGRATIONS, + model.JOB_TYPE_PLUGINS, + model.JOB_TYPE_PRODUCT_NOTICES, + model.JOB_TYPE_EXPIRY_NOTIFY, + model.JOB_TYPE_ACTIVE_USERS, + model.JOB_TYPE_IMPORT_PROCESS, + model.JOB_TYPE_IMPORT_DELETE, + model.JOB_TYPE_EXPORT_PROCESS, + model.JOB_TYPE_EXPORT_DELETE, + model.JOB_TYPE_CLOUD: + return a.SessionHasPermissionTo(session, model.PERMISSION_MANAGE_JOBS), model.PERMISSION_MANAGE_JOBS + } + + return false, nil +} + +func (a *App) SessionHasPermissionToReadJob(session model.Session, jobType string) (bool, *model.Permission) { + switch jobType { + case model.JOB_TYPE_DATA_RETENTION: + return a.SessionHasPermissionTo(session, model.PERMISSION_READ_DATA_RETENTION_JOB), model.PERMISSION_READ_DATA_RETENTION_JOB + case model.JOB_TYPE_MESSAGE_EXPORT: + return a.SessionHasPermissionTo(session, model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB), model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB + case model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING: + return a.SessionHasPermissionTo(session, model.PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB), model.PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB + case model.JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION: + return a.SessionHasPermissionTo(session, model.PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB), model.PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB + case model.JOB_TYPE_LDAP_SYNC: + return a.SessionHasPermissionTo(session, model.PERMISSION_READ_LDAP_SYNC_JOB), model.PERMISSION_READ_LDAP_SYNC_JOB + case + model.JOB_TYPE_BLEVE_POST_INDEXING, + model.JOB_TYPE_MIGRATIONS, + model.JOB_TYPE_PLUGINS, + model.JOB_TYPE_PRODUCT_NOTICES, + model.JOB_TYPE_EXPIRY_NOTIFY, + model.JOB_TYPE_ACTIVE_USERS, + model.JOB_TYPE_IMPORT_PROCESS, + model.JOB_TYPE_IMPORT_DELETE, + model.JOB_TYPE_EXPORT_PROCESS, + model.JOB_TYPE_EXPORT_DELETE, + model.JOB_TYPE_CLOUD: + return a.SessionHasPermissionTo(session, model.PERMISSION_READ_JOBS), model.PERMISSION_READ_JOBS + } + + return false, nil +} diff --git a/app/job_test.go b/app/job_test.go index 4fdc0df585..72a2d4e3ea 100644 --- a/app/job_test.go +++ b/app/job_test.go @@ -6,6 +6,7 @@ package app import ( "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/mattermost/mattermost-server/v5/model" @@ -29,6 +30,185 @@ func TestGetJob(t *testing.T) { require.Equal(t, status, received, "incorrect job status received") } +func TestSessionHasPermissionToCreateJob(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + jobs := []model.Job{ + { + Id: model.NewId(), + Type: model.JOB_TYPE_BLEVE_POST_INDEXING, + CreateAt: 1000, + }, + { + Id: model.NewId(), + Type: model.JOB_TYPE_DATA_RETENTION, + CreateAt: 999, + }, + { + Id: model.NewId(), + Type: model.JOB_TYPE_MESSAGE_EXPORT, + CreateAt: 1001, + }, + } + + testCases := []struct { + Job model.Job + PermissionRequired *model.Permission + }{ + { + Job: jobs[0], + PermissionRequired: model.PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB, + }, + { + Job: jobs[1], + PermissionRequired: model.PERMISSION_CREATE_DATA_RETENTION_JOB, + }, + { + Job: jobs[2], + PermissionRequired: model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB, + }, + } + + session := model.Session{ + Roles: model.SYSTEM_USER_ROLE_ID + " " + model.SYSTEM_ADMIN_ROLE_ID, + } + + // Check to see if admin has permission to all the jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job) + assert.Equal(t, true, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } + + session = model.Session{ + Roles: model.SYSTEM_USER_ROLE_ID + " " + model.SYSTEM_READ_ONLY_ADMIN_ROLE_ID, + } + + // Initially the system read only admin should not have access to create these jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job) + assert.Equal(t, false, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } + + role, _ := th.App.GetRoleByName(model.SYSTEM_READ_ONLY_ADMIN_ROLE_ID) + + role.Permissions = append(role.Permissions, model.PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB.Id) + + _, err := th.App.UpdateRole(role) + require.Nil(t, err) + + // Now system read only admin should have ability to create a Belve Post Index job but not the others + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job) + expectedHasPermission := testCase.Job.Type == model.JOB_TYPE_BLEVE_POST_INDEXING + assert.Equal(t, expectedHasPermission, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } + + role.Permissions = append(role.Permissions, model.PERMISSION_CREATE_DATA_RETENTION_JOB.Id) + role.Permissions = append(role.Permissions, model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB.Id) + + _, err = th.App.UpdateRole(role) + require.Nil(t, err) + + // Now system read only admin should have ability to create all jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job) + assert.Equal(t, true, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } +} + +func TestSessionHasPermissionToReadJob(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + jobs := []model.Job{ + { + Id: model.NewId(), + Type: model.JOB_TYPE_DATA_RETENTION, + CreateAt: 999, + }, + { + Id: model.NewId(), + Type: model.JOB_TYPE_MESSAGE_EXPORT, + CreateAt: 1001, + }, + } + testCases := []struct { + Job model.Job + PermissionRequired *model.Permission + }{ + { + Job: jobs[0], + PermissionRequired: model.PERMISSION_READ_DATA_RETENTION_JOB, + }, + { + Job: jobs[1], + PermissionRequired: model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB, + }, + } + + session := model.Session{ + Roles: model.SYSTEM_USER_ROLE_ID + " " + model.SYSTEM_ADMIN_ROLE_ID, + } + + // Check to see if admin has permission to all the jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type) + assert.Equal(t, true, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } + + session = model.Session{ + Roles: model.SYSTEM_USER_ROLE_ID + " " + model.SYSTEM_MANAGER_ROLE_ID, + } + + // Initially the system manager should not have access to read these jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type) + assert.Equal(t, false, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } + + role, _ := th.App.GetRoleByName(model.SYSTEM_MANAGER_ROLE_ID) + + role.Permissions = append(role.Permissions, model.PERMISSION_READ_DATA_RETENTION_JOB.Id) + + _, err := th.App.UpdateRole(role) + require.Nil(t, err) + + // Now system manager should have ability to read data retention jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type) + expectedHasPermission := testCase.Job.Type == model.JOB_TYPE_DATA_RETENTION + assert.Equal(t, expectedHasPermission, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } + + role.Permissions = append(role.Permissions, model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB.Id) + + _, err = th.App.UpdateRole(role) + require.Nil(t, err) + + // Now system read only admin should have ability to create all jobs + for _, testCase := range testCases { + hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type) + assert.Equal(t, true, hasPermission) + require.NotNil(t, permissionRequired) + assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id) + } +} + func TestGetJobByType(t *testing.T) { th := Setup(t) defer th.TearDown() @@ -70,3 +250,55 @@ func TestGetJobByType(t *testing.T) { require.Len(t, received, 1, "received wrong number of statuses") require.Equal(t, statuses[1], received[0], "should've received oldest job last") } + +func TestGetJobsByTypes(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + jobType := model.NewId() + jobType1 := model.NewId() + jobType2 := model.NewId() + + statuses := []*model.Job{ + { + Id: model.NewId(), + Type: jobType, + CreateAt: 1000, + }, + { + Id: model.NewId(), + Type: jobType1, + CreateAt: 999, + }, + { + Id: model.NewId(), + Type: jobType2, + CreateAt: 1001, + }, + } + + for _, status := range statuses { + _, err := th.App.Srv().Store.Job().Save(status) + require.NoError(t, err) + defer th.App.Srv().Store.Job().Delete(status.Id) + } + + jobTypes := []string{jobType, jobType1, jobType2} + received, err := th.App.GetJobsByTypes(jobTypes, 0, 2) + require.Nil(t, err) + require.Len(t, received, 2, "received wrong number of jobs") + require.Equal(t, statuses[2], received[0], "should've received newest job first") + require.Equal(t, statuses[0], received[1], "should've received second newest job second") + + received, err = th.App.GetJobsByTypes(jobTypes, 2, 2) + require.Nil(t, err) + require.Len(t, received, 1, "received wrong number of jobs") + require.Equal(t, statuses[1], received[0], "should've received oldest job last") + + jobTypes = []string{jobType1, jobType2} + received, err = th.App.GetJobsByTypes(jobTypes, 0, 3) + require.Nil(t, err) + require.Len(t, received, 2, "received wrong number of jobs") + require.Equal(t, statuses[2], received[0], "received wrong job type") + require.Equal(t, statuses[1], received[1], "received wrong job type") +} diff --git a/app/opentracing/opentracing_layer.go b/app/opentracing/opentracing_layer.go index 79e6730653..ff3b3c6ac7 100644 --- a/app/opentracing/opentracing_layer.go +++ b/app/opentracing/opentracing_layer.go @@ -14,6 +14,7 @@ import ( "mime/multipart" "net/http" "net/url" + "reflect" "time" "github.com/dyatlov/go-opengraph/opengraph" @@ -3714,7 +3715,7 @@ func (a *OpenTracingAppLayer) EnableUserAccessToken(token *model.UserAccessToken return resultVar0 } -func (a *OpenTracingAppLayer) EnvironmentConfig() map[string]interface{} { +func (a *OpenTracingAppLayer) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.EnvironmentConfig") @@ -3726,7 +3727,7 @@ func (a *OpenTracingAppLayer) EnvironmentConfig() map[string]interface{} { }() defer span.Finish() - resultVar0 := a.app.EnvironmentConfig() + resultVar0 := a.app.EnvironmentConfig(filter) return resultVar0 } @@ -5541,7 +5542,7 @@ func (a *OpenTracingAppLayer) GetEmojiStaticUrl(emojiName string) (string, *mode return resultVar0, resultVar1 } -func (a *OpenTracingAppLayer) GetEnvironmentConfig() map[string]interface{} { +func (a *OpenTracingAppLayer) GetEnvironmentConfig(filter func(reflect.StructField) bool) map[string]interface{} { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetEnvironmentConfig") @@ -5553,7 +5554,7 @@ func (a *OpenTracingAppLayer) GetEnvironmentConfig() map[string]interface{} { }() defer span.Finish() - resultVar0 := a.app.GetEnvironmentConfig() + resultVar0 := a.app.GetEnvironmentConfig(filter) return resultVar0 } @@ -6345,6 +6346,50 @@ func (a *OpenTracingAppLayer) GetJobsByTypePage(jobType string, page int, perPag return resultVar0, resultVar1 } +func (a *OpenTracingAppLayer) GetJobsByTypes(jobTypes []string, offset int, limit int) ([]*model.Job, *model.AppError) { + origCtx := a.ctx + span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetJobsByTypes") + + a.ctx = newCtx + a.app.Srv().Store.SetContext(newCtx) + defer func() { + a.app.Srv().Store.SetContext(origCtx) + a.ctx = origCtx + }() + + defer span.Finish() + resultVar0, resultVar1 := a.app.GetJobsByTypes(jobTypes, offset, limit) + + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + +func (a *OpenTracingAppLayer) GetJobsByTypesPage(jobType []string, page int, perPage int) ([]*model.Job, *model.AppError) { + origCtx := a.ctx + span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetJobsByTypesPage") + + a.ctx = newCtx + a.app.Srv().Store.SetContext(newCtx) + defer func() { + a.app.Srv().Store.SetContext(origCtx) + a.ctx = origCtx + }() + + defer span.Finish() + resultVar0, resultVar1 := a.app.GetJobsByTypesPage(jobType, page, perPage) + + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + func (a *OpenTracingAppLayer) GetJobsPage(page int, perPage int) ([]*model.Job, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetJobsPage") @@ -14053,6 +14098,23 @@ func (a *OpenTracingAppLayer) SessionHasPermissionToChannelByPost(session model. return resultVar0 } +func (a *OpenTracingAppLayer) SessionHasPermissionToCreateJob(session model.Session, job *model.Job) (bool, *model.Permission) { + origCtx := a.ctx + span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SessionHasPermissionToCreateJob") + + a.ctx = newCtx + a.app.Srv().Store.SetContext(newCtx) + defer func() { + a.app.Srv().Store.SetContext(origCtx) + a.ctx = origCtx + }() + + defer span.Finish() + resultVar0, resultVar1 := a.app.SessionHasPermissionToCreateJob(session, job) + + return resultVar0, resultVar1 +} + func (a *OpenTracingAppLayer) SessionHasPermissionToManageBot(session model.Session, botUserId string) *model.AppError { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SessionHasPermissionToManageBot") @@ -14075,6 +14137,23 @@ func (a *OpenTracingAppLayer) SessionHasPermissionToManageBot(session model.Sess return resultVar0 } +func (a *OpenTracingAppLayer) SessionHasPermissionToReadJob(session model.Session, jobType string) (bool, *model.Permission) { + origCtx := a.ctx + span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SessionHasPermissionToReadJob") + + a.ctx = newCtx + a.app.Srv().Store.SetContext(newCtx) + defer func() { + a.app.Srv().Store.SetContext(origCtx) + a.ctx = origCtx + }() + + defer span.Finish() + resultVar0, resultVar1 := a.app.SessionHasPermissionToReadJob(session, jobType) + + return resultVar0, resultVar1 +} + func (a *OpenTracingAppLayer) SessionHasPermissionToTeam(session model.Session, teamID string, permission *model.Permission) bool { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SessionHasPermissionToTeam") diff --git a/app/permissions_migrations.go b/app/permissions_migrations.go index 4d88034869..b6820c2b4b 100644 --- a/app/permissions_migrations.go +++ b/app/permissions_migrations.go @@ -537,7 +537,7 @@ func (a *App) getAddManageRemoteClustersPermissionsMigration() (permissionsMap, func (a *App) getAddDownloadComplianceExportResult() (permissionsMap, error) { transformations := []permissionTransformation{} - permissionsToAddComplianceRead := []string{model.PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT.Id, model.PERMISSION_READ_JOBS.Id} + permissionsToAddComplianceRead := []string{model.PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT.Id, model.PERMISSION_READ_DATA_RETENTION_JOB.Id} permissionsToAddComplianceWrite := []string{model.PERMISSION_MANAGE_JOBS.Id} // add the new permissions to system admin @@ -562,6 +562,350 @@ func (a *App) getAddDownloadComplianceExportResult() (permissionsMap, error) { return transformations, nil } +func (a *App) getAddExperimentalSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsExperimentalRead := []string{model.PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE.Id, model.PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES.Id, model.PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS.Id} + permissionsExperimentalWrite := []string{model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE.Id, model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES.Id, model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS.Id} + + // Give the new subsection READ permissions to any user with READ_EXPERIMENTAL + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id), + Add: permissionsExperimentalRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_EXPERIMENTAL + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL.Id), + Add: permissionsExperimentalWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL.Id}, + }) + + // Give the ancillary permissions MANAGE_JOBS and PURGE_BLEVE_INDEXES to anyone with WRITE_EXPERIMENTAL_BLEVE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE.Id), + Add: []string{model.PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB.Id, model.PERMISSION_PURGE_BLEVE_INDEXES.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddIntegrationsSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsIntegrationsRead := []string{model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS.Id, model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF.Id, model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id} + permissionsIntegrationsWrite := []string{model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS.Id, model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF.Id, model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS.Id} + + // Give the new subsection READ permissions to any user with READ_INTEGRATIONS + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id), + Add: permissionsIntegrationsRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_EXPERIMENTAL + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id), + Add: permissionsIntegrationsWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddSiteSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsSiteRead := []string{model.PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_EMOJI.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_POSTS.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS.Id, model.PERMISSION_SYSCONSOLE_READ_SITE_NOTICES.Id} + permissionsSiteWrite := []string{model.PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS.Id, model.PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES.Id} + + // Give the new subsection READ permissions to any user with READ_SITE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_SITE.Id), + Add: permissionsSiteRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_SITE.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_SITE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_SITE.Id), + Add: permissionsSiteWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_SITE.Id}, + }) + + // Give the ancillary permissions EDIT_BRAND to anyone with WRITE_SITE_CUSTOMIZATION + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION.Id), + Add: []string{model.PERMISSION_EDIT_BRAND.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddComplianceSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsComplianceRead := []string{model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY.Id, model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT.Id, model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING.Id, model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id} + permissionsComplianceWrite := []string{model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY.Id, model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT.Id, model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING.Id, model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id} + + // Give the new subsection READ permissions to any user with READ_COMPLIANCE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE.Id), + Add: permissionsComplianceRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_COMPLIANCE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE.Id), + Add: permissionsComplianceWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE.Id}, + }) + + // Ancilary permissions + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY.Id), + Add: []string{model.PERMISSION_CREATE_DATA_RETENTION_JOB.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY.Id), + Add: []string{model.PERMISSION_READ_DATA_RETENTION_JOB.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT.Id), + Add: []string{model.PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB.Id, model.PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT.Id), + Add: []string{model.PERMISSION_READ_COMPLIANCE_EXPORT_JOB.Id, model.PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id), + Add: []string{model.PERMISSION_READ_AUDITS.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddEnvironmentSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsEnvironmentRead := []string{ + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING.Id, + model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER.Id, + } + permissionsEnvironmentWrite := []string{ + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING.Id, + model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER.Id, + } + + // Give the new subsection READ permissions to any user with READ_ENVIRONMENT + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id), + Add: permissionsEnvironmentRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_ENVIRONMENT + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id), + Add: permissionsEnvironmentWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id}, + }) + + // Give these ancillary permissions to anyone with READ_ENVIRONMENT_ELASTICSEARCH + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id), + Add: []string{ + model.PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB.Id, + model.PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB.Id, + }, + }) + + // Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_WEB_SERVER + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER.Id), + Add: []string{ + model.PERMISSION_TEST_SITE_URL.Id, + model.PERMISSION_RELOAD_CONFIG.Id, + model.PERMISSION_INVALIDATE_CACHES.Id, + }, + }) + + // Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_DATABASE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE.Id), + Add: []string{model.PERMISSION_RECYCLE_DATABASE_CONNECTIONS.Id}, + }) + + // Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_ELASTICSEARCH + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH.Id), + Add: []string{ + model.PERMISSION_TEST_ELASTICSEARCH.Id, + model.PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB.Id, + model.PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB.Id, + model.PERMISSION_PURGE_ELASTICSEARCH_INDEXES.Id, + }, + }) + + // Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_FILE_STORAGE + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE.Id), + Add: []string{model.PERMISSION_TEST_S3.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddAboutSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsAboutRead := []string{model.PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id} + permissionsAboutWrite := []string{model.PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE.Id} + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_ABOUT.Id), + Add: permissionsAboutRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_ABOUT.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT.Id), + Add: permissionsAboutWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_ABOUT.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id), + Add: []string{model.PERMISSION_READ_LICENSE_INFORMATION.Id}, + }) + + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE.Id), + Add: []string{model.PERMISSION_MANAGE_LICENSE_INFORMATION.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddReportingSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsReportingRead := []string{ + model.PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id, + model.PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id, + model.PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id, + } + permissionsReportingWrite := []string{ + model.PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS.Id, + model.PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS.Id, + model.PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS.Id, + } + + // Give the new subsection READ permissions to any user with READ_REPORTING + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_REPORTING.Id), + Add: permissionsReportingRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_REPORTING.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_REPORTING + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_REPORTING.Id), + Add: permissionsReportingWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_REPORTING.Id}, + }) + + // Give the ancillary permissions PERMISSION_GET_ANALYTICS to anyone with PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS or PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS + transformations = append(transformations, permissionTransformation{ + On: permissionOr(permissionExists(model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id), permissionExists(model.PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id)), + Add: []string{model.PERMISSION_GET_ANALYTICS.Id}, + }) + + // Give the ancillary permissions PERMISSION_GET_LOGS to anyone with PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id), + Add: []string{model.PERMISSION_GET_LOGS.Id}, + }) + + return transformations, nil +} + +func (a *App) getAddAuthenticationSubsectionPermissions() (permissionsMap, error) { + transformations := []permissionTransformation{} + + permissionsAuthenticationRead := []string{model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id, model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id} + permissionsAuthenticationWrite := []string{model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID.Id, model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS.Id} + + // Give the new subsection READ permissions to any user with READ_AUTHENTICATION + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id), + Add: permissionsAuthenticationRead, + Remove: []string{model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id}, + }) + + // Give the new subsection WRITE permissions to any user with WRITE_AUTHENTICATION + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION.Id), + Add: permissionsAuthenticationWrite, + Remove: []string{model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION.Id}, + }) + + // Give the ancillary permissions for LDAP to anyone with WRITE_AUTHENTICATION_LDAP + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP.Id), + Add: []string{model.PERMISSION_CREATE_LDAP_SYNC_JOB.Id, model.PERMISSION_TEST_LDAP.Id, model.PERMISSION_ADD_LDAP_PUBLIC_CERT.Id, model.PERMISSION_ADD_LDAP_PRIVATE_CERT.Id, model.PERMISSION_REMOVE_LDAP_PUBLIC_CERT.Id, model.PERMISSION_REMOVE_LDAP_PRIVATE_CERT.Id}, + }) + + // Give the ancillary permissions PERMISSION_TEST_LDAP to anyone with READ_AUTHENTICATION_LDAP + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id), + Add: []string{model.PERMISSION_READ_LDAP_SYNC_JOB.Id}, + }) + + // Give the ancillary permissions PERMISSION_INVALIDATE_EMAIL_INVITE to anyone with WRITE_AUTHENTICATION_EMAIL + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL.Id), + Add: []string{model.PERMISSION_INVALIDATE_EMAIL_INVITE.Id}, + }) + + // Give the ancillary permissions for SAML to anyone with WRITE_AUTHENTICATION_SAML + transformations = append(transformations, permissionTransformation{ + On: permissionExists(model.PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML.Id), + Add: []string{model.PERMISSION_GET_SAML_METADATA_FROM_IDP.Id, model.PERMISSION_ADD_SAML_PUBLIC_CERT.Id, model.PERMISSION_ADD_SAML_PRIVATE_CERT.Id, model.PERMISSION_ADD_SAML_IDP_CERT.Id, model.PERMISSION_REMOVE_SAML_PUBLIC_CERT.Id, model.PERMISSION_REMOVE_SAML_PRIVATE_CERT.Id, model.PERMISSION_REMOVE_SAML_IDP_CERT.Id, model.PERMISSION_GET_SAML_CERT_STATUS.Id}, + }) + + return transformations, nil +} + // DoPermissionsMigrations execute all the permissions migrations need by the current version. func (a *App) DoPermissionsMigrations() error { PermissionsMigrations := []struct { @@ -586,6 +930,14 @@ func (a *App) DoPermissionsMigrations() error { {Key: model.MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS, Migration: a.getSystemRolesPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_BILLING_PERMISSIONS, Migration: a.getBillingPermissionsMigration}, {Key: model.MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS, Migration: a.getAddDownloadComplianceExportResult}, + {Key: model.MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS, Migration: a.getAddExperimentalSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_AUTHENTICATION_SUBSECTION_PERMISSIONS, Migration: a.getAddAuthenticationSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS, Migration: a.getAddIntegrationsSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_SITE_SUBSECTION_PERMISSIONS, Migration: a.getAddSiteSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_COMPLIANCE_SUBSECTION_PERMISSIONS, Migration: a.getAddComplianceSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_ENVIRONMENT_SUBSECTION_PERMISSIONS, Migration: a.getAddEnvironmentSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS, Migration: a.getAddAboutSubsectionPermissions}, + {Key: model.MIGRATION_KEY_ADD_REPORTING_SUBSECTION_PERMISSIONS, Migration: a.getAddReportingSubsectionPermissions}, } roles, err := a.GetAllRoles() diff --git a/config/environment.go b/config/environment.go index 092cee52ed..7adaa2de74 100644 --- a/config/environment.go +++ b/config/environment.go @@ -89,12 +89,12 @@ func applyEnvironmentMap(inputConfig *model.Config, env map[string]string) *mode // generateEnvironmentMap creates a map[string]interface{} containing true at the leaves mirroring the // configuration structure so the client can know which env variables are overridden -func generateEnvironmentMap(env map[string]string) map[string]interface{} { +func generateEnvironmentMap(env map[string]string, filter func(reflect.StructField) bool) map[string]interface{} { rType := reflect.TypeOf(model.Config{}) - return generateEnvironmentMapWithBaseKey(env, rType, "MM") + return generateEnvironmentMapWithBaseKey(env, rType, "MM", filter) } -func generateEnvironmentMapWithBaseKey(env map[string]string, rType reflect.Type, base string) map[string]interface{} { +func generateEnvironmentMapWithBaseKey(env map[string]string, rType reflect.Type, base string, filter func(reflect.StructField) bool) map[string]interface{} { if rType.Kind() != reflect.Struct { return nil } @@ -102,8 +102,11 @@ func generateEnvironmentMapWithBaseKey(env map[string]string, rType reflect.Type mapRepresentation := make(map[string]interface{}) for i := 0; i < rType.NumField(); i++ { rField := rType.Field(i) + if filter != nil && !filter(rField) { + continue + } if rField.Type.Kind() == reflect.Struct { - if val := generateEnvironmentMapWithBaseKey(env, rField.Type, base+"_"+rField.Name); val != nil { + if val := generateEnvironmentMapWithBaseKey(env, rField.Type, base+"_"+rField.Name, filter); val != nil { mapRepresentation[rField.Name] = val } } else { diff --git a/config/store.go b/config/store.go index 539103a0eb..d96db5ec45 100644 --- a/config/store.go +++ b/config/store.go @@ -6,6 +6,7 @@ package config import ( "bytes" "encoding/json" + "reflect" "sync" "github.com/pkg/errors" @@ -140,7 +141,13 @@ func (s *Store) GetNoEnv() *model.Config { // GetEnvironmentOverrides fetches the configuration fields overridden by environment variables. func (s *Store) GetEnvironmentOverrides() map[string]interface{} { - return generateEnvironmentMap(GetEnvironment()) + return generateEnvironmentMap(GetEnvironment(), nil) +} + +// GetEnvironmentOverridesWithFilter fetches the configuration fields overridden by environment variables. +// If filter is not nil and returns false for a struct field, that field will be omitted. +func (s *Store) GetEnvironmentOverridesWithFilter(filter func(reflect.StructField) bool) map[string]interface{} { + return generateEnvironmentMap(GetEnvironment(), filter) } // RemoveEnvironmentOverrides returns a new config without the environment diff --git a/i18n/en.json b/i18n/en.json index 4dacee5e8e..fc932eb3de 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1908,6 +1908,14 @@ "id": "api.io_error", "translation": "input/output error" }, + { + "id": "api.job.retrieve.nopermissions", + "translation": "The job types of a job you are trying to retrieve does not contain permissions" + }, + { + "id": "api.job.unable_to_create_job.incorrect_job_type", + "translation": "The job type of the job you are trying to create is invalid" + }, { "id": "api.job.unable_to_download_job", "translation": "Unable to download this job" diff --git a/model/config.go b/model/config.go index 5a06ed5ba3..9c605944bc 100644 --- a/model/config.go +++ b/model/config.go @@ -272,108 +272,108 @@ var ServerTLSSupportedCiphers = map[string]uint16{ } type ServiceSettings struct { - SiteURL *string `access:"environment,authentication,write_restrictable"` + SiteURL *string `access:"environment_web_server,authentication_saml,write_restrictable"` WebsocketURL *string `access:"write_restrictable,cloud_restrictable"` - LicenseFileLocation *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none - ListenAddress *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - ConnectionSecurity *string `access:"environment,write_restrictable,cloud_restrictable"` - TLSCertFile *string `access:"environment,write_restrictable,cloud_restrictable"` - TLSKeyFile *string `access:"environment,write_restrictable,cloud_restrictable"` + LicenseFileLocation *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none + ListenAddress *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` // telemetry: none + ConnectionSecurity *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` + TLSCertFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` + TLSKeyFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` TLSMinVer *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none TLSStrictTransport *bool `access:"write_restrictable,cloud_restrictable"` TLSStrictTransportMaxAge *int64 `access:"write_restrictable,cloud_restrictable"` // telemetry: none TLSOverwriteCiphers []string `access:"write_restrictable,cloud_restrictable"` // telemetry: none - UseLetsEncrypt *bool `access:"environment,write_restrictable,cloud_restrictable"` - LetsEncryptCertificateCacheFile *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - Forward80To443 *bool `access:"environment,write_restrictable,cloud_restrictable"` + UseLetsEncrypt *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"` + LetsEncryptCertificateCacheFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` // telemetry: none + Forward80To443 *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"` TrustedProxyIPHeader []string `access:"write_restrictable,cloud_restrictable"` // telemetry: none - ReadTimeout *int `access:"environment,write_restrictable,cloud_restrictable"` - WriteTimeout *int `access:"environment,write_restrictable,cloud_restrictable"` + ReadTimeout *int `access:"environment_web_server,write_restrictable,cloud_restrictable"` + WriteTimeout *int `access:"environment_web_server,write_restrictable,cloud_restrictable"` IdleTimeout *int `access:"write_restrictable,cloud_restrictable"` - MaximumLoginAttempts *int `access:"authentication,write_restrictable,cloud_restrictable"` + MaximumLoginAttempts *int `access:"authentication_password,write_restrictable,cloud_restrictable"` GoroutineHealthThreshold *int `access:"write_restrictable,cloud_restrictable"` // telemetry: none - GoogleDeveloperKey *string `access:"site,write_restrictable,cloud_restrictable"` - EnableOAuthServiceProvider *bool `access:"integrations"` - EnableIncomingWebhooks *bool `access:"integrations"` - EnableOutgoingWebhooks *bool `access:"integrations"` - EnableCommands *bool `access:"integrations"` + EnableOAuthServiceProvider *bool `access:"integrations_integration_management"` + EnableIncomingWebhooks *bool `access:"integrations_integration_management"` + EnableOutgoingWebhooks *bool `access:"integrations_integration_management"` + EnableCommands *bool `access:"integrations_integration_management"` + EnablePostUsernameOverride *bool `access:"integrations_integration_management"` + EnablePostIconOverride *bool `access:"integrations_integration_management"` + GoogleDeveloperKey *string `access:"site_posts,write_restrictable,cloud_restrictable"` DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations *bool `json:"EnableOnlyAdminIntegrations" mapstructure:"EnableOnlyAdminIntegrations"` // Deprecated: do not use - EnablePostUsernameOverride *bool `access:"integrations"` - EnablePostIconOverride *bool `access:"integrations"` - EnableLinkPreviews *bool `access:"site"` - RestrictLinkPreviews *string `access:"site"` - EnableTesting *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableDeveloper *bool `access:"environment,write_restrictable,cloud_restrictable"` + EnableLinkPreviews *bool `access:"site_posts"` + RestrictLinkPreviews *string `access:"site_posts"` + EnableTesting *bool `access:"environment_developer,write_restrictable,cloud_restrictable"` + EnableDeveloper *bool `access:"environment_developer,write_restrictable,cloud_restrictable"` EnableOpenTracing *bool `access:"write_restrictable,cloud_restrictable"` - EnableSecurityFixAlert *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableInsecureOutgoingConnections *bool `access:"environment,write_restrictable,cloud_restrictable"` - AllowedUntrustedInternalConnections *string `access:"environment,write_restrictable,cloud_restrictable"` - EnableMultifactorAuthentication *bool `access:"authentication"` - EnforceMultifactorAuthentication *bool `access:"authentication"` - EnableUserAccessTokens *bool `access:"integrations"` - AllowCorsFrom *string `access:"integrations,write_restrictable,cloud_restrictable"` - CorsExposedHeaders *string `access:"integrations,write_restrictable,cloud_restrictable"` - CorsAllowCredentials *bool `access:"integrations,write_restrictable,cloud_restrictable"` - CorsDebug *bool `access:"integrations,write_restrictable,cloud_restrictable"` + EnableSecurityFixAlert *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"` + EnableInsecureOutgoingConnections *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"` + AllowedUntrustedInternalConnections *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` + EnableMultifactorAuthentication *bool `access:"authentication_mfa"` + EnforceMultifactorAuthentication *bool `access:"authentication_mfa"` + EnableUserAccessTokens *bool `access:"integrations_integration_management"` + AllowCorsFrom *string `access:"integrations_cors,write_restrictable,cloud_restrictable"` + CorsExposedHeaders *string `access:"integrations_cors,write_restrictable,cloud_restrictable"` + CorsAllowCredentials *bool `access:"integrations_cors,write_restrictable,cloud_restrictable"` + CorsDebug *bool `access:"integrations_cors,write_restrictable,cloud_restrictable"` AllowCookiesForSubdomains *bool `access:"write_restrictable,cloud_restrictable"` - ExtendSessionLengthWithActivity *bool `access:"environment,write_restrictable,cloud_restrictable"` - SessionLengthWebInDays *int `access:"environment,write_restrictable,cloud_restrictable"` - SessionLengthMobileInDays *int `access:"environment,write_restrictable,cloud_restrictable"` - SessionLengthSSOInDays *int `access:"environment,write_restrictable,cloud_restrictable"` - SessionCacheInMinutes *int `access:"environment,write_restrictable,cloud_restrictable"` - SessionIdleTimeoutInMinutes *int `access:"environment,write_restrictable,cloud_restrictable"` + ExtendSessionLengthWithActivity *bool `access:"environment_session_lengths,write_restrictable,cloud_restrictable"` + SessionLengthWebInDays *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"` + SessionLengthMobileInDays *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"` + SessionLengthSSOInDays *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"` + SessionCacheInMinutes *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"` + SessionIdleTimeoutInMinutes *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"` WebsocketSecurePort *int `access:"write_restrictable,cloud_restrictable"` // telemetry: none WebsocketPort *int `access:"write_restrictable,cloud_restrictable"` // telemetry: none - WebserverMode *string `access:"environment,write_restrictable,cloud_restrictable"` - EnableCustomEmoji *bool `access:"site"` - EnableEmojiPicker *bool `access:"site"` - EnableGifPicker *bool `access:"integrations"` - GfycatApiKey *string `access:"integrations"` - GfycatApiSecret *string `access:"integrations"` + WebserverMode *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` + EnableGifPicker *bool `access:"integrations_gif"` + GfycatApiKey *string `access:"integrations_gif"` + GfycatApiSecret *string `access:"integrations_gif"` + EnableCustomEmoji *bool `access:"site_emoji"` + EnableEmojiPicker *bool `access:"site_emoji"` DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation *string `json:"RestrictCustomEmojiCreation" mapstructure:"RestrictCustomEmojiCreation"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_RestrictPostDelete *string `json:"RestrictPostDelete" mapstructure:"RestrictPostDelete"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_AllowEditPost *string `json:"AllowEditPost" mapstructure:"AllowEditPost"` // Deprecated: do not use PostEditTimeLimit *int `access:"user_management_permissions"` - TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"experimental,write_restrictable,cloud_restrictable"` + TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"` EnablePostSearch *bool `access:"write_restrictable,cloud_restrictable"` EnableFileSearch *bool `access:"write_restrictable"` - MinimumHashtagLength *int `access:"environment,write_restrictable,cloud_restrictable"` - EnableUserTypingMessages *bool `access:"experimental,write_restrictable,cloud_restrictable"` - EnableChannelViewedMessages *bool `access:"experimental,write_restrictable,cloud_restrictable"` + MinimumHashtagLength *int `access:"environment_database,write_restrictable,cloud_restrictable"` + EnableUserTypingMessages *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` + EnableChannelViewedMessages *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` EnableUserStatuses *bool `access:"write_restrictable,cloud_restrictable"` - ExperimentalEnableAuthenticationTransfer *bool `access:"experimental,write_restrictable,cloud_restrictable"` + ExperimentalEnableAuthenticationTransfer *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` ClusterLogTimeoutMilliseconds *int `access:"write_restrictable,cloud_restrictable"` - CloseUnusedDirectMessages *bool `access:"experimental"` - EnablePreviewFeatures *bool `access:"experimental"` - EnableTutorial *bool `access:"experimental"` - ExperimentalEnableDefaultChannelLeaveJoinMessages *bool `access:"experimental"` - ExperimentalGroupUnreadChannels *string `access:"experimental"` - ExperimentalChannelOrganization *bool `access:"experimental"` + CloseUnusedDirectMessages *bool `access:"experimental_features"` + EnablePreviewFeatures *bool `access:"experimental_features"` + EnableTutorial *bool `access:"experimental_features"` + ExperimentalEnableDefaultChannelLeaveJoinMessages *bool `access:"experimental_features"` + ExperimentalGroupUnreadChannels *string `access:"experimental_features"` + ExperimentalChannelOrganization *bool `access:"experimental_features"` DEPRECATED_DO_NOT_USE_ImageProxyType *string `json:"ImageProxyType" mapstructure:"ImageProxyType"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_ImageProxyURL *string `json:"ImageProxyURL" mapstructure:"ImageProxyURL"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_ImageProxyOptions *string `json:"ImageProxyOptions" mapstructure:"ImageProxyOptions"` // Deprecated: do not use EnableAPITeamDeletion *bool EnableAPIUserDeletion *bool - ExperimentalEnableHardenedMode *bool `access:"experimental"` + ExperimentalEnableHardenedMode *bool `access:"experimental_features"` DisableLegacyMFA *bool `access:"write_restrictable,cloud_restrictable"` - ExperimentalStrictCSRFEnforcement *bool `access:"experimental,write_restrictable,cloud_restrictable"` - EnableEmailInvitations *bool `access:"authentication"` - DisableBotsWhenOwnerIsDeactivated *bool `access:"integrations,write_restrictable,cloud_restrictable"` - EnableBotAccountCreation *bool `access:"integrations"` - EnableSVGs *bool `access:"site"` - EnableLatex *bool `access:"site"` + ExperimentalStrictCSRFEnforcement *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` + EnableEmailInvitations *bool `access:"authentication_signup"` + DisableBotsWhenOwnerIsDeactivated *bool `access:"integrations_bot_accounts,write_restrictable,cloud_restrictable"` + EnableBotAccountCreation *bool `access:"integrations_bot_accounts"` + EnableSVGs *bool `access:"site_posts"` + EnableLatex *bool `access:"site_posts"` EnableAPIChannelDeletion *bool EnableLocalMode *bool LocalModeSocketLocation *string // telemetry: none EnableAWSMetering *bool // telemetry: none - SplitKey *string `access:"environment,write_restrictable"` // telemetry: none - FeatureFlagSyncIntervalSeconds *int `access:"environment,write_restrictable"` // telemetry: none - DebugSplit *bool `access:"environment,write_restrictable"` // telemetry: none - ThreadAutoFollow *bool `access:"experimental"` - CollapsedThreads *string `access:"experimental"` - ManagedResourcePaths *string `access:"environment,write_restrictable,cloud_restrictable"` - EnableLegacySidebar *bool `access:"experimental"` - EnableReliableWebSockets *bool `access:"experimental"` // telemetry: none + SplitKey *string `access:"experimental_feature_flags,write_restrictable"` // telemetry: none + FeatureFlagSyncIntervalSeconds *int `access:"experimental_feature_flags,write_restrictable"` // telemetry: none + DebugSplit *bool `access:"experimental_feature_flags,write_restrictable"` // telemetry: none + ThreadAutoFollow *bool `access:"experimental_features"` + CollapsedThreads *string `access:"experimental_features"` + ManagedResourcePaths *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` + EnableLegacySidebar *bool `access:"experimental_features"` + EnableReliableWebSockets *bool `access:"experimental_features"` // telemetry: none } func (s *ServiceSettings) SetDefaults(isUpdate bool) { @@ -826,22 +826,22 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) { } type ClusterSettings struct { - Enable *bool `access:"environment,write_restrictable"` - ClusterName *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - OverrideHostname *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - NetworkInterface *string `access:"environment,write_restrictable,cloud_restrictable"` - BindAddress *string `access:"environment,write_restrictable,cloud_restrictable"` - AdvertiseAddress *string `access:"environment,write_restrictable,cloud_restrictable"` - UseIpAddress *bool `access:"environment,write_restrictable,cloud_restrictable"` - UseExperimentalGossip *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableGossipCompression *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableExperimentalGossipEncryption *bool `access:"environment,write_restrictable,cloud_restrictable"` - ReadOnlyConfig *bool `access:"environment,write_restrictable,cloud_restrictable"` - GossipPort *int `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - StreamingPort *int `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - MaxIdleConns *int `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - MaxIdleConnsPerHost *int `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - IdleConnTimeoutMilliseconds *int `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none + Enable *bool `access:"environment_high_availability,write_restrictable"` + ClusterName *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none + OverrideHostname *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none + NetworkInterface *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + BindAddress *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + AdvertiseAddress *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + UseIpAddress *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + UseExperimentalGossip *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + EnableGossipCompression *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + EnableExperimentalGossipEncryption *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + ReadOnlyConfig *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"` + GossipPort *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none + StreamingPort *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none + MaxIdleConns *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none + MaxIdleConnsPerHost *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none + IdleConnTimeoutMilliseconds *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none } func (s *ClusterSettings) SetDefaults() { @@ -911,9 +911,9 @@ func (s *ClusterSettings) SetDefaults() { } type MetricsSettings struct { - Enable *bool `access:"environment,write_restrictable,cloud_restrictable"` - BlockProfileRate *int `access:"environment,write_restrictable,cloud_restrictable"` - ListenAddress *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none + Enable *bool `access:"environment_performance_monitoring,write_restrictable,cloud_restrictable"` + BlockProfileRate *int `access:"environment_performance_monitoring,write_restrictable,cloud_restrictable"` + ListenAddress *string `access:"environment_performance_monitoring,write_restrictable,cloud_restrictable"` // telemetry: none } func (s *MetricsSettings) SetDefaults() { @@ -931,16 +931,16 @@ func (s *MetricsSettings) SetDefaults() { } type ExperimentalSettings struct { - ClientSideCertEnable *bool `access:"experimental,cloud_restrictable"` - ClientSideCertCheck *string `access:"experimental,cloud_restrictable"` - EnableClickToReply *bool `access:"experimental,write_restrictable,cloud_restrictable"` - LinkMetadataTimeoutMilliseconds *int64 `access:"experimental,write_restrictable,cloud_restrictable"` - RestrictSystemAdmin *bool `access:"experimental,write_restrictable"` - UseNewSAMLLibrary *bool `access:"experimental,cloud_restrictable"` - CloudUserLimit *int64 `access:"experimental,write_restrictable"` - CloudBilling *bool `access:"experimental,write_restrictable"` - EnableSharedChannels *bool `access:"experimental"` - EnableRemoteClusterService *bool `access:"experimental"` + ClientSideCertEnable *bool `access:"experimental_features,cloud_restrictable"` + ClientSideCertCheck *string `access:"experimental_features,cloud_restrictable"` + EnableClickToReply *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` + LinkMetadataTimeoutMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"` + RestrictSystemAdmin *bool `access:"experimental_features,write_restrictable"` + UseNewSAMLLibrary *bool `access:"experimental_features,cloud_restrictable"` + CloudUserLimit *int64 `access:"experimental_features,write_restrictable"` + CloudBilling *bool `access:"experimental_features,write_restrictable"` + EnableSharedChannels *bool `access:"experimental_features"` + EnableRemoteClusterService *bool `access:"experimental_features"` } func (s *ExperimentalSettings) SetDefaults() { @@ -997,16 +997,16 @@ func (s *AnalyticsSettings) SetDefaults() { } type SSOSettings struct { - Enable *bool `access:"authentication"` - Secret *string `access:"authentication"` // telemetry: none - Id *string `access:"authentication"` // telemetry: none - Scope *string `access:"authentication"` // telemetry: none - AuthEndpoint *string `access:"authentication"` // telemetry: none - TokenEndpoint *string `access:"authentication"` // telemetry: none - UserApiEndpoint *string `access:"authentication"` // telemetry: none - DiscoveryEndpoint *string `access:"authentication"` // telemetry: none - ButtonText *string `access:"authentication"` // telemetry: none - ButtonColor *string `access:"authentication"` // telemetry: none + Enable *bool `access:"authentication_openid"` + Secret *string `access:"authentication_openid"` // telemetry: none + Id *string `access:"authentication_openid"` // telemetry: none + Scope *string `access:"authentication_openid"` // telemetry: none + AuthEndpoint *string `access:"authentication_openid"` // telemetry: none + TokenEndpoint *string `access:"authentication_openid"` // telemetry: none + UserApiEndpoint *string `access:"authentication_openid"` // telemetry: none + DiscoveryEndpoint *string `access:"authentication_openid"` // telemetry: none + ButtonText *string `access:"authentication_openid"` // telemetry: none + ButtonColor *string `access:"authentication_openid"` // telemetry: none } func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEndpoint, buttonColor string) { @@ -1052,15 +1052,15 @@ func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEnd } type Office365Settings struct { - Enable *bool `access:"authentication"` - Secret *string `access:"authentication"` // telemetry: none - Id *string `access:"authentication"` // telemetry: none - Scope *string `access:"authentication"` - AuthEndpoint *string `access:"authentication"` // telemetry: none - TokenEndpoint *string `access:"authentication"` // telemetry: none - UserApiEndpoint *string `access:"authentication"` // telemetry: none - DiscoveryEndpoint *string `access:"authentication"` // telemetry: none - DirectoryId *string `access:"authentication"` // telemetry: none + Enable *bool `access:"authentication_openid"` + Secret *string `access:"authentication_openid"` // telemetry: none + Id *string `access:"authentication_openid"` // telemetry: none + Scope *string `access:"authentication_openid"` + AuthEndpoint *string `access:"authentication_openid"` // telemetry: none + TokenEndpoint *string `access:"authentication_openid"` // telemetry: none + UserApiEndpoint *string `access:"authentication_openid"` // telemetry: none + DiscoveryEndpoint *string `access:"authentication_openid"` // telemetry: none + DirectoryId *string `access:"authentication_openid"` // telemetry: none } func (s *Office365Settings) setDefaults() { @@ -1121,19 +1121,19 @@ type ReplicaLagSettings struct { } type SqlSettings struct { - DriverName *string `access:"environment,write_restrictable,cloud_restrictable"` - DataSource *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - DataSourceReplicas []string `access:"environment,write_restrictable,cloud_restrictable"` - DataSourceSearchReplicas []string `access:"environment,write_restrictable,cloud_restrictable"` - MaxIdleConns *int `access:"environment,write_restrictable,cloud_restrictable"` - ConnMaxLifetimeMilliseconds *int `access:"environment,write_restrictable,cloud_restrictable"` - ConnMaxIdleTimeMilliseconds *int `access:"environment,write_restrictable,cloud_restrictable"` - MaxOpenConns *int `access:"environment,write_restrictable,cloud_restrictable"` - Trace *bool `access:"environment,write_restrictable,cloud_restrictable"` - AtRestEncryptKey *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - QueryTimeout *int `access:"environment,write_restrictable,cloud_restrictable"` - DisableDatabaseSearch *bool `access:"environment,write_restrictable,cloud_restrictable"` - ReplicaLagSettings []*ReplicaLagSettings `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none + DriverName *string `access:"environment_database,write_restrictable,cloud_restrictable"` + DataSource *string `access:"environment_database,write_restrictable,cloud_restrictable"` // telemetry: none + DataSourceReplicas []string `access:"environment_database,write_restrictable,cloud_restrictable"` + DataSourceSearchReplicas []string `access:"environment_database,write_restrictable,cloud_restrictable"` + MaxIdleConns *int `access:"environment_database,write_restrictable,cloud_restrictable"` + ConnMaxLifetimeMilliseconds *int `access:"environment_database,write_restrictable,cloud_restrictable"` + ConnMaxIdleTimeMilliseconds *int `access:"environment_database,write_restrictable,cloud_restrictable"` + MaxOpenConns *int `access:"environment_database,write_restrictable,cloud_restrictable"` + Trace *bool `access:"environment_database,write_restrictable,cloud_restrictable"` + AtRestEncryptKey *string `access:"environment_database,write_restrictable,cloud_restrictable"` // telemetry: none + QueryTimeout *int `access:"environment_database,write_restrictable,cloud_restrictable"` + DisableDatabaseSearch *bool `access:"environment_database,write_restrictable,cloud_restrictable"` + ReplicaLagSettings []*ReplicaLagSettings `access:"environment_database,write_restrictable,cloud_restrictable"` // telemetry: none } func (s *SqlSettings) SetDefaults(isUpdate bool) { @@ -1197,17 +1197,17 @@ func (s *SqlSettings) SetDefaults(isUpdate bool) { } type LogSettings struct { - EnableConsole *bool `access:"environment,write_restrictable,cloud_restrictable"` - ConsoleLevel *string `access:"environment,write_restrictable,cloud_restrictable"` - ConsoleJson *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableFile *bool `access:"environment,write_restrictable,cloud_restrictable"` - FileLevel *string `access:"environment,write_restrictable,cloud_restrictable"` - FileJson *bool `access:"environment,write_restrictable,cloud_restrictable"` - FileLocation *string `access:"environment,write_restrictable,cloud_restrictable"` - EnableWebhookDebugging *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableDiagnostics *bool `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - EnableSentry *bool `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AdvancedLoggingConfig *string `access:"environment,write_restrictable,cloud_restrictable"` + EnableConsole *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` + ConsoleLevel *string `access:"environment_logging,write_restrictable,cloud_restrictable"` + ConsoleJson *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` + EnableFile *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` + FileLevel *string `access:"environment_logging,write_restrictable,cloud_restrictable"` + FileJson *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` + FileLocation *string `access:"environment_logging,write_restrictable,cloud_restrictable"` + EnableWebhookDebugging *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` + EnableDiagnostics *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` // telemetry: none + EnableSentry *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` // telemetry: none + AdvancedLoggingConfig *string `access:"environment_logging,write_restrictable,cloud_restrictable"` } func (s *LogSettings) SetDefaults() { @@ -1257,14 +1257,14 @@ func (s *LogSettings) SetDefaults() { } type ExperimentalAuditSettings struct { - FileEnabled *bool `access:"experimental,write_restrictable,cloud_restrictable"` - FileName *string `access:"experimental,write_restrictable,cloud_restrictable"` // telemetry: none - FileMaxSizeMB *int `access:"experimental,write_restrictable,cloud_restrictable"` - FileMaxAgeDays *int `access:"experimental,write_restrictable,cloud_restrictable"` - FileMaxBackups *int `access:"experimental,write_restrictable,cloud_restrictable"` - FileCompress *bool `access:"experimental,write_restrictable,cloud_restrictable"` - FileMaxQueueSize *int `access:"experimental,write_restrictable,cloud_restrictable"` - AdvancedLoggingConfig *string `access:"experimental,write_restrictable,cloud_restrictable"` + FileEnabled *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` + FileName *string `access:"experimental_features,write_restrictable,cloud_restrictable"` // telemetry: none + FileMaxSizeMB *int `access:"experimental_features,write_restrictable,cloud_restrictable"` + FileMaxAgeDays *int `access:"experimental_features,write_restrictable,cloud_restrictable"` + FileMaxBackups *int `access:"experimental_features,write_restrictable,cloud_restrictable"` + FileCompress *bool `access:"experimental_features,write_restrictable,cloud_restrictable"` + FileMaxQueueSize *int `access:"experimental_features,write_restrictable,cloud_restrictable"` + AdvancedLoggingConfig *string `access:"experimental_features,write_restrictable,cloud_restrictable"` } func (s *ExperimentalAuditSettings) SetDefaults() { @@ -1347,11 +1347,11 @@ func (s *NotificationLogSettings) SetDefaults() { } type PasswordSettings struct { - MinimumLength *int `access:"authentication"` - Lowercase *bool `access:"authentication"` - Number *bool `access:"authentication"` - Uppercase *bool `access:"authentication"` - Symbol *bool `access:"authentication"` + MinimumLength *int `access:"authentication_password"` + Lowercase *bool `access:"authentication_password"` + Number *bool `access:"authentication_password"` + Uppercase *bool `access:"authentication_password"` + Symbol *bool `access:"authentication_password"` } func (s *PasswordSettings) SetDefaults() { @@ -1377,27 +1377,27 @@ func (s *PasswordSettings) SetDefaults() { } type FileSettings struct { - EnableFileAttachments *bool `access:"site,cloud_restrictable"` - EnableMobileUpload *bool `access:"site,cloud_restrictable"` - EnableMobileDownload *bool `access:"site,cloud_restrictable"` - MaxFileSize *int64 `access:"environment,cloud_restrictable"` - DriverName *string `access:"environment,write_restrictable,cloud_restrictable"` - Directory *string `access:"environment,write_restrictable,cloud_restrictable"` - EnablePublicLink *bool `access:"site,cloud_restrictable"` - ExtractContent *bool `access:"environment,write_restrictable"` - ArchiveRecursion *bool `access:"environment,write_restrictable"` - PublicLinkSalt *string `access:"site,cloud_restrictable"` // telemetry: none - InitialFont *string `access:"environment,cloud_restrictable"` // telemetry: none - AmazonS3AccessKeyId *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AmazonS3SecretAccessKey *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AmazonS3Bucket *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AmazonS3PathPrefix *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AmazonS3Region *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AmazonS3Endpoint *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - AmazonS3SSL *bool `access:"environment,write_restrictable,cloud_restrictable"` - AmazonS3SignV2 *bool `access:"environment,write_restrictable,cloud_restrictable"` - AmazonS3SSE *bool `access:"environment,write_restrictable,cloud_restrictable"` - AmazonS3Trace *bool `access:"environment,write_restrictable,cloud_restrictable"` + EnableFileAttachments *bool `access:"site_file_sharing_and_downloads,cloud_restrictable"` + EnableMobileUpload *bool `access:"site_file_sharing_and_downloads,cloud_restrictable"` + EnableMobileDownload *bool `access:"site_file_sharing_and_downloads,cloud_restrictable"` + MaxFileSize *int64 `access:"environment_file_storage,cloud_restrictable"` + DriverName *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` + Directory *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` + EnablePublicLink *bool `access:"site_public_links,cloud_restrictable"` + ExtractContent *bool `access:"environment_file_storage,write_restrictable"` + ArchiveRecursion *bool `access:"environment_file_storage,write_restrictable"` + PublicLinkSalt *string `access:"site_public_links,cloud_restrictable"` // telemetry: none + InitialFont *string `access:"environment_file_storage,cloud_restrictable"` // telemetry: none + AmazonS3AccessKeyId *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none + AmazonS3SecretAccessKey *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none + AmazonS3Bucket *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none + AmazonS3PathPrefix *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none + AmazonS3Region *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none + AmazonS3Endpoint *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none + AmazonS3SSL *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"` + AmazonS3SignV2 *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"` + AmazonS3SSE *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"` + AmazonS3Trace *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"` } func (s *FileSettings) SetDefaults(isUpdate bool) { @@ -1518,36 +1518,36 @@ func (s *FileSettings) ToFileBackendSettings(enableComplianceFeature bool) files } type EmailSettings struct { - EnableSignUpWithEmail *bool `access:"authentication"` - EnableSignInWithEmail *bool `access:"authentication"` - EnableSignInWithUsername *bool `access:"authentication"` - SendEmailNotifications *bool `access:"site"` - UseChannelInEmailNotifications *bool `access:"experimental"` - RequireEmailVerification *bool `access:"authentication"` - FeedbackName *string `access:"site"` - FeedbackEmail *string `access:"site,cloud_restrictable"` - ReplyToAddress *string `access:"site,cloud_restrictable"` - FeedbackOrganization *string `access:"site"` - EnableSMTPAuth *bool `access:"environment,write_restrictable,cloud_restrictable"` - SMTPUsername *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - SMTPPassword *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - SMTPServer *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - SMTPPort *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none + EnableSignUpWithEmail *bool `access:"authentication_email"` + EnableSignInWithEmail *bool `access:"authentication_email"` + EnableSignInWithUsername *bool `access:"authentication_email"` + SendEmailNotifications *bool `access:"site_notifications"` + UseChannelInEmailNotifications *bool `access:"experimental_features"` + RequireEmailVerification *bool `access:"authentication_email"` + FeedbackName *string `access:"site_notifications"` + FeedbackEmail *string `access:"site_notifications,cloud_restrictable"` + ReplyToAddress *string `access:"site_notifications,cloud_restrictable"` + FeedbackOrganization *string `access:"site_notifications"` + EnableSMTPAuth *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"` + SMTPUsername *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none + SMTPPassword *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none + SMTPServer *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none + SMTPPort *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none SMTPServerTimeout *int `access:"cloud_restrictable"` - ConnectionSecurity *string `access:"environment,write_restrictable,cloud_restrictable"` - SendPushNotifications *bool `access:"environment"` - PushNotificationServer *string `access:"environment"` // telemetry: none - PushNotificationContents *string `access:"site"` + ConnectionSecurity *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` + SendPushNotifications *bool `access:"environment_push_notification_server"` + PushNotificationServer *string `access:"environment_push_notification_server"` // telemetry: none + PushNotificationContents *string `access:"site_notifications"` PushNotificationBuffer *int // telemetry: none - EnableEmailBatching *bool `access:"site"` - EmailBatchingBufferSize *int `access:"experimental"` - EmailBatchingInterval *int `access:"experimental"` - EnablePreviewModeBanner *bool `access:"site"` - SkipServerCertificateVerification *bool `access:"environment,write_restrictable,cloud_restrictable"` - EmailNotificationContentsType *string `access:"site"` - LoginButtonColor *string `access:"experimental"` - LoginButtonBorderColor *string `access:"experimental"` - LoginButtonTextColor *string `access:"experimental"` + EnableEmailBatching *bool `access:"site_notifications"` + EmailBatchingBufferSize *int `access:"experimental_features"` + EmailBatchingInterval *int `access:"experimental_features"` + EnablePreviewModeBanner *bool `access:"site_notifications"` + SkipServerCertificateVerification *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"` + EmailNotificationContentsType *string `access:"site_notifications"` + LoginButtonColor *string `access:"experimental_features"` + LoginButtonBorderColor *string `access:"experimental_features"` + LoginButtonTextColor *string `access:"experimental_features"` } func (s *EmailSettings) SetDefaults(isUpdate bool) { @@ -1693,13 +1693,13 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) { } type RateLimitSettings struct { - Enable *bool `access:"environment,write_restrictable,cloud_restrictable"` - PerSec *int `access:"environment,write_restrictable,cloud_restrictable"` - MaxBurst *int `access:"environment,write_restrictable,cloud_restrictable"` - MemoryStoreSize *int `access:"environment,write_restrictable,cloud_restrictable"` - VaryByRemoteAddr *bool `access:"environment,write_restrictable,cloud_restrictable"` - VaryByUser *bool `access:"environment,write_restrictable,cloud_restrictable"` - VaryByHeader string `access:"environment,write_restrictable,cloud_restrictable"` + Enable *bool `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` + PerSec *int `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` + MaxBurst *int `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` + MemoryStoreSize *int `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` + VaryByRemoteAddr *bool `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` + VaryByUser *bool `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` + VaryByHeader string `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"` } func (s *RateLimitSettings) SetDefaults() { @@ -1729,8 +1729,8 @@ func (s *RateLimitSettings) SetDefaults() { } type PrivacySettings struct { - ShowEmailAddress *bool `access:"site"` - ShowFullName *bool `access:"site"` + ShowEmailAddress *bool `access:"site_users_and_teams"` + ShowFullName *bool `access:"site_users_and_teams"` } func (s *PrivacySettings) setDefaults() { @@ -1744,15 +1744,15 @@ func (s *PrivacySettings) setDefaults() { } type SupportSettings struct { - TermsOfServiceLink *string `access:"site,write_restrictable,cloud_restrictable"` - PrivacyPolicyLink *string `access:"site,write_restrictable,cloud_restrictable"` - AboutLink *string `access:"site,write_restrictable,cloud_restrictable"` - HelpLink *string `access:"site,write_restrictable,cloud_restrictable"` - ReportAProblemLink *string `access:"site,write_restrictable,cloud_restrictable"` - SupportEmail *string `access:"site"` - CustomTermsOfServiceEnabled *bool `access:"compliance"` - CustomTermsOfServiceReAcceptancePeriod *int `access:"compliance"` - EnableAskCommunityLink *bool `access:"site"` + TermsOfServiceLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + PrivacyPolicyLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + AboutLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + HelpLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + ReportAProblemLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + SupportEmail *string `access:"site_customization"` + CustomTermsOfServiceEnabled *bool `access:"compliance_custom_terms_of_service"` + CustomTermsOfServiceReAcceptancePeriod *int `access:"compliance_custom_terms_of_service"` + EnableAskCommunityLink *bool `access:"site_customization"` } func (s *SupportSettings) SetDefaults() { @@ -1814,16 +1814,16 @@ func (s *SupportSettings) SetDefaults() { } type AnnouncementSettings struct { - EnableBanner *bool `access:"site"` - BannerText *string `access:"site"` // telemetry: none - BannerColor *string `access:"site"` - BannerTextColor *string `access:"site"` - AllowBannerDismissal *bool `access:"site"` - AdminNoticesEnabled *bool `access:"site"` - UserNoticesEnabled *bool `access:"site"` - NoticesURL *string `access:"site,write_restrictable"` // telemetry: none - NoticesFetchFrequency *int `access:"site,write_restrictable"` // telemetry: none - NoticesSkipCache *bool `access:"site,write_restrictable"` // telemetry: none + EnableBanner *bool `access:"site_announcement_banner"` + BannerText *string `access:"site_announcement_banner"` // telemetry: none + BannerColor *string `access:"site_announcement_banner"` + BannerTextColor *string `access:"site_announcement_banner"` + AllowBannerDismissal *bool `access:"site_announcement_banner"` + AdminNoticesEnabled *bool `access:"site_notices"` + UserNoticesEnabled *bool `access:"site_notices"` + NoticesURL *string `access:"site_notices,write_restrictable"` // telemetry: none + NoticesFetchFrequency *int `access:"site_notices,write_restrictable"` // telemetry: none + NoticesSkipCache *bool `access:"site_notices,write_restrictable"` // telemetry: none } func (s *AnnouncementSettings) SetDefaults() { @@ -1867,9 +1867,9 @@ func (s *AnnouncementSettings) SetDefaults() { } type ThemeSettings struct { - EnableThemeSelection *bool `access:"experimental"` - DefaultTheme *string `access:"experimental"` - AllowCustomThemes *bool `access:"experimental"` + EnableThemeSelection *bool `access:"experimental_features"` + DefaultTheme *string `access:"experimental_features"` + AllowCustomThemes *bool `access:"experimental_features"` AllowedThemes []string } @@ -1892,18 +1892,18 @@ func (s *ThemeSettings) SetDefaults() { } type TeamSettings struct { - SiteName *string `access:"site"` - MaxUsersPerTeam *int `access:"site"` + SiteName *string `access:"site_customization"` + MaxUsersPerTeam *int `access:"site_users_and_teams"` DEPRECATED_DO_NOT_USE_EnableTeamCreation *bool `json:"EnableTeamCreation" mapstructure:"EnableTeamCreation"` // Deprecated: do not use - EnableUserCreation *bool `access:"authentication"` - EnableOpenServer *bool `access:"authentication"` - EnableUserDeactivation *bool `access:"experimental"` - RestrictCreationToDomains *string `access:"authentication"` // telemetry: none - EnableCustomUserStatuses *bool `access:"site"` - EnableCustomBrand *bool `access:"site"` - CustomBrandText *string `access:"site"` - CustomDescriptionText *string `access:"site"` - RestrictDirectMessage *string `access:"site"` + EnableUserCreation *bool `access:"authentication_signup"` + EnableOpenServer *bool `access:"authentication_signup"` + EnableUserDeactivation *bool `access:"experimental_features"` + RestrictCreationToDomains *string `access:"authentication_signup"` // telemetry: none + EnableCustomUserStatuses *bool `access:"site_users_and_teams"` + EnableCustomBrand *bool `access:"site_customization"` + CustomBrandText *string `access:"site_customization"` + CustomDescriptionText *string `access:"site_customization"` + RestrictDirectMessage *string `access:"site_users_and_teams"` DEPRECATED_DO_NOT_USE_RestrictTeamInvite *string `json:"RestrictTeamInvite" mapstructure:"RestrictTeamInvite"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement *string `json:"RestrictPublicChannelManagement" mapstructure:"RestrictPublicChannelManagement"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement *string `json:"RestrictPrivateChannelManagement" mapstructure:"RestrictPrivateChannelManagement"` // Deprecated: do not use @@ -1912,19 +1912,19 @@ type TeamSettings struct { DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion *string `json:"RestrictPublicChannelDeletion" mapstructure:"RestrictPublicChannelDeletion"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion *string `json:"RestrictPrivateChannelDeletion" mapstructure:"RestrictPrivateChannelDeletion"` // Deprecated: do not use DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers *string `json:"RestrictPrivateChannelManageMembers" mapstructure:"RestrictPrivateChannelManageMembers"` // Deprecated: do not use - EnableXToLeaveChannelsFromLHS *bool `access:"experimental"` - UserStatusAwayTimeout *int64 `access:"experimental"` - MaxChannelsPerTeam *int64 `access:"site"` - MaxNotificationsPerChannel *int64 `access:"environment"` - EnableConfirmNotificationsToChannel *bool `access:"site"` - TeammateNameDisplay *string `access:"site"` - ExperimentalViewArchivedChannels *bool `access:"experimental,site"` - ExperimentalEnableAutomaticReplies *bool `access:"experimental"` - ExperimentalHideTownSquareinLHS *bool `access:"experimental"` - ExperimentalTownSquareIsReadOnly *bool `access:"experimental"` - LockTeammateNameDisplay *bool `access:"site"` - ExperimentalPrimaryTeam *string `access:"experimental"` - ExperimentalDefaultChannels []string `access:"experimental"` + EnableXToLeaveChannelsFromLHS *bool `access:"experimental_features"` + UserStatusAwayTimeout *int64 `access:"experimental_features"` + MaxChannelsPerTeam *int64 `access:"site_users_and_teams"` + MaxNotificationsPerChannel *int64 `access:"environment_push_notification_server"` + EnableConfirmNotificationsToChannel *bool `access:"site_notifications"` + TeammateNameDisplay *string `access:"site_users_and_teams"` + ExperimentalViewArchivedChannels *bool `access:"experimental_features,site_users_and_teams"` + ExperimentalEnableAutomaticReplies *bool `access:"experimental_features"` + ExperimentalHideTownSquareinLHS *bool `access:"experimental_features"` + ExperimentalTownSquareIsReadOnly *bool `access:"experimental_features"` + LockTeammateNameDisplay *bool `access:"site_users_and_teams"` + ExperimentalPrimaryTeam *string `access:"experimental_features"` + ExperimentalDefaultChannels []string `access:"experimental_features"` } func (s *TeamSettings) SetDefaults() { @@ -2090,55 +2090,55 @@ type ClientRequirements struct { type LdapSettings struct { // Basic - Enable *bool `access:"authentication"` - EnableSync *bool `access:"authentication"` - LdapServer *string `access:"authentication"` // telemetry: none - LdapPort *int `access:"authentication"` // telemetry: none - ConnectionSecurity *string `access:"authentication"` - BaseDN *string `access:"authentication"` // telemetry: none - BindUsername *string `access:"authentication"` // telemetry: none - BindPassword *string `access:"authentication"` // telemetry: none + Enable *bool `access:"authentication_ldap"` + EnableSync *bool `access:"authentication_ldap"` + LdapServer *string `access:"authentication_ldap"` // telemetry: none + LdapPort *int `access:"authentication_ldap"` // telemetry: none + ConnectionSecurity *string `access:"authentication_ldap"` + BaseDN *string `access:"authentication_ldap"` // telemetry: none + BindUsername *string `access:"authentication_ldap"` // telemetry: none + BindPassword *string `access:"authentication_ldap"` // telemetry: none // Filtering - UserFilter *string `access:"authentication"` // telemetry: none - GroupFilter *string `access:"authentication"` - GuestFilter *string `access:"authentication"` + UserFilter *string `access:"authentication_ldap"` // telemetry: none + GroupFilter *string `access:"authentication_ldap"` + GuestFilter *string `access:"authentication_ldap"` EnableAdminFilter *bool AdminFilter *string // Group Mapping - GroupDisplayNameAttribute *string `access:"authentication"` - GroupIdAttribute *string `access:"authentication"` + GroupDisplayNameAttribute *string `access:"authentication_ldap"` + GroupIdAttribute *string `access:"authentication_ldap"` // User Mapping - FirstNameAttribute *string `access:"authentication"` - LastNameAttribute *string `access:"authentication"` - EmailAttribute *string `access:"authentication"` - UsernameAttribute *string `access:"authentication"` - NicknameAttribute *string `access:"authentication"` - IdAttribute *string `access:"authentication"` - PositionAttribute *string `access:"authentication"` - LoginIdAttribute *string `access:"authentication"` - PictureAttribute *string `access:"authentication"` + FirstNameAttribute *string `access:"authentication_ldap"` + LastNameAttribute *string `access:"authentication_ldap"` + EmailAttribute *string `access:"authentication_ldap"` + UsernameAttribute *string `access:"authentication_ldap"` + NicknameAttribute *string `access:"authentication_ldap"` + IdAttribute *string `access:"authentication_ldap"` + PositionAttribute *string `access:"authentication_ldap"` + LoginIdAttribute *string `access:"authentication_ldap"` + PictureAttribute *string `access:"authentication_ldap"` // Synchronization - SyncIntervalMinutes *int `access:"authentication"` + SyncIntervalMinutes *int `access:"authentication_ldap"` // Advanced - SkipCertificateVerification *bool `access:"authentication"` - PublicCertificateFile *string `access:"authentication"` - PrivateKeyFile *string `access:"authentication"` - QueryTimeout *int `access:"authentication"` - MaxPageSize *int `access:"authentication"` + SkipCertificateVerification *bool `access:"authentication_ldap"` + PublicCertificateFile *string `access:"authentication_ldap"` + PrivateKeyFile *string `access:"authentication_ldap"` + QueryTimeout *int `access:"authentication_ldap"` + MaxPageSize *int `access:"authentication_ldap"` // Customization - LoginFieldName *string `access:"authentication"` + LoginFieldName *string `access:"authentication_ldap"` - LoginButtonColor *string `access:"authentication"` - LoginButtonBorderColor *string `access:"authentication"` - LoginButtonTextColor *string `access:"authentication"` + LoginButtonColor *string `access:"experimental_features"` + LoginButtonBorderColor *string `access:"experimental_features"` + LoginButtonTextColor *string `access:"experimental_features"` - Trace *bool `access:"authentication"` // telemetry: none + Trace *bool `access:"authentication_ldap"` // telemetry: none } func (s *LdapSettings) SetDefaults() { @@ -2287,9 +2287,9 @@ func (s *LdapSettings) SetDefaults() { } type ComplianceSettings struct { - Enable *bool `access:"compliance"` - Directory *string `access:"compliance"` // telemetry: none - EnableDaily *bool `access:"compliance"` + Enable *bool `access:"compliance_compliance_monitoring"` + Directory *string `access:"compliance_compliance_monitoring"` // telemetry: none + EnableDaily *bool `access:"compliance_compliance_monitoring"` } func (s *ComplianceSettings) SetDefaults() { @@ -2307,9 +2307,9 @@ func (s *ComplianceSettings) SetDefaults() { } type LocalizationSettings struct { - DefaultServerLocale *string `access:"site"` - DefaultClientLocale *string `access:"site"` - AvailableLocales *string `access:"site"` + DefaultServerLocale *string `access:"site_localization"` + DefaultClientLocale *string `access:"site_localization"` + AvailableLocales *string `access:"site_localization"` } func (s *LocalizationSettings) SetDefaults() { @@ -2328,49 +2328,49 @@ func (s *LocalizationSettings) SetDefaults() { type SamlSettings struct { // Basic - Enable *bool `access:"authentication"` - EnableSyncWithLdap *bool `access:"authentication"` - EnableSyncWithLdapIncludeAuth *bool `access:"authentication"` - IgnoreGuestsLdapSync *bool `access:"authentication"` + Enable *bool `access:"authentication_saml"` + EnableSyncWithLdap *bool `access:"authentication_saml"` + EnableSyncWithLdapIncludeAuth *bool `access:"authentication_saml"` + IgnoreGuestsLdapSync *bool `access:"authentication_saml"` - Verify *bool `access:"authentication"` - Encrypt *bool `access:"authentication"` - SignRequest *bool `access:"authentication"` + Verify *bool `access:"authentication_saml"` + Encrypt *bool `access:"authentication_saml"` + SignRequest *bool `access:"authentication_saml"` - IdpUrl *string `access:"authentication"` // telemetry: none - IdpDescriptorUrl *string `access:"authentication"` // telemetry: none - IdpMetadataUrl *string `access:"authentication"` // telemetry: none - ServiceProviderIdentifier *string `access:"authentication"` // telemetry: none - AssertionConsumerServiceURL *string `access:"authentication"` // telemetry: none + IdpUrl *string `access:"authentication_saml"` // telemetry: none + IdpDescriptorUrl *string `access:"authentication_saml"` // telemetry: none + IdpMetadataUrl *string `access:"authentication_saml"` // telemetry: none + ServiceProviderIdentifier *string `access:"authentication_saml"` // telemetry: none + AssertionConsumerServiceURL *string `access:"authentication_saml"` // telemetry: none - SignatureAlgorithm *string `access:"authentication"` - CanonicalAlgorithm *string `access:"authentication"` + SignatureAlgorithm *string `access:"authentication_saml"` + CanonicalAlgorithm *string `access:"authentication_saml"` - ScopingIDPProviderId *string `access:"authentication"` - ScopingIDPName *string `access:"authentication"` + ScopingIDPProviderId *string `access:"authentication_saml"` + ScopingIDPName *string `access:"authentication_saml"` - IdpCertificateFile *string `access:"authentication"` // telemetry: none - PublicCertificateFile *string `access:"authentication"` // telemetry: none - PrivateKeyFile *string `access:"authentication"` // telemetry: none + IdpCertificateFile *string `access:"authentication_saml"` // telemetry: none + PublicCertificateFile *string `access:"authentication_saml"` // telemetry: none + PrivateKeyFile *string `access:"authentication_saml"` // telemetry: none // User Mapping - IdAttribute *string `access:"authentication"` - GuestAttribute *string `access:"authentication"` + IdAttribute *string `access:"authentication_saml"` + GuestAttribute *string `access:"authentication_saml"` EnableAdminAttribute *bool AdminAttribute *string - FirstNameAttribute *string `access:"authentication"` - LastNameAttribute *string `access:"authentication"` - EmailAttribute *string `access:"authentication"` - UsernameAttribute *string `access:"authentication"` - NicknameAttribute *string `access:"authentication"` - LocaleAttribute *string `access:"authentication"` - PositionAttribute *string `access:"authentication"` + FirstNameAttribute *string `access:"authentication_saml"` + LastNameAttribute *string `access:"authentication_saml"` + EmailAttribute *string `access:"authentication_saml"` + UsernameAttribute *string `access:"authentication_saml"` + NicknameAttribute *string `access:"authentication_saml"` + LocaleAttribute *string `access:"authentication_saml"` + PositionAttribute *string `access:"authentication_saml"` - LoginButtonText *string `access:"authentication"` + LoginButtonText *string `access:"authentication_saml"` - LoginButtonColor *string `access:"authentication"` - LoginButtonBorderColor *string `access:"authentication"` - LoginButtonTextColor *string `access:"authentication"` + LoginButtonColor *string `access:"experimental_features"` + LoginButtonBorderColor *string `access:"experimental_features"` + LoginButtonTextColor *string `access:"experimental_features"` } func (s *SamlSettings) SetDefaults() { @@ -2514,10 +2514,10 @@ func (s *SamlSettings) SetDefaults() { } type NativeAppSettings struct { - AppCustomURLSchemes []string `access:"site,write_restrictable,cloud_restrictable"` // telemetry: none - AppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"` - AndroidAppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"` - IosAppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"` + AppCustomURLSchemes []string `access:"site_customization,write_restrictable,cloud_restrictable"` // telemetry: none + AppDownloadLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + AndroidAppDownloadLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` + IosAppDownloadLink *string `access:"site_customization,write_restrictable,cloud_restrictable"` } func (s *NativeAppSettings) SetDefaults() { @@ -2539,27 +2539,27 @@ func (s *NativeAppSettings) SetDefaults() { } type ElasticsearchSettings struct { - ConnectionUrl *string `access:"environment,write_restrictable,cloud_restrictable"` - Username *string `access:"environment,write_restrictable,cloud_restrictable"` - Password *string `access:"environment,write_restrictable,cloud_restrictable"` - EnableIndexing *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableSearching *bool `access:"environment,write_restrictable,cloud_restrictable"` - EnableAutocomplete *bool `access:"environment,write_restrictable,cloud_restrictable"` - Sniff *bool `access:"environment,write_restrictable,cloud_restrictable"` - PostIndexReplicas *int `access:"environment,write_restrictable,cloud_restrictable"` - PostIndexShards *int `access:"environment,write_restrictable,cloud_restrictable"` - ChannelIndexReplicas *int `access:"environment,write_restrictable,cloud_restrictable"` - ChannelIndexShards *int `access:"environment,write_restrictable,cloud_restrictable"` - UserIndexReplicas *int `access:"environment,write_restrictable,cloud_restrictable"` - UserIndexShards *int `access:"environment,write_restrictable,cloud_restrictable"` - AggregatePostsAfterDays *int `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - PostsAggregatorJobStartTime *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none - IndexPrefix *string `access:"environment,write_restrictable,cloud_restrictable"` - LiveIndexingBatchSize *int `access:"environment,write_restrictable,cloud_restrictable"` - BulkIndexingTimeWindowSeconds *int `access:"environment,write_restrictable,cloud_restrictable"` - RequestTimeoutSeconds *int `access:"environment,write_restrictable,cloud_restrictable"` - SkipTLSVerification *bool `access:"environment,write_restrictable,cloud_restrictable"` - Trace *string `access:"environment,write_restrictable,cloud_restrictable"` + ConnectionUrl *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + Username *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + Password *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + EnableIndexing *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + EnableSearching *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + EnableAutocomplete *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + Sniff *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + PostIndexReplicas *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + PostIndexShards *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + ChannelIndexReplicas *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + ChannelIndexShards *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + UserIndexReplicas *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + UserIndexShards *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + AggregatePostsAfterDays *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` // telemetry: none + PostsAggregatorJobStartTime *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` // telemetry: none + IndexPrefix *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + LiveIndexingBatchSize *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + BulkIndexingTimeWindowSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + RequestTimeoutSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + SkipTLSVerification *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` + Trace *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` } func (s *ElasticsearchSettings) SetDefaults() { @@ -2649,11 +2649,11 @@ func (s *ElasticsearchSettings) SetDefaults() { } type BleveSettings struct { - IndexDir *string `access:"experimental"` // telemetry: none - EnableIndexing *bool `access:"experimental"` - EnableSearching *bool `access:"experimental"` - EnableAutocomplete *bool `access:"experimental"` - BulkIndexingTimeWindowSeconds *int `access:"experimental"` + IndexDir *string `access:"experimental_bleve"` // telemetry: none + EnableIndexing *bool `access:"experimental_bleve"` + EnableSearching *bool `access:"experimental_bleve"` + EnableAutocomplete *bool `access:"experimental_bleve"` + BulkIndexingTimeWindowSeconds *int `access:"experimental_bleve"` } func (bs *BleveSettings) SetDefaults() { @@ -2679,11 +2679,11 @@ func (bs *BleveSettings) SetDefaults() { } type DataRetentionSettings struct { - EnableMessageDeletion *bool `access:"compliance"` - EnableFileDeletion *bool `access:"compliance"` - MessageRetentionDays *int `access:"compliance"` - FileRetentionDays *int `access:"compliance"` - DeletionJobStartTime *string `access:"compliance"` + EnableMessageDeletion *bool `access:"compliance_data_retention_policy"` + EnableFileDeletion *bool `access:"compliance_data_retention_policy"` + MessageRetentionDays *int `access:"compliance_data_retention_policy"` + FileRetentionDays *int `access:"compliance_data_retention_policy"` + DeletionJobStartTime *string `access:"compliance_data_retention_policy"` } func (s *DataRetentionSettings) SetDefaults() { @@ -2724,8 +2724,8 @@ func (s *JobSettings) SetDefaults() { } type CloudSettings struct { - CWSUrl *string `access:"environment,write_restrictable"` - CWSAPIUrl *string `access:"environment,write_restrictable"` + CWSUrl *string `access:"write_restrictable"` + CWSAPIUrl *string `access:"write_restrictable"` } func (s *CloudSettings) SetDefaults() { @@ -2832,11 +2832,11 @@ func (s *PluginSettings) SetDefaults(ls LogSettings) { } type GlobalRelayMessageExportSettings struct { - CustomerType *string `access:"compliance"` // must be either A9 or A10, dictates SMTP server url - SmtpUsername *string `access:"compliance"` - SmtpPassword *string `access:"compliance"` - EmailAddress *string `access:"compliance"` // the address to send messages to - SMTPServerTimeout *int `access:"compliance"` + CustomerType *string `access:"compliance_compliance_export"` // must be either A9 or A10, dictates SMTP server url + SmtpUsername *string `access:"compliance_compliance_export"` + SmtpPassword *string `access:"compliance_compliance_export"` + EmailAddress *string `access:"compliance_compliance_export"` // the address to send messages to + SMTPServerTimeout *int `access:"compliance_compliance_export"` } func (s *GlobalRelayMessageExportSettings) SetDefaults() { @@ -2858,15 +2858,15 @@ func (s *GlobalRelayMessageExportSettings) SetDefaults() { } type MessageExportSettings struct { - EnableExport *bool `access:"compliance"` - ExportFormat *string `access:"compliance"` - DailyRunTime *string `access:"compliance"` - ExportFromTimestamp *int64 `access:"compliance"` - BatchSize *int `access:"compliance"` - DownloadExportResults *bool `access:"compliance"` + EnableExport *bool `access:"compliance_compliance_export"` + ExportFormat *string `access:"compliance_compliance_export"` + DailyRunTime *string `access:"compliance_compliance_export"` + ExportFromTimestamp *int64 `access:"compliance_compliance_export"` + BatchSize *int `access:"compliance_compliance_export"` + DownloadExportResults *bool `access:"compliance_compliance_export"` // formatter-specific settings - these are only expected to be non-nil if ExportFormat is set to the associated format - GlobalRelaySettings *GlobalRelayMessageExportSettings `access:"compliance"` + GlobalRelaySettings *GlobalRelayMessageExportSettings `access:"compliance_compliance_export"` } func (s *MessageExportSettings) SetDefaults() { @@ -2901,8 +2901,8 @@ func (s *MessageExportSettings) SetDefaults() { } type DisplaySettings struct { - CustomUrlSchemes []string `access:"site"` - ExperimentalTimezone *bool `access:"experimental"` + CustomUrlSchemes []string `access:"site_customization"` + ExperimentalTimezone *bool `access:"experimental_features"` } func (s *DisplaySettings) SetDefaults() { @@ -2917,10 +2917,10 @@ func (s *DisplaySettings) SetDefaults() { } type GuestAccountsSettings struct { - Enable *bool `access:"authentication"` - AllowEmailAccounts *bool `access:"authentication"` - EnforceMultifactorAuthentication *bool `access:"authentication"` - RestrictCreationToDomains *string `access:"authentication"` + Enable *bool `access:"authentication_guest_access"` + AllowEmailAccounts *bool `access:"authentication_guest_access"` + EnforceMultifactorAuthentication *bool `access:"authentication_guest_access"` + RestrictCreationToDomains *string `access:"authentication_guest_access"` } func (s *GuestAccountsSettings) SetDefaults() { @@ -2942,10 +2942,10 @@ func (s *GuestAccountsSettings) SetDefaults() { } type ImageProxySettings struct { - Enable *bool `access:"environment"` - ImageProxyType *string `access:"environment"` - RemoteImageProxyURL *string `access:"environment"` - RemoteImageProxyOptions *string `access:"environment"` + Enable *bool `access:"environment_image_proxy"` + ImageProxyType *string `access:"environment_image_proxy"` + RemoteImageProxyURL *string `access:"environment_image_proxy"` + RemoteImageProxyOptions *string `access:"environment_image_proxy"` } func (s *ImageProxySettings) SetDefaults(ss ServiceSettings) { @@ -3056,7 +3056,10 @@ const ConfigAccessTagAnySysConsoleRead = "*_read" // Config fields support the 'access' tag with the following values corresponding to the suffix of the associated // PERMISSION_SYSCONSOLE_*_* permission Id: 'about', 'reporting', 'user_management_users', // 'user_management_groups', 'user_management_teams', 'user_management_channels', -// 'user_management_permissions', 'environment', 'site', 'authentication', 'plugins', +// 'user_management_permissions', 'environment_web_server', 'environment_database', 'environment_elasticsearch', +// 'environment_file_storage', 'environment_image_proxy', 'environment_smtp', 'environment_push_notification_server', +// 'environment_high_availability', 'environment_rate_limiting', 'environment_logging', 'environment_session_lengths', +// 'environment_performance_monitoring', 'environment_developer', 'site', 'authentication', 'plugins', // 'integrations', 'compliance', 'plugins', and 'experimental'. They grant read and/or write access to the config field // to roles without PERMISSION_MANAGE_SYSTEM. // diff --git a/model/job.go b/model/job.go index 9b3274cf70..78d5a4ff5a 100644 --- a/model/job.go +++ b/model/job.go @@ -38,6 +38,25 @@ const ( JOB_STATUS_WARNING = "warning" ) +var ALL_JOB_TYPES = [...]string{ + JOB_TYPE_DATA_RETENTION, + JOB_TYPE_MESSAGE_EXPORT, + JOB_TYPE_ELASTICSEARCH_POST_INDEXING, + JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION, + JOB_TYPE_BLEVE_POST_INDEXING, + JOB_TYPE_LDAP_SYNC, + JOB_TYPE_MIGRATIONS, + JOB_TYPE_PLUGINS, + JOB_TYPE_EXPIRY_NOTIFY, + JOB_TYPE_PRODUCT_NOTICES, + JOB_TYPE_ACTIVE_USERS, + JOB_TYPE_IMPORT_PROCESS, + JOB_TYPE_IMPORT_DELETE, + JOB_TYPE_EXPORT_PROCESS, + JOB_TYPE_EXPORT_DELETE, + JOB_TYPE_CLOUD, +} + type Job struct { Id string `json:"id"` Type string `json:"type"` diff --git a/model/migration.go b/model/migration.go index 387d4d5633..366f8ac207 100644 --- a/model/migration.go +++ b/model/migration.go @@ -26,4 +26,12 @@ const ( MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS = "manage_shared_channel_permissions" MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS = "manage_remote_clusters_permissions" MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS = "download_compliance_export_results" + MIGRATION_KEY_ADD_COMPLIANCE_SUBSECTION_PERMISSIONS = "compliance_subsection_permissions" + MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS = "experimental_subsection_permissions" + MIGRATION_KEY_ADD_AUTHENTICATION_SUBSECTION_PERMISSIONS = "authentication_subsection_permissions" + MIGRATION_KEY_ADD_SITE_SUBSECTION_PERMISSIONS = "site_subsection_permissions" + MIGRATION_KEY_ADD_ENVIRONMENT_SUBSECTION_PERMISSIONS = "environment_subsection_permissions" + MIGRATION_KEY_ADD_REPORTING_SUBSECTION_PERMISSIONS = "reporting_subsection_permissions" + MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS = "about_subsection_permissions" + MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS = "integrations_subsection_permissions" ) diff --git a/model/permission.go b/model/permission.go index e7b85089e5..017aee585e 100644 --- a/model/permission.go +++ b/model/permission.go @@ -102,16 +102,67 @@ var PERMISSION_EDIT_BRAND *Permission var PERMISSION_MANAGE_SHARED_CHANNELS *Permission var PERMISSION_MANAGE_REMOTE_CLUSTERS *Permission var PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT *Permission +var PERMISSION_CREATE_DATA_RETENTION_JOB *Permission +var PERMISSION_READ_DATA_RETENTION_JOB *Permission +var PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB *Permission +var PERMISSION_READ_COMPLIANCE_EXPORT_JOB *Permission +var PERMISSION_READ_AUDITS *Permission +var PERMISSION_TEST_ELASTICSEARCH *Permission +var PERMISSION_TEST_SITE_URL *Permission +var PERMISSION_TEST_S3 *Permission +var PERMISSION_RELOAD_CONFIG *Permission +var PERMISSION_INVALIDATE_CACHES *Permission +var PERMISSION_RECYCLE_DATABASE_CONNECTIONS *Permission +var PERMISSION_PURGE_ELASTICSEARCH_INDEXES *Permission +var PERMISSION_TEST_EMAIL *Permission +var PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB *Permission +var PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB *Permission +var PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB *Permission +var PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB *Permission +var PERMISSION_PURGE_BLEVE_INDEXES *Permission +var PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB *Permission +var PERMISSION_CREATE_LDAP_SYNC_JOB *Permission +var PERMISSION_READ_LDAP_SYNC_JOB *Permission +var PERMISSION_TEST_LDAP *Permission +var PERMISSION_INVALIDATE_EMAIL_INVITE *Permission +var PERMISSION_GET_SAML_METADATA_FROM_IDP *Permission +var PERMISSION_ADD_SAML_PUBLIC_CERT *Permission +var PERMISSION_ADD_SAML_PRIVATE_CERT *Permission +var PERMISSION_ADD_SAML_IDP_CERT *Permission +var PERMISSION_REMOVE_SAML_PUBLIC_CERT *Permission +var PERMISSION_REMOVE_SAML_PRIVATE_CERT *Permission +var PERMISSION_REMOVE_SAML_IDP_CERT *Permission +var PERMISSION_GET_SAML_CERT_STATUS *Permission +var PERMISSION_ADD_LDAP_PUBLIC_CERT *Permission +var PERMISSION_ADD_LDAP_PRIVATE_CERT *Permission +var PERMISSION_REMOVE_LDAP_PUBLIC_CERT *Permission +var PERMISSION_REMOVE_LDAP_PRIVATE_CERT *Permission +var PERMISSION_GET_LOGS *Permission +var PERMISSION_GET_ANALYTICS *Permission +var PERMISSION_READ_LICENSE_INFORMATION *Permission +var PERMISSION_MANAGE_LICENSE_INFORMATION *Permission var PERMISSION_SYSCONSOLE_READ_ABOUT *Permission var PERMISSION_SYSCONSOLE_WRITE_ABOUT *Permission +var PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE *Permission +var PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE *Permission + var PERMISSION_SYSCONSOLE_READ_BILLING *Permission var PERMISSION_SYSCONSOLE_WRITE_BILLING *Permission var PERMISSION_SYSCONSOLE_READ_REPORTING *Permission var PERMISSION_SYSCONSOLE_WRITE_REPORTING *Permission +var PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS *Permission +var PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS *Permission + +var PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS *Permission +var PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS *Permission + +var PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS *Permission +var PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS *Permission + var PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS *Permission var PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS *Permission @@ -130,27 +181,156 @@ var PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS *Permission var PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES *Permission var PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES *Permission +// DEPRECATED var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT *Permission + +// DEPRECATED var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT *Permission +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING *Permission + +var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER *Permission +var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER *Permission + var PERMISSION_SYSCONSOLE_READ_SITE *Permission var PERMISSION_SYSCONSOLE_WRITE_SITE *Permission +var PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_EMOJI *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_POSTS *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS *Permission + +var PERMISSION_SYSCONSOLE_READ_SITE_NOTICES *Permission +var PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES *Permission + var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION *Permission var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION *Permission +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID *Permission + +var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS *Permission +var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS *Permission + var PERMISSION_SYSCONSOLE_READ_PLUGINS *Permission var PERMISSION_SYSCONSOLE_WRITE_PLUGINS *Permission var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS *Permission var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS *Permission +var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT *Permission +var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT *Permission + +var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS *Permission +var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS *Permission + +var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF *Permission +var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF *Permission + +var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS *Permission +var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS *Permission + var PERMISSION_SYSCONSOLE_READ_COMPLIANCE *Permission var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE *Permission +var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY *Permission +var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY *Permission + +var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT *Permission +var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT *Permission + +var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING *Permission +var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING *Permission + +var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE *Permission +var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE *Permission + var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL *Permission var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL *Permission +var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES *Permission +var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES *Permission + +var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS *Permission +var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS *Permission + +var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE *Permission +var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE *Permission + // General permission that encompasses all system admin functions // in the future this could be broken up to allow access to some // admin functions but not others @@ -538,6 +718,190 @@ func initializePermissions() { PermissionScopeSystem, } + PERMISSION_CREATE_DATA_RETENTION_JOB = &Permission{ + "create_data_retention_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_READ_DATA_RETENTION_JOB = &Permission{ + "read_data_retention_job", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB = &Permission{ + "create_compliance_export_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_READ_COMPLIANCE_EXPORT_JOB = &Permission{ + "read_compliance_export_job", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_READ_AUDITS = &Permission{ + "read_audits", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_PURGE_BLEVE_INDEXES = &Permission{ + "purge_bleve_indexes", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB = &Permission{ + "create_post_bleve_indexes_job", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_CREATE_LDAP_SYNC_JOB = &Permission{ + "create_ldap_sync_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_READ_LDAP_SYNC_JOB = &Permission{ + "read_ldap_sync_job", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_TEST_LDAP = &Permission{ + "test_ldap", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_INVALIDATE_EMAIL_INVITE = &Permission{ + "invalidate_email_invite", + "", + "", + PermissionScopeSystem, + } + PERMISSION_GET_SAML_METADATA_FROM_IDP = &Permission{ + "get_saml_metadata_from_idp", + "", + "", + PermissionScopeSystem, + } + PERMISSION_ADD_SAML_PUBLIC_CERT = &Permission{ + "add_saml_public_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_ADD_SAML_PRIVATE_CERT = &Permission{ + "add_saml_private_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_ADD_SAML_IDP_CERT = &Permission{ + "add_saml_idp_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_REMOVE_SAML_PUBLIC_CERT = &Permission{ + "remove_saml_public_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_REMOVE_SAML_PRIVATE_CERT = &Permission{ + "remove_saml_private_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_REMOVE_SAML_IDP_CERT = &Permission{ + "remove_saml_idp_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_GET_SAML_CERT_STATUS = &Permission{ + "get_saml_cert_status", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_ADD_LDAP_PUBLIC_CERT = &Permission{ + "add_ldap_public_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_ADD_LDAP_PRIVATE_CERT = &Permission{ + "add_ldap_private_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_REMOVE_LDAP_PUBLIC_CERT = &Permission{ + "remove_ldap_public_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_REMOVE_LDAP_PRIVATE_CERT = &Permission{ + "remove_ldap_private_cert", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_GET_LOGS = &Permission{ + "get_logs", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_READ_LICENSE_INFORMATION = &Permission{ + "read_license_information", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_GET_ANALYTICS = &Permission{ + "get_analytics", + "", + "", + PermissionScopeSystem, + } + + PERMISSION_MANAGE_LICENSE_INFORMATION = &Permission{ + "manage_license_information", + "", + "", + PermissionScopeSystem, + } + PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT = &Permission{ "download_compliance_export_result", "authentication.permissions.download_compliance_export_result.name", @@ -545,6 +909,79 @@ func initializePermissions() { PermissionScopeSystem, } + PERMISSION_TEST_SITE_URL = &Permission{ + "test_site_url", + "", + "", + PermissionScopeSystem, + } + PERMISSION_TEST_ELASTICSEARCH = &Permission{ + "test_elasticsearch", + "", + "", + PermissionScopeSystem, + } + PERMISSION_TEST_S3 = &Permission{ + "test_s3", + "", + "", + PermissionScopeSystem, + } + PERMISSION_RELOAD_CONFIG = &Permission{ + "reload_config", + "", + "", + PermissionScopeSystem, + } + PERMISSION_INVALIDATE_CACHES = &Permission{ + "invalidate_caches", + "", + "", + PermissionScopeSystem, + } + PERMISSION_RECYCLE_DATABASE_CONNECTIONS = &Permission{ + "recycle_database_connections", + "", + "", + PermissionScopeSystem, + } + PERMISSION_PURGE_ELASTICSEARCH_INDEXES = &Permission{ + "purge_elasticsearch_indexes", + "", + "", + PermissionScopeSystem, + } + PERMISSION_TEST_EMAIL = &Permission{ + "test_email", + "", + "", + PermissionScopeSystem, + } + PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB = &Permission{ + "create_elasticsearch_post_indexing_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB = &Permission{ + "create_elasticsearch_post_aggregation_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB = &Permission{ + "read_elasticsearch_post_indexing_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB = &Permission{ + "read_elasticsearch_post_aggregation_job", + "", + "", + PermissionScopeSystem, + } + PERMISSION_REMOVE_USER_FROM_TEAM = &Permission{ "remove_user_from_team", "authentication.permissions.remove_user_from_team.name", @@ -695,18 +1132,32 @@ func initializePermissions() { "authentication.permissions.edit_brand.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_ABOUT = &Permission{ "sysconsole_read_about", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_ABOUT = &Permission{ "sysconsole_write_about", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE = &Permission{ + "sysconsole_read_about_edition_and_license", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE = &Permission{ + "sysconsole_write_about_edition_and_license", + "", + "", + PermissionScopeSystem, + } PERMISSION_SYSCONSOLE_READ_BILLING = &Permission{ "sysconsole_read_billing", "", @@ -719,18 +1170,56 @@ func initializePermissions() { "", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_REPORTING = &Permission{ "sysconsole_read_reporting", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_REPORTING = &Permission{ "sysconsole_write_reporting", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS = &Permission{ + "sysconsole_read_reporting_site_statistics", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS = &Permission{ + "sysconsole_write_reporting_site_statistics", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS = &Permission{ + "sysconsole_read_reporting_team_statistics", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS = &Permission{ + "sysconsole_write_reporting_team_statistics", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS = &Permission{ + "sysconsole_read_reporting_server_logs", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS = &Permission{ + "sysconsole_write_reporting_server_logs", + "", + "", + PermissionScopeSystem, + } PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS = &Permission{ "sysconsole_read_user_management_users", "authentication.permissions.use_group_mentions.name", @@ -803,42 +1292,422 @@ func initializePermissions() { "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_ENVIRONMENT = &Permission{ "sysconsole_read_environment", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT = &Permission{ "sysconsole_write_environment", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER = &Permission{ + "sysconsole_read_environment_web_server", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER = &Permission{ + "sysconsole_write_environment_web_server", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE = &Permission{ + "sysconsole_read_environment_database", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE = &Permission{ + "sysconsole_write_environment_database", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH = &Permission{ + "sysconsole_read_environment_elasticsearch", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH = &Permission{ + "sysconsole_write_environment_elasticsearch", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE = &Permission{ + "sysconsole_read_environment_file_storage", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE = &Permission{ + "sysconsole_write_environment_file_storage", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY = &Permission{ + "sysconsole_read_environment_image_proxy", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY = &Permission{ + "sysconsole_write_environment_image_proxy", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP = &Permission{ + "sysconsole_read_environment_smtp", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP = &Permission{ + "sysconsole_write_environment_smtp", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER = &Permission{ + "sysconsole_read_environment_push_notification_server", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER = &Permission{ + "sysconsole_write_environment_push_notification_server", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY = &Permission{ + "sysconsole_read_environment_high_availability", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY = &Permission{ + "sysconsole_write_environment_high_availability", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING = &Permission{ + "sysconsole_read_environment_rate_limiting", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING = &Permission{ + "sysconsole_write_environment_rate_limiting", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING = &Permission{ + "sysconsole_read_environment_logging", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING = &Permission{ + "sysconsole_write_environment_logging", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS = &Permission{ + "sysconsole_read_environment_session_lengths", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS = &Permission{ + "sysconsole_write_environment_session_lengths", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING = &Permission{ + "sysconsole_read_environment_performance_monitoring", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING = &Permission{ + "sysconsole_write_environment_performance_monitoring", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER = &Permission{ + "sysconsole_read_environment_developer", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER = &Permission{ + "sysconsole_write_environment_developer", + "", + "", + PermissionScopeSystem, + } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_SITE = &Permission{ "sysconsole_read_site", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_SITE = &Permission{ "sysconsole_write_site", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + + PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION = &Permission{ + "sysconsole_read_site_customization", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION = &Permission{ + "sysconsole_write_site_customization", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION = &Permission{ + "sysconsole_read_site_localization", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION = &Permission{ + "sysconsole_write_site_localization", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS = &Permission{ + "sysconsole_read_site_users_and_teams", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS = &Permission{ + "sysconsole_write_site_users_and_teams", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS = &Permission{ + "sysconsole_read_site_notifications", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS = &Permission{ + "sysconsole_write_site_notifications", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER = &Permission{ + "sysconsole_read_site_announcement_banner", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER = &Permission{ + "sysconsole_write_site_announcement_banner", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_EMOJI = &Permission{ + "sysconsole_read_site_emoji", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI = &Permission{ + "sysconsole_write_site_emoji", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_POSTS = &Permission{ + "sysconsole_read_site_posts", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS = &Permission{ + "sysconsole_write_site_posts", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS = &Permission{ + "sysconsole_read_site_file_sharing_and_downloads", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS = &Permission{ + "sysconsole_write_site_file_sharing_and_downloads", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS = &Permission{ + "sysconsole_read_site_public_links", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS = &Permission{ + "sysconsole_write_site_public_links", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_SITE_NOTICES = &Permission{ + "sysconsole_read_site_notices", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES = &Permission{ + "sysconsole_write_site_notices", + "", + "", + PermissionScopeSystem, + } + + // Deprecated PERMISSION_SYSCONSOLE_READ_AUTHENTICATION = &Permission{ "sysconsole_read_authentication", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // Deprecated PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION = &Permission{ "sysconsole_write_authentication", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP = &Permission{ + "sysconsole_read_authentication_signup", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP = &Permission{ + "sysconsole_write_authentication_signup", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL = &Permission{ + "sysconsole_read_authentication_email", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL = &Permission{ + "sysconsole_write_authentication_email", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD = &Permission{ + "sysconsole_read_authentication_password", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD = &Permission{ + "sysconsole_write_authentication_password", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA = &Permission{ + "sysconsole_read_authentication_mfa", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA = &Permission{ + "sysconsole_write_authentication_mfa", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP = &Permission{ + "sysconsole_read_authentication_ldap", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP = &Permission{ + "sysconsole_write_authentication_ldap", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML = &Permission{ + "sysconsole_read_authentication_saml", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML = &Permission{ + "sysconsole_write_authentication_saml", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID = &Permission{ + "sysconsole_read_authentication_openid", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID = &Permission{ + "sysconsole_write_authentication_openid", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS = &Permission{ + "sysconsole_read_authentication_guest_access", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS = &Permission{ + "sysconsole_write_authentication_guest_access", + "", + "", + PermissionScopeSystem, + } PERMISSION_SYSCONSOLE_READ_PLUGINS = &Permission{ "sysconsole_read_plugins", "authentication.permissions.use_group_mentions.name", @@ -851,91 +1720,293 @@ func initializePermissions() { "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_INTEGRATIONS = &Permission{ "sysconsole_read_integrations", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS = &Permission{ "sysconsole_write_integrations", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT = &Permission{ + "sysconsole_read_integrations_integration_management", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT = &Permission{ + "sysconsole_write_integrations_integration_management", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS = &Permission{ + "sysconsole_read_integrations_bot_accounts", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS = &Permission{ + "sysconsole_write_integrations_bot_accounts", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF = &Permission{ + "sysconsole_read_integrations_gif", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF = &Permission{ + "sysconsole_write_integrations_gif", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS = &Permission{ + "sysconsole_read_integrations_cors", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS = &Permission{ + "sysconsole_write_integrations_cors", + "", + "", + PermissionScopeSystem, + } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_COMPLIANCE = &Permission{ "sysconsole_read_compliance", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE = &Permission{ "sysconsole_write_compliance", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } - PERMISSION_SYSCONSOLE_READ_PLUGINS = &Permission{ - "sysconsole_read_plugins", - "authentication.permissions.use_group_mentions.name", - "authentication.permissions.use_group_mentions.description", + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY = &Permission{ + "sysconsole_read_compliance_data_retention_policy", + "", + "", PermissionScopeSystem, } - PERMISSION_SYSCONSOLE_WRITE_PLUGINS = &Permission{ - "sysconsole_write_plugins", - "authentication.permissions.use_group_mentions.name", - "authentication.permissions.use_group_mentions.description", + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY = &Permission{ + "sysconsole_write_compliance_data_retention_policy", + "", + "", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT = &Permission{ + "sysconsole_read_compliance_compliance_export", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT = &Permission{ + "sysconsole_write_compliance_compliance_export", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING = &Permission{ + "sysconsole_read_compliance_compliance_monitoring", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING = &Permission{ + "sysconsole_write_compliance_compliance_monitoring", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE = &Permission{ + "sysconsole_read_compliance_custom_terms_of_service", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE = &Permission{ + "sysconsole_write_compliance_custom_terms_of_service", + "", + "", + PermissionScopeSystem, + } + // DEPRECATED PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL = &Permission{ "sysconsole_read_experimental", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + // DEPRECATED PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL = &Permission{ "sysconsole_write_experimental", "authentication.permissions.use_group_mentions.name", "authentication.permissions.use_group_mentions.description", PermissionScopeSystem, } + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES = &Permission{ + "sysconsole_read_experimental_features", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES = &Permission{ + "sysconsole_write_experimental_features", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS = &Permission{ + "sysconsole_read_experimental_feature_flags", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS = &Permission{ + "sysconsole_write_experimental_feature_flags", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE = &Permission{ + "sysconsole_read_experimental_bleve", + "", + "", + PermissionScopeSystem, + } + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE = &Permission{ + "sysconsole_write_experimental_bleve", + "", + "", + PermissionScopeSystem, + } SysconsoleReadPermissions = []*Permission{ - PERMISSION_SYSCONSOLE_READ_ABOUT, + PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE, PERMISSION_SYSCONSOLE_READ_BILLING, - PERMISSION_SYSCONSOLE_READ_REPORTING, + PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS, + PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS, + PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES, - PERMISSION_SYSCONSOLE_READ_ENVIRONMENT, - PERMISSION_SYSCONSOLE_READ_SITE, - PERMISSION_SYSCONSOLE_READ_AUTHENTICATION, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER, + PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION, + PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION, + PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS, + PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS, + PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER, + PERMISSION_SYSCONSOLE_READ_SITE_EMOJI, + PERMISSION_SYSCONSOLE_READ_SITE_POSTS, + PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS, + PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS, + PERMISSION_SYSCONSOLE_READ_SITE_NOTICES, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS, PERMISSION_SYSCONSOLE_READ_PLUGINS, - PERMISSION_SYSCONSOLE_READ_INTEGRATIONS, - PERMISSION_SYSCONSOLE_READ_COMPLIANCE, - PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE, } SysconsoleWritePermissions = []*Permission{ - PERMISSION_SYSCONSOLE_WRITE_ABOUT, + PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE, PERMISSION_SYSCONSOLE_WRITE_BILLING, - PERMISSION_SYSCONSOLE_WRITE_REPORTING, + PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS, + PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS, + PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES, - PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT, - PERMISSION_SYSCONSOLE_WRITE_SITE, - PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER, + PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION, + PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION, + PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS, + PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS, + PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER, + PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI, + PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS, + PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS, + PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS, + PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS, PERMISSION_SYSCONSOLE_WRITE_PLUGINS, - PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS, - PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE, - PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE, + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES, + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS, + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE, } SystemScopedPermissionsMinusSysconsole := []*Permission{ @@ -972,6 +2043,45 @@ func initializePermissions() { PERMISSION_MANAGE_SHARED_CHANNELS, PERMISSION_MANAGE_REMOTE_CLUSTERS, PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT, + PERMISSION_CREATE_DATA_RETENTION_JOB, + PERMISSION_READ_DATA_RETENTION_JOB, + PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB, + PERMISSION_READ_COMPLIANCE_EXPORT_JOB, + PERMISSION_READ_AUDITS, + PERMISSION_TEST_SITE_URL, + PERMISSION_TEST_ELASTICSEARCH, + PERMISSION_TEST_S3, + PERMISSION_RELOAD_CONFIG, + PERMISSION_INVALIDATE_CACHES, + PERMISSION_RECYCLE_DATABASE_CONNECTIONS, + PERMISSION_PURGE_ELASTICSEARCH_INDEXES, + PERMISSION_TEST_EMAIL, + PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB, + PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB, + PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB, + PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB, + PERMISSION_PURGE_BLEVE_INDEXES, + PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB, + PERMISSION_CREATE_LDAP_SYNC_JOB, + PERMISSION_READ_LDAP_SYNC_JOB, + PERMISSION_TEST_LDAP, + PERMISSION_INVALIDATE_EMAIL_INVITE, + PERMISSION_GET_SAML_METADATA_FROM_IDP, + PERMISSION_ADD_SAML_PUBLIC_CERT, + PERMISSION_ADD_SAML_PRIVATE_CERT, + PERMISSION_ADD_SAML_IDP_CERT, + PERMISSION_REMOVE_SAML_PUBLIC_CERT, + PERMISSION_REMOVE_SAML_PRIVATE_CERT, + PERMISSION_REMOVE_SAML_IDP_CERT, + PERMISSION_GET_SAML_CERT_STATUS, + PERMISSION_ADD_LDAP_PUBLIC_CERT, + PERMISSION_ADD_LDAP_PRIVATE_CERT, + PERMISSION_REMOVE_LDAP_PUBLIC_CERT, + PERMISSION_REMOVE_LDAP_PRIVATE_CERT, + PERMISSION_GET_ANALYTICS, + PERMISSION_GET_LOGS, + PERMISSION_READ_LICENSE_INFORMATION, + PERMISSION_MANAGE_LICENSE_INFORMATION, } TeamScopedPermissions := []*Permission{ @@ -1035,6 +2145,22 @@ func initializePermissions() { PERMISSION_MANAGE_OTHERS_WEBHOOKS, PERMISSION_MANAGE_EMOJIS, PERMISSION_MANAGE_OTHERS_EMOJIS, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION, + PERMISSION_SYSCONSOLE_READ_SITE, + PERMISSION_SYSCONSOLE_WRITE_SITE, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT, + PERMISSION_SYSCONSOLE_READ_REPORTING, + PERMISSION_SYSCONSOLE_WRITE_REPORTING, + PERMISSION_SYSCONSOLE_READ_ABOUT, + PERMISSION_SYSCONSOLE_WRITE_ABOUT, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL, + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE, } AllPermissions = []*Permission{} diff --git a/model/permission_test.go b/model/permission_test.go deleted file mode 100644 index 5e803d5bea..0000000000 --- a/model/permission_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package model - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -// This is a test to ensure that we don't accidentally add more permissions than can fit -// in the database column for role permissions. -func TestPermissionsLength(t *testing.T) { - permissionsString := "" - for _, permission := range AllPermissions { - permissionsString += " " + permission.Id - } - - assert.True(t, len(permissionsString) < 4096) -} diff --git a/model/role.go b/model/role.go index 3a6c8a41d2..fc1606cedd 100644 --- a/model/role.go +++ b/model/role.go @@ -47,6 +47,12 @@ func init() { // When updating the values here, the values in mattermost-redux must also be updated. SysconsoleAncillaryPermissions = map[string][]*Permission{ + PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id: { + PERMISSION_READ_LICENSE_INFORMATION, + }, + PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE.Id: { + PERMISSION_MANAGE_LICENSE_INFORMATION, + }, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id: { PERMISSION_READ_PUBLIC_CHANNEL, PERMISSION_READ_CHANNEL, @@ -55,26 +61,44 @@ func init() { }, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id: { PERMISSION_READ_OTHER_USERS_TEAMS, + PERMISSION_GET_ANALYTICS, }, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id: { PERMISSION_LIST_PRIVATE_TEAMS, PERMISSION_LIST_PUBLIC_TEAMS, PERMISSION_VIEW_TEAM, }, - PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE.Id: { - PERMISSION_MANAGE_JOBS, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id: { + PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB, + PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB, }, - PERMISSION_SYSCONSOLE_READ_COMPLIANCE.Id: { - PERMISSION_READ_JOBS, - PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER.Id: { + PERMISSION_TEST_SITE_URL, + PERMISSION_RELOAD_CONFIG, + PERMISSION_INVALIDATE_CACHES, }, - PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id: { - PERMISSION_READ_JOBS, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE.Id: { + PERMISSION_RECYCLE_DATABASE_CONNECTIONS, }, - PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id: { - PERMISSION_READ_JOBS, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH.Id: { + PERMISSION_TEST_ELASTICSEARCH, + PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB, + PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB, + PERMISSION_PURGE_ELASTICSEARCH_INDEXES, }, - PERMISSION_SYSCONSOLE_READ_REPORTING.Id: { + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE.Id: { + PERMISSION_TEST_S3, + }, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP.Id: { + PERMISSION_TEST_EMAIL, + }, + PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id: { + PERMISSION_GET_LOGS, + }, + PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id: { + PERMISSION_GET_ANALYTICS, + }, + PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id: { PERMISSION_VIEW_TEAM, }, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS.Id: { @@ -109,12 +133,54 @@ func init() { PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE, PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC, }, - PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id: { - PERMISSION_MANAGE_JOBS, - }, - PERMISSION_SYSCONSOLE_WRITE_SITE.Id: { + PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION.Id: { PERMISSION_EDIT_BRAND, }, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY.Id: { + PERMISSION_CREATE_DATA_RETENTION_JOB, + }, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY.Id: { + PERMISSION_READ_DATA_RETENTION_JOB, + }, + PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT.Id: { + PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB, + PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT, + }, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT.Id: { + PERMISSION_READ_COMPLIANCE_EXPORT_JOB, + PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT, + }, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id: { + PERMISSION_READ_AUDITS, + }, + PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE.Id: { + PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB, + PERMISSION_PURGE_BLEVE_INDEXES, + }, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP.Id: { + PERMISSION_CREATE_LDAP_SYNC_JOB, + PERMISSION_ADD_LDAP_PUBLIC_CERT, + PERMISSION_REMOVE_LDAP_PUBLIC_CERT, + PERMISSION_ADD_LDAP_PRIVATE_CERT, + PERMISSION_REMOVE_LDAP_PRIVATE_CERT, + }, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id: { + PERMISSION_TEST_LDAP, + PERMISSION_READ_LDAP_SYNC_JOB, + }, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL.Id: { + PERMISSION_INVALIDATE_EMAIL_INVITE, + }, + PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML.Id: { + PERMISSION_GET_SAML_METADATA_FROM_IDP, + PERMISSION_ADD_SAML_PUBLIC_CERT, + PERMISSION_ADD_SAML_PRIVATE_CERT, + PERMISSION_ADD_SAML_IDP_CERT, + PERMISSION_REMOVE_SAML_PUBLIC_CERT, + PERMISSION_REMOVE_SAML_PRIVATE_CERT, + PERMISSION_REMOVE_SAML_IDP_CERT, + PERMISSION_GET_SAML_CERT_STATUS, + }, } SystemUserManagerDefaultPermissions = []string{ @@ -125,29 +191,76 @@ func init() { PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id, PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id, - PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id, } SystemReadOnlyAdminDefaultPermissions = []string{ - PERMISSION_SYSCONSOLE_READ_ABOUT.Id, - PERMISSION_SYSCONSOLE_READ_REPORTING.Id, + PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.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_ENVIRONMENT_WEB_SERVER.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER.Id, + PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION.Id, + PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION.Id, + PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER.Id, + PERMISSION_SYSCONSOLE_READ_SITE_EMOJI.Id, + PERMISSION_SYSCONSOLE_READ_SITE_POSTS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_NOTICES.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id, PERMISSION_SYSCONSOLE_READ_PLUGINS.Id, - PERMISSION_SYSCONSOLE_READ_COMPLIANCE.Id, - PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, - PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY.Id, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT.Id, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING.Id, + PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES.Id, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS.Id, + PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE.Id, } SystemManagerDefaultPermissions = []string{ - PERMISSION_SYSCONSOLE_READ_ABOUT.Id, - PERMISSION_SYSCONSOLE_READ_REPORTING.Id, + PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id, + PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id, PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id, @@ -156,20 +269,75 @@ func init() { 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_ENVIRONMENT_WEB_SERVER.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING.Id, + PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING.Id, + PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER.Id, + PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION.Id, + PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION.Id, + PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER.Id, + PERMISSION_SYSCONSOLE_READ_SITE_EMOJI.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI.Id, + PERMISSION_SYSCONSOLE_READ_SITE_POSTS.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS.Id, + PERMISSION_SYSCONSOLE_READ_SITE_NOTICES.Id, + PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id, + PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id, PERMISSION_SYSCONSOLE_READ_PLUGINS.Id, - PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id, - PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF.Id, + PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS.Id, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF.Id, + PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS.Id, } // Add the ancillary permissions to each system role - SystemUserManagerDefaultPermissions = addAncillaryPermissions(SystemUserManagerDefaultPermissions) - SystemReadOnlyAdminDefaultPermissions = addAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions) - SystemManagerDefaultPermissions = addAncillaryPermissions(SystemManagerDefaultPermissions) + SystemUserManagerDefaultPermissions = AddAncillaryPermissions(SystemUserManagerDefaultPermissions) + SystemReadOnlyAdminDefaultPermissions = AddAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions) + SystemManagerDefaultPermissions = AddAncillaryPermissions(SystemManagerDefaultPermissions) } type RoleType string @@ -772,7 +940,7 @@ func MakeDefaultRoles() map[string]*Role { return roles } -func addAncillaryPermissions(permissions []string) []string { +func AddAncillaryPermissions(permissions []string) []string { for _, permission := range permissions { if ancillaryPermissions, ok := SysconsoleAncillaryPermissions[permission]; ok { for _, ancillaryPermission := range ancillaryPermissions { diff --git a/model/utils.go b/model/utils.go index 4827fb5a9e..775a82c3cf 100644 --- a/model/utils.go +++ b/model/utils.go @@ -697,3 +697,18 @@ func filterBlocklist(r rune) rune { return r } + +// UniqueStrings returns a unique subset of the string slice provided. +func UniqueStrings(input []string) []string { + u := make([]string, 0, len(input)) + m := make(map[string]bool) + + for _, val := range input { + if _, ok := m[val]; !ok { + m[val] = true + u = append(u, val) + } + } + + return u +} diff --git a/model/utils_test.go b/model/utils_test.go index 1764a46a25..059910fd9f 100644 --- a/model/utils_test.go +++ b/model/utils_test.go @@ -866,3 +866,36 @@ func TestIsValidHttpUrl(t *testing.T) { }) } } + +func TestUniqueStrings(t *testing.T) { + cases := []struct { + Input []string + Result []string + }{ + { + Input: []string{"1", "2", "3", "3", "3"}, + Result: []string{"1", "2", "3"}, + }, + { + Input: []string{"1", "2", "3", "4", "5"}, + Result: []string{"1", "2", "3", "4", "5"}, + }, + { + Input: []string{"1", "1", "1", "3", "3"}, + Result: []string{"1", "3"}, + }, + { + Input: []string{"1", "1", "1", "1", "1"}, + Result: []string{"1"}, + }, + { + Input: []string{}, + Result: []string{}, + }, + } + + for _, tc := range cases { + actual := UniqueStrings(tc.Input) + require.Equalf(t, actual, tc.Result, "case: %v\tshould returned: %#v", tc, tc.Result) + } +} diff --git a/scripts/mattermost-postgresql-5.0.sql b/scripts/mattermost-postgresql-5.0.sql index 8ff8de8930..3437d947be 100644 --- a/scripts/mattermost-postgresql-5.0.sql +++ b/scripts/mattermost-postgresql-5.0.sql @@ -445,7 +445,7 @@ CREATE TABLE public.roles ( createat bigint, updateat bigint, deleteat bigint, - permissions character varying(4096), + permissions text, schememanaged boolean, builtin boolean ); diff --git a/store/opentracinglayer/opentracinglayer.go b/store/opentracinglayer/opentracinglayer.go index 31565c12a8..2ac7ee7ca7 100644 --- a/store/opentracinglayer/opentracinglayer.go +++ b/store/opentracinglayer/opentracinglayer.go @@ -4185,6 +4185,24 @@ func (s *OpenTracingLayerJobStore) GetAllByTypePage(jobType string, offset int, return result, err } +func (s *OpenTracingLayerJobStore) GetAllByTypesPage(jobTypes []string, offset int, limit int) ([]*model.Job, error) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "JobStore.GetAllByTypesPage") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + result, err := s.JobStore.GetAllByTypesPage(jobTypes, offset, limit) + if err != nil { + span.LogFields(spanlog.Error(err)) + ext.Error.Set(span, true) + } + + return result, err +} + func (s *OpenTracingLayerJobStore) GetAllPage(offset int, limit int) ([]*model.Job, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "JobStore.GetAllPage") diff --git a/store/retrylayer/retrylayer.go b/store/retrylayer/retrylayer.go index 4506fb05b7..6ab4c139af 100644 --- a/store/retrylayer/retrylayer.go +++ b/store/retrylayer/retrylayer.go @@ -4516,6 +4516,26 @@ func (s *RetryLayerJobStore) GetAllByTypePage(jobType string, offset int, limit } +func (s *RetryLayerJobStore) GetAllByTypesPage(jobTypes []string, offset int, limit int) ([]*model.Job, error) { + + tries := 0 + for { + result, err := s.JobStore.GetAllByTypesPage(jobTypes, offset, limit) + if err == nil { + return result, nil + } + if !isRepeatableError(err) { + return result, err + } + tries++ + if tries >= 3 { + err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") + return result, err + } + } + +} + func (s *RetryLayerJobStore) GetAllPage(offset int, limit int) ([]*model.Job, error) { tries := 0 diff --git a/store/sqlstore/job_store.go b/store/sqlstore/job_store.go index 9e30c1a7fb..6ef7b32022 100644 --- a/store/sqlstore/job_store.go +++ b/store/sqlstore/job_store.go @@ -156,6 +156,25 @@ func (jss SqlJobStore) GetAllPage(offset int, limit int) ([]*model.Job, error) { return statuses, nil } +func (jss SqlJobStore) GetAllByTypesPage(jobTypes []string, offset int, limit int) ([]*model.Job, error) { + query, args, err := jss.getQueryBuilder(). + Select("*"). + From("Jobs"). + Where(sq.Eq{"Type": jobTypes}). + OrderBy("CreateAt DESC"). + Limit(uint64(limit)). + Offset(uint64(offset)).ToSql() + if err != nil { + return nil, errors.Wrap(err, "job_tosql") + } + + var jobs []*model.Job + if _, err = jss.GetReplica().Select(&jobs, query, args...); err != nil { + return nil, errors.Wrapf(err, "failed to find Jobs with types") + } + return jobs, nil +} + func (jss SqlJobStore) GetAllByType(jobType string) ([]*model.Job, error) { query, args, err := jss.getQueryBuilder(). Select("*"). diff --git a/store/sqlstore/role_store.go b/store/sqlstore/role_store.go index b037b05c9f..e2791b3892 100644 --- a/store/sqlstore/role_store.go +++ b/store/sqlstore/role_store.go @@ -91,7 +91,7 @@ func newSqlRoleStore(sqlStore *SqlStore) store.RoleStore { table.ColMap("Name").SetMaxSize(64).SetUnique(true) table.ColMap("DisplayName").SetMaxSize(128) table.ColMap("Description").SetMaxSize(1024) - table.ColMap("Permissions").SetMaxSize(4096) + table.ColMap("Permissions") } return s } diff --git a/store/sqlstore/upgrade.go b/store/sqlstore/upgrade.go index b2e2ca6465..c0e829d702 100644 --- a/store/sqlstore/upgrade.go +++ b/store/sqlstore/upgrade.go @@ -1011,6 +1011,7 @@ func upgradeDatabaseToVersion534(sqlStore *SqlStore) { func upgradeDatabaseToVersion535(sqlStore *SqlStore) { // if shouldPerformUpgrade(sqlStore, Version5340, Version5350) { + sqlStore.AlterColumnTypeIfExists("Roles", "Permissions", "longtext", "text") sqlStore.CreateColumnIfNotExists("SidebarCategories", "Collapsed", "tinyint(1)", "boolean", "0") diff --git a/store/store.go b/store/store.go index daf930e83b..9f8adf4586 100644 --- a/store/store.go +++ b/store/store.go @@ -630,6 +630,7 @@ type JobStore interface { GetAllPage(offset int, limit int) ([]*model.Job, error) GetAllByType(jobType string) ([]*model.Job, error) GetAllByTypePage(jobType string, offset int, limit int) ([]*model.Job, error) + GetAllByTypesPage(jobTypes []string, offset int, limit int) ([]*model.Job, error) GetAllByStatus(status string) ([]*model.Job, error) GetNewestJobByStatusAndType(status string, jobType string) (*model.Job, error) GetNewestJobByStatusesAndType(statuses []string, jobType string) (*model.Job, error) diff --git a/store/storetest/job_store.go b/store/storetest/job_store.go index cfab648409..1f0269f298 100644 --- a/store/storetest/job_store.go +++ b/store/storetest/job_store.go @@ -20,6 +20,7 @@ func TestJobStore(t *testing.T, ss store.Store) { t.Run("JobSaveGet", func(t *testing.T) { testJobSaveGet(t, ss) }) t.Run("JobGetAllByType", func(t *testing.T) { testJobGetAllByType(t, ss) }) t.Run("JobGetAllByTypePage", func(t *testing.T) { testJobGetAllByTypePage(t, ss) }) + t.Run("JobGetAllByTypesPage", func(t *testing.T) { testJobGetAllByTypesPage(t, ss) }) t.Run("JobGetAllPage", func(t *testing.T) { testJobGetAllPage(t, ss) }) t.Run("JobGetAllByStatus", func(t *testing.T) { testJobGetAllByStatus(t, ss) }) t.Run("GetNewestJobByStatusAndType", func(t *testing.T) { testJobStoreGetNewestJobByStatusAndType(t, ss) }) @@ -127,6 +128,61 @@ func testJobGetAllByTypePage(t *testing.T, ss store.Store) { require.Equal(t, received[0].Id, jobs[1].Id, "should've received oldest job last") } +func testJobGetAllByTypesPage(t *testing.T, ss store.Store) { + jobType := model.NewId() + jobType2 := model.NewId() + + jobs := []*model.Job{ + { + Id: model.NewId(), + Type: jobType, + CreateAt: 1000, + }, + { + Id: model.NewId(), + Type: jobType, + CreateAt: 999, + }, + { + Id: model.NewId(), + Type: jobType2, + CreateAt: 1001, + }, + { + Id: model.NewId(), + Type: model.NewId(), + CreateAt: 1002, + }, + } + + for _, job := range jobs { + _, err := ss.Job().Save(job) + require.NoError(t, err) + defer ss.Job().Delete(job.Id) + } + + // test return all + jobTypes := []string{jobType, jobType2} + received, err := ss.Job().GetAllByTypesPage(jobTypes, 0, 4) + require.NoError(t, err) + require.Len(t, received, 3) + require.Equal(t, received[0].Id, jobs[2].Id, "should've received newest job first") + require.Equal(t, received[1].Id, jobs[0].Id, "should've received second newest job second") + + // test paging + jobTypes = []string{jobType, jobType2} + received, err = ss.Job().GetAllByTypesPage(jobTypes, 0, 2) + require.NoError(t, err) + require.Len(t, received, 2) + require.Equal(t, received[0].Id, jobs[2].Id, "should've received newest job first") + require.Equal(t, received[1].Id, jobs[0].Id, "should've received second newest job second") + + received, err = ss.Job().GetAllByTypesPage(jobTypes, 2, 2) + require.NoError(t, err) + require.Len(t, received, 1) + require.Equal(t, received[0].Id, jobs[1].Id, "should've received oldest job last") +} + func testJobGetAllPage(t *testing.T, ss store.Store) { jobType := model.NewId() createAtTime := model.GetMillis() diff --git a/store/storetest/mocks/JobStore.go b/store/storetest/mocks/JobStore.go index 659ff0e55f..b3bac22f8c 100644 --- a/store/storetest/mocks/JobStore.go +++ b/store/storetest/mocks/JobStore.go @@ -127,6 +127,29 @@ func (_m *JobStore) GetAllByTypePage(jobType string, offset int, limit int) ([]* return r0, r1 } +// GetAllByTypesPage provides a mock function with given fields: jobTypes, offset, limit +func (_m *JobStore) GetAllByTypesPage(jobTypes []string, offset int, limit int) ([]*model.Job, error) { + ret := _m.Called(jobTypes, offset, limit) + + var r0 []*model.Job + if rf, ok := ret.Get(0).(func([]string, int, int) []*model.Job); ok { + r0 = rf(jobTypes, offset, limit) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Job) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func([]string, int, int) error); ok { + r1 = rf(jobTypes, offset, limit) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetAllPage provides a mock function with given fields: offset, limit func (_m *JobStore) GetAllPage(offset int, limit int) ([]*model.Job, error) { ret := _m.Called(offset, limit) diff --git a/store/timerlayer/timerlayer.go b/store/timerlayer/timerlayer.go index 4ab4c12413..d9bef90a2e 100644 --- a/store/timerlayer/timerlayer.go +++ b/store/timerlayer/timerlayer.go @@ -3809,6 +3809,22 @@ func (s *TimerLayerJobStore) GetAllByTypePage(jobType string, offset int, limit return result, err } +func (s *TimerLayerJobStore) GetAllByTypesPage(jobTypes []string, offset int, limit int) ([]*model.Job, error) { + start := timemodule.Now() + + result, err := s.JobStore.GetAllByTypesPage(jobTypes, offset, limit) + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if err == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("JobStore.GetAllByTypesPage", success, elapsed) + } + return result, err +} + func (s *TimerLayerJobStore) GetAllPage(offset int, limit int) ([]*model.Job, error) { start := timemodule.Now() diff --git a/testlib/store.go b/testlib/store.go index 1f8b520e21..884ffa4acc 100644 --- a/testlib/store.go +++ b/testlib/store.go @@ -50,6 +50,14 @@ func GetMockStoreForSetupFunctions() *mocks.Store { systemStore.On("GetByName", model.MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_BILLING_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_BILLING_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_SITE_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_SITE_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_AUTHENTICATION_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_AUTHENTICATION_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_COMPLIANCE_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_ENVIRONMENT_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_ENVIRONMENT_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_REPORTING_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_REPORTING_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS, Value: "true"}, nil) systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_REMOTE_CLUSTERS_PERMISSIONS, Value: "true"}, nil) systemStore.On("Get").Return(make(model.StringMap), nil)