MM-63200: unrestricted local admin (#30295)
* use SessionHasPermissionToCheckRestrictedAdmin * allow unrestricted config edits from localmode * check model.PermissionManageSystem for getLatestVersion * simplify/clarify RequestTrialLicense semantics * rename for clarity * whitespace from linter --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ca9fd45408
Коммит
42274b9eee
@@ -18,16 +18,11 @@ 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.AppContext.Session(), model.PermissionPurgeBleveIndexes) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionPurgeBleveIndexes) {
|
||||
c.SetPermissionError(model.PermissionPurgeBleveIndexes)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("purgeBleveIndexes", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.App.PurgeBleveIndexes(c.AppContext); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
|
||||
@@ -15,16 +15,11 @@ func (api *API) InitCluster() {
|
||||
}
|
||||
|
||||
func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadEnvironmentHighAvailability) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionSysconsoleReadEnvironmentHighAvailability) {
|
||||
c.SetPermissionError(model.PermissionSysconsoleReadEnvironmentHighAvailability)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("getClusterStatus", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
infos := c.App.GetClusterStatus(c.AppContext)
|
||||
js, err := json.Marshal(infos)
|
||||
if err != nil {
|
||||
|
||||
@@ -19,9 +19,11 @@ import (
|
||||
"github.com/mattermost/mattermost/server/v8/config"
|
||||
)
|
||||
|
||||
var writeFilter func(c *Context, structField reflect.StructField) bool
|
||||
var readFilter func(c *Context, structField reflect.StructField) bool
|
||||
var permissionMap map[string]*model.Permission
|
||||
var (
|
||||
writeFilter func(c *Context, structField reflect.StructField) bool
|
||||
readFilter func(c *Context, structField reflect.StructField) bool
|
||||
permissionMap map[string]*model.Permission
|
||||
)
|
||||
|
||||
type filterType string
|
||||
|
||||
@@ -100,16 +102,11 @@ func configReload(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("configReload", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionReloadConfig) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionReloadConfig) {
|
||||
c.SetPermissionError(model.PermissionReloadConfig)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.AppContext.Session().IsUnrestricted() && *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("configReload", "api.restricted_system_admin", nil, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.App.ReloadConfig(); err != nil {
|
||||
c.Err = model.NewAppError("configReload", "api.config.reload_config.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
@@ -230,7 +227,7 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
//auditRec.AddEventResultState(cfg) // TODO we can do this too but do we want to? the config object is huge
|
||||
// auditRec.AddEventResultState(cfg) // TODO we can do this too but do we want to? the config object is huge
|
||||
auditRec.AddEventObjectType("config")
|
||||
auditRec.Success()
|
||||
c.LogAudit("updateConfig")
|
||||
@@ -406,12 +403,8 @@ func makeFilterConfigByPermission(accessType filterType) func(c *Context, struct
|
||||
|
||||
tagPermissions := strings.Split(structField.Tag.Get("access"), ",")
|
||||
|
||||
// If there are no access tag values and the role has manage_system, no need to continue
|
||||
// checking permissions.
|
||||
if len(tagPermissions) == 0 {
|
||||
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
|
||||
return true
|
||||
}
|
||||
if c.AppContext.Session().IsUnrestricted() {
|
||||
return true
|
||||
}
|
||||
|
||||
// one iteration for write_restrictable value, it could be anywhere in the order of values
|
||||
|
||||
@@ -39,16 +39,11 @@ func testElasticsearch(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 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.AppContext.Session(), model.PermissionTestElasticsearch) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionTestElasticsearch) {
|
||||
c.SetPermissionError(model.PermissionTestElasticsearch)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("testElasticsearch", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.App.TestElasticsearch(c.AppContext, cfg); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -61,16 +56,11 @@ 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.AppContext.Session(), model.PermissionPurgeElasticsearchIndexes) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionPurgeElasticsearchIndexes) {
|
||||
c.SetPermissionError(model.PermissionPurgeElasticsearchIndexes)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("purgeElasticsearchIndexes", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
specifiedIndexesQuery := r.URL.Query()["index"]
|
||||
if err := c.App.PurgeElasticsearchIndexes(c.AppContext, specifiedIndexesQuery); err != nil {
|
||||
c.Err = err
|
||||
|
||||
@@ -55,16 +55,11 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
defer c.LogAuditRec(auditRec)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("addLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
@@ -162,16 +157,11 @@ func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
defer c.LogAuditRec(auditRec)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("removeLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.App.Srv().RemoveLicense(); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -188,16 +178,11 @@ func requestTrialLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
defer c.LogAuditRec(auditRec)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("requestTrialLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if c.App.Srv().Platform().LicenseManager() == nil {
|
||||
c.Err = model.NewAppError("requestTrialLicense", "api.license.upgrade_needed.app_error", nil, "", http.StatusForbidden)
|
||||
return
|
||||
|
||||
@@ -83,13 +83,8 @@ func generateSupportPacket(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
const FileMime = "application/zip"
|
||||
const OutputDirectory = "support_packet"
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("generateSupportPacket", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Support Packet generation is limited to system admins (MM-42271).
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionManageSystem) {
|
||||
c.SetPermissionError(model.PermissionManageSystem)
|
||||
return
|
||||
}
|
||||
@@ -262,16 +257,11 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionTestEmail) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionTestEmail) {
|
||||
c.SetPermissionError(model.PermissionTestEmail)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("testEmail", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
appErr := c.App.TestEmail(c.AppContext, c.AppContext.Session().UserId, cfg)
|
||||
if appErr != nil {
|
||||
c.Err = appErr
|
||||
@@ -282,16 +272,11 @@ 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.AppContext.Session(), model.PermissionTestSiteURL) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionTestSiteURL) {
|
||||
c.SetPermissionError(model.PermissionTestSiteURL)
|
||||
return
|
||||
}
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("testSiteURL", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
props := model.MapFromJSON(r.Body)
|
||||
siteURL := props["site_url"]
|
||||
if siteURL == "" {
|
||||
@@ -333,7 +318,7 @@ 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.AppContext.Session(), model.PermissionRecycleDatabaseConnections) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionRecycleDatabaseConnections) {
|
||||
c.SetPermissionError(model.PermissionRecycleDatabaseConnections)
|
||||
return
|
||||
}
|
||||
@@ -341,11 +326,6 @@ func databaseRecycle(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("databaseRecycle", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("databaseRecycle", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
c.App.RecycleDatabaseConnection(c.AppContext)
|
||||
|
||||
auditRec.Success()
|
||||
@@ -353,7 +333,7 @@ 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.AppContext.Session(), model.PermissionInvalidateCaches) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionInvalidateCaches) {
|
||||
c.SetPermissionError(model.PermissionInvalidateCaches)
|
||||
return
|
||||
}
|
||||
@@ -361,11 +341,6 @@ func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("invalidateCaches", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("invalidateCaches", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
appErr := c.App.Srv().InvalidateAllCaches()
|
||||
if appErr != nil {
|
||||
c.Err = appErr
|
||||
@@ -382,12 +357,7 @@ func queryLogs(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("queryLogs", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("queryLogs", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionGetLogs) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionGetLogs) {
|
||||
c.SetPermissionError(model.PermissionGetLogs)
|
||||
return
|
||||
}
|
||||
@@ -430,12 +400,7 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("getLogs", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("getLogs", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionGetLogs) {
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionGetLogs) {
|
||||
c.SetPermissionError(model.PermissionGetLogs)
|
||||
return
|
||||
}
|
||||
@@ -457,11 +422,8 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
func downloadLogs(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord("downloadLogs", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("downloadLogs", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionGetLogs) {
|
||||
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionGetLogs) {
|
||||
c.SetPermissionError(model.PermissionGetLogs)
|
||||
return
|
||||
}
|
||||
@@ -563,8 +525,8 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func getLatestVersion(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
c.Err = model.NewAppError("latestVersion", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
if !c.App.SessionHasPermissionToAndNotRestrictedAdmin(*c.AppContext.Session(), model.PermissionManageSystem) {
|
||||
c.SetPermissionError(model.PermissionManageSystem)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1034,7 +996,6 @@ func getOnboarding(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
firstAdminCompleteSetupObj, err := c.App.GetOnboarding()
|
||||
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("getOnboarding", "app.system.get_onboarding_request.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
|
||||
@@ -21,6 +21,20 @@ func (a *App) SessionHasPermissionTo(session model.Session, permission *model.Pe
|
||||
return a.RolesGrantPermission(session.GetUserRoles(), permission.Id)
|
||||
}
|
||||
|
||||
// SessionHasPermissionToAndNotRestrictedAdmin is a variant of [App.SessionHasPermissionTo] that
|
||||
// denies access to restricted system admins. Note that a local session is always unrestricted.
|
||||
func (a *App) SessionHasPermissionToAndNotRestrictedAdmin(session model.Session, permission *model.Permission) bool {
|
||||
if session.IsUnrestricted() {
|
||||
return true
|
||||
}
|
||||
|
||||
if *a.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
return false
|
||||
}
|
||||
|
||||
return a.RolesGrantPermission(session.GetUserRoles(), permission.Id)
|
||||
}
|
||||
|
||||
func (a *App) SessionHasPermissionToAny(session model.Session, permissions []*model.Permission) bool {
|
||||
for _, perm := range permissions {
|
||||
if a.SessionHasPermissionTo(session, perm) {
|
||||
|
||||
@@ -21,6 +21,102 @@ import (
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store/storetest/mocks"
|
||||
)
|
||||
|
||||
func TestSessionHasPermissionTo(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
localSession := model.Session{
|
||||
UserId: th.BasicUser.Id,
|
||||
Roles: model.SystemUserRoleId,
|
||||
Local: true,
|
||||
}
|
||||
|
||||
adminSession := model.Session{
|
||||
UserId: th.SystemAdminUser.Id,
|
||||
Roles: model.SystemAdminRoleId,
|
||||
}
|
||||
|
||||
session := model.Session{
|
||||
UserId: th.BasicUser.Id,
|
||||
Roles: model.SystemUserRoleId,
|
||||
}
|
||||
|
||||
t.Run("basic user cannot manage system", func(t *testing.T) {
|
||||
require.False(t, th.App.SessionHasPermissionTo(session, model.PermissionManageSystem))
|
||||
})
|
||||
|
||||
t.Run("basic user generally has no global permissions", func(t *testing.T) {
|
||||
require.False(t, th.App.SessionHasPermissionTo(session, model.PermissionReadPublicChannel))
|
||||
})
|
||||
|
||||
t.Run("system admin can manage system", func(t *testing.T) {
|
||||
require.True(t, th.App.SessionHasPermissionTo(adminSession, model.PermissionManageSystem))
|
||||
})
|
||||
|
||||
t.Run("unrestricted session has all permissions", func(t *testing.T) {
|
||||
require.True(t, th.App.SessionHasPermissionTo(localSession, model.PermissionManageSystem))
|
||||
require.True(t, th.App.SessionHasPermissionTo(localSession, model.PermissionCreateBot))
|
||||
require.True(t, th.App.SessionHasPermissionTo(localSession, model.PermissionReadPublicChannel))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSessionHasPermissionToAndNotRestrictedAdmin(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
localSession := model.Session{
|
||||
UserId: th.BasicUser.Id,
|
||||
Roles: model.SystemUserRoleId,
|
||||
Local: true,
|
||||
}
|
||||
|
||||
adminSession := model.Session{
|
||||
UserId: th.SystemAdminUser.Id,
|
||||
Roles: model.SystemAdminRoleId,
|
||||
}
|
||||
|
||||
session := model.Session{
|
||||
UserId: th.BasicUser.Id,
|
||||
Roles: model.SystemUserRoleId,
|
||||
}
|
||||
|
||||
t.Run("basic user cannot manage system", func(t *testing.T) {
|
||||
require.False(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(session, model.PermissionManageSystem))
|
||||
})
|
||||
|
||||
t.Run("allow system admin when not restricted", func(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.ExperimentalSettings.RestrictSystemAdmin = false
|
||||
})
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(adminSession, model.PermissionManageSystem))
|
||||
})
|
||||
|
||||
t.Run("reject system admin when restricted", func(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.ExperimentalSettings.RestrictSystemAdmin = true
|
||||
})
|
||||
require.False(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(adminSession, model.PermissionManageSystem))
|
||||
})
|
||||
|
||||
t.Run("always allow unrestricted session", func(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.ExperimentalSettings.RestrictSystemAdmin = false
|
||||
})
|
||||
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(localSession, model.PermissionManageSystem))
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(localSession, model.PermissionCreateBot))
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(localSession, model.PermissionReadPublicChannel))
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.ExperimentalSettings.RestrictSystemAdmin = true
|
||||
})
|
||||
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(localSession, model.PermissionManageSystem))
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(localSession, model.PermissionCreateBot))
|
||||
require.True(t, th.App.SessionHasPermissionToAndNotRestrictedAdmin(localSession, model.PermissionReadPublicChannel))
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckIfRolesGrantPermission(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
@@ -18,10 +18,6 @@ func (ch *Channels) License() *model.License {
|
||||
}
|
||||
|
||||
func (ch *Channels) RequestTrialLicenseWithExtraFields(requesterID string, trialRequest *model.TrialLicenseRequest) *model.AppError {
|
||||
if *ch.srv.platform.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
return model.NewAppError("RequestTrialLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
}
|
||||
|
||||
requester, err := ch.srv.userService.GetUser(requesterID)
|
||||
if err != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
@@ -63,10 +59,6 @@ func (ch *Channels) RequestTrialLicenseWithExtraFields(requesterID string, trial
|
||||
|
||||
// Deprecated: Use RequestTrialLicenseWithExtraFields instead. This function remains to support the Plugin API.
|
||||
func (ch *Channels) RequestTrialLicense(requesterID string, users int, termsAccepted bool, receiveEmailsAccepted bool) *model.AppError {
|
||||
if *ch.srv.platform.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
return model.NewAppError("RequestTrialLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
}
|
||||
|
||||
if !termsAccepted {
|
||||
return model.NewAppError("RequestTrialLicense", "api.license.request-trial.bad-request.terms-not-accepted", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -1354,6 +1354,9 @@ func (api *PluginAPI) PublishPluginClusterEvent(ev model.PluginClusterEvent,
|
||||
|
||||
// RequestTrialLicense requests a trial license and installs it in the server
|
||||
func (api *PluginAPI) RequestTrialLicense(requesterID string, users int, termsAccepted bool, receiveEmailsAccepted bool) *model.AppError {
|
||||
// Normally, plugins are unrestricted in their abilities, but to maintain backwards compatbilibity with plugins
|
||||
// that were unaware of the nuances of ExperimentalSettings.RestrictSystemAdmin, we restrict the trial license
|
||||
// unconditionally.
|
||||
if *api.app.Config().ExperimentalSettings.RestrictSystemAdmin {
|
||||
return model.NewAppError("RequestTrialLicense", "api.restricted_system_admin", nil, "", http.StatusForbidden)
|
||||
}
|
||||
|
||||
@@ -3677,7 +3677,8 @@ const ConfigAccessTagAnySysConsoleRead = "*_read"
|
||||
// The 'access' tag '*_read' checks for any Sysconsole read permission and grants access if any read permission is allowed.
|
||||
//
|
||||
// By default config values can be written with PermissionManageSystem, but if ExperimentalSettings.RestrictSystemAdmin is true
|
||||
// and the access tag contains the value 'write_restrictable', then even PermissionManageSystem, does not grant write access.
|
||||
// and the access tag contains the value 'write_restrictable', then even PermissionManageSystem, does not grant write access
|
||||
// unless the request is made using local mode.
|
||||
//
|
||||
// PermissionManageSystem always grants read access.
|
||||
//
|
||||
|
||||
Ссылка в новой задаче
Block a user