Commit 26bb22bf by Daniel Lee Committed by GitHub

Merge pull request #11554 from grafana/11553_viewer_general_access

User with org viewer role permission fixes
parents 4a842f96 e73479ef
...@@ -224,6 +224,10 @@ func GetFolderUrl(folderUid string, slug string) string { ...@@ -224,6 +224,10 @@ func GetFolderUrl(folderUid string, slug string) string {
return fmt.Sprintf("%s/dashboards/f/%s/%s", setting.AppSubUrl, folderUid, slug) return fmt.Sprintf("%s/dashboards/f/%s/%s", setting.AppSubUrl, folderUid, slug)
} }
type ValidateDashboardBeforeSaveResult struct {
IsParentFolderChanged bool
}
// //
// COMMANDS // COMMANDS
// //
...@@ -268,6 +272,7 @@ type ValidateDashboardBeforeSaveCommand struct { ...@@ -268,6 +272,7 @@ type ValidateDashboardBeforeSaveCommand struct {
OrgId int64 OrgId int64
Dashboard *Dashboard Dashboard *Dashboard
Overwrite bool Overwrite bool
Result *ValidateDashboardBeforeSaveResult
} }
// //
......
...@@ -103,6 +103,16 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO, ...@@ -103,6 +103,16 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO,
return nil, err return nil, err
} }
if validateBeforeSaveCmd.Result.IsParentFolderChanged {
folderGuardian := guardian.New(dash.FolderId, dto.OrgId, dto.User)
if canSave, err := folderGuardian.CanSave(); err != nil || !canSave {
if err != nil {
return nil, err
}
return nil, models.ErrDashboardUpdateAccessDenied
}
}
guard := guardian.New(dash.GetDashboardIdForSavePermissionCheck(), dto.OrgId, dto.User) guard := guardian.New(dash.GetDashboardIdForSavePermissionCheck(), dto.OrgId, dto.User)
if canSave, err := guard.CanSave(); err != nil || !canSave { if canSave, err := guard.CanSave(); err != nil || !canSave {
if err != nil { if err != nil {
......
...@@ -51,6 +51,7 @@ func TestDashboardService(t *testing.T) { ...@@ -51,6 +51,7 @@ func TestDashboardService(t *testing.T) {
}) })
bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error { bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error {
cmd.Result = &models.ValidateDashboardBeforeSaveResult{}
return nil return nil
}) })
......
...@@ -32,6 +32,7 @@ func TestFolderService(t *testing.T) { ...@@ -32,6 +32,7 @@ func TestFolderService(t *testing.T) {
}) })
bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error { bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error {
cmd.Result = &models.ValidateDashboardBeforeSaveResult{}
return models.ErrDashboardUpdateAccessDenied return models.ErrDashboardUpdateAccessDenied
}) })
...@@ -92,6 +93,7 @@ func TestFolderService(t *testing.T) { ...@@ -92,6 +93,7 @@ func TestFolderService(t *testing.T) {
}) })
bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error { bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error {
cmd.Result = &models.ValidateDashboardBeforeSaveResult{}
return nil return nil
}) })
......
...@@ -544,6 +544,10 @@ func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *m.ValidateDash ...@@ -544,6 +544,10 @@ func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *m.ValidateDash
dash.SetId(existingByUid.Id) dash.SetId(existingByUid.Id)
dash.SetUid(existingByUid.Uid) dash.SetUid(existingByUid.Uid)
existing = existingByUid existing = existingByUid
if !dash.IsFolder {
cmd.Result.IsParentFolderChanged = true
}
} }
if (existing.IsFolder && !dash.IsFolder) || if (existing.IsFolder && !dash.IsFolder) ||
...@@ -551,6 +555,10 @@ func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *m.ValidateDash ...@@ -551,6 +555,10 @@ func getExistingDashboardByIdOrUidForUpdate(sess *DBSession, cmd *m.ValidateDash
return m.ErrDashboardTypeMismatch return m.ErrDashboardTypeMismatch
} }
if !dash.IsFolder && dash.FolderId != existing.FolderId {
cmd.Result.IsParentFolderChanged = true
}
// check for is someone else has written in between // check for is someone else has written in between
if dash.Version != existing.Version { if dash.Version != existing.Version {
if cmd.Overwrite { if cmd.Overwrite {
...@@ -586,6 +594,10 @@ func getExistingDashboardByTitleAndFolder(sess *DBSession, cmd *m.ValidateDashbo ...@@ -586,6 +594,10 @@ func getExistingDashboardByTitleAndFolder(sess *DBSession, cmd *m.ValidateDashbo
return m.ErrDashboardFolderWithSameNameAsDashboard return m.ErrDashboardFolderWithSameNameAsDashboard
} }
if !dash.IsFolder && (dash.FolderId != existing.FolderId || dash.Id == 0) {
cmd.Result.IsParentFolderChanged = true
}
if cmd.Overwrite { if cmd.Overwrite {
dash.SetId(existing.Id) dash.SetId(existing.Id)
dash.SetUid(existing.Uid) dash.SetUid(existing.Uid)
...@@ -599,6 +611,7 @@ func getExistingDashboardByTitleAndFolder(sess *DBSession, cmd *m.ValidateDashbo ...@@ -599,6 +611,7 @@ func getExistingDashboardByTitleAndFolder(sess *DBSession, cmd *m.ValidateDashbo
} }
func ValidateDashboardBeforeSave(cmd *m.ValidateDashboardBeforeSaveCommand) (err error) { func ValidateDashboardBeforeSave(cmd *m.ValidateDashboardBeforeSaveCommand) (err error) {
cmd.Result = &m.ValidateDashboardBeforeSaveResult{}
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
if err = getExistingDashboardByIdOrUidForUpdate(sess, cmd); err != nil { if err = getExistingDashboardByIdOrUidForUpdate(sess, cmd); err != nil {
return err return err
......
...@@ -19,9 +19,12 @@ export class FolderPickerCtrl { ...@@ -19,9 +19,12 @@ export class FolderPickerCtrl {
newFolderNameTouched: boolean; newFolderNameTouched: boolean;
hasValidationError: boolean; hasValidationError: boolean;
validationError: any; validationError: any;
isEditor: boolean;
/** @ngInject */ /** @ngInject */
constructor(private backendSrv, private validationSrv) { constructor(private backendSrv, private validationSrv, private contextSrv) {
this.isEditor = this.contextSrv.isEditor;
if (!this.labelClass) { if (!this.labelClass) {
this.labelClass = 'width-7'; this.labelClass = 'width-7';
} }
...@@ -38,19 +41,20 @@ export class FolderPickerCtrl { ...@@ -38,19 +41,20 @@ export class FolderPickerCtrl {
return this.backendSrv.get('api/search', params).then(result => { return this.backendSrv.get('api/search', params).then(result => {
if ( if (
query === '' || this.isEditor &&
(query === '' ||
query.toLowerCase() === 'g' || query.toLowerCase() === 'g' ||
query.toLowerCase() === 'ge' || query.toLowerCase() === 'ge' ||
query.toLowerCase() === 'gen' || query.toLowerCase() === 'gen' ||
query.toLowerCase() === 'gene' || query.toLowerCase() === 'gene' ||
query.toLowerCase() === 'gener' || query.toLowerCase() === 'gener' ||
query.toLowerCase() === 'genera' || query.toLowerCase() === 'genera' ||
query.toLowerCase() === 'general' query.toLowerCase() === 'general')
) { ) {
result.unshift({ title: this.rootName, id: 0 }); result.unshift({ title: this.rootName, id: 0 });
} }
if (this.enableCreateNew && query === '') { if (this.isEditor && this.enableCreateNew && query === '') {
result.unshift({ title: '-- New Folder --', id: -1 }); result.unshift({ title: '-- New Folder --', id: -1 });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment