diff --git a/pkg/services/store/service.go b/pkg/services/store/service.go index 480fee1b6eb..6278719602e 100644 --- a/pkg/services/store/service.go +++ b/pkg/services/store/service.go @@ -30,7 +30,13 @@ const RootResources = "resources" const RootDevenv = "devenv" const RootSystem = "system" -const SystemBrandingStorage = "system/branding" +const brandingStorage = "branding" +const SystemBrandingStorage = "system/" + brandingStorage + +var ( + SystemBrandingReader = &models.SignedInUser{OrgId: 1} + SystemBrandingAdmin = &models.SignedInUser{OrgId: 1} +) const MAX_UPLOAD_SIZE = 1 * 1024 * 1024 // 3MB @@ -129,7 +135,30 @@ func ProvideService(sql *sqlstore.SQLStore, features featuremgmt.FeatureToggles, } authService := newStaticStorageAuthService(func(ctx context.Context, user *models.SignedInUser, storageName string) map[string]filestorage.PathFilter { - if user == nil || !user.IsGrafanaAdmin { + if user == nil { + return nil + } + + if storageName == RootSystem { + if user == SystemBrandingReader { + return map[string]filestorage.PathFilter{ + ActionFilesRead: createSystemBrandingPathFilter(), + ActionFilesWrite: denyAllPathFilter, + ActionFilesDelete: denyAllPathFilter, + } + } + + if user == SystemBrandingAdmin { + systemBrandingFilter := createSystemBrandingPathFilter() + return map[string]filestorage.PathFilter{ + ActionFilesRead: systemBrandingFilter, + ActionFilesWrite: systemBrandingFilter, + ActionFilesDelete: systemBrandingFilter, + } + } + } + + if !user.IsGrafanaAdmin { return nil } @@ -152,12 +181,6 @@ func ProvideService(sql *sqlstore.SQLStore, features featuremgmt.FeatureToggles, ActionFilesWrite: allowAllPathFilter, ActionFilesDelete: allowAllPathFilter, } - case RootSystem: - return map[string]filestorage.PathFilter{ - ActionFilesRead: allowAllPathFilter, - ActionFilesWrite: allowAllPathFilter, - ActionFilesDelete: allowAllPathFilter, - } default: return nil } @@ -166,6 +189,14 @@ func ProvideService(sql *sqlstore.SQLStore, features featuremgmt.FeatureToggles, return newStandardStorageService(sql, globalRoots, initializeOrgStorages, authService) } +func createSystemBrandingPathFilter() filestorage.PathFilter { + return filestorage.NewPathFilter( + []string{filestorage.Delimiter + brandingStorage + filestorage.Delimiter}, // access to all folders and files inside `/branding/` + []string{filestorage.Delimiter + brandingStorage}, // access to the `/branding` folder itself, but not to any other sibling folder + nil, + nil) +} + func newStandardStorageService(sql *sqlstore.SQLStore, globalRoots []storageRuntime, initializeOrgStorages func(orgId int64) []storageRuntime, authService storageAuthService) *standardStorageService { rootsByOrgId := make(map[int64][]storageRuntime) rootsByOrgId[ac.GlobalOrgID] = globalRoots