Nested folders: Refactor folder update (#60323)

* Nested folders: Refactor folder update

* Apply suggestions from code review
This commit is contained in:
Sofia Papagiannaki
2022-12-20 15:00:33 +02:00
committed by GitHub
parent 5d4e35c3d5
commit 55b014974d
15 changed files with 267 additions and 148 deletions
+66 -35
View File
@@ -366,33 +366,33 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
return f, nil
}
func (s *Service) Update(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) (*folder.Folder, error) {
foldr, err := s.legacyUpdate(ctx, user, orgID, existingUid, cmd)
func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (*folder.Folder, error) {
if cmd.SignedInUser == nil {
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
}
user := cmd.SignedInUser
foldr, err := s.legacyUpdate(ctx, cmd)
if err != nil {
return nil, err
}
if s.features.IsEnabled(featuremgmt.FlagNestedFolders) {
if cmd.Uid != "" {
if !util.IsValidShortUID(cmd.Uid) {
if cmd.NewUID != nil && *cmd.NewUID != "" {
if !util.IsValidShortUID(*cmd.NewUID) {
return nil, dashboards.ErrDashboardInvalidUid
} else if util.IsShortUIDTooLong(cmd.Uid) {
} else if util.IsShortUIDTooLong(*cmd.NewUID) {
return nil, dashboards.ErrDashboardUidTooLong
}
}
getFolder, err := s.store.Get(ctx, folder.GetFolderQuery{
UID: &existingUid,
OrgID: orgID,
})
if err != nil {
return nil, err
}
foldr, err := s.store.Update(ctx, folder.UpdateFolderCommand{
Folder: getFolder,
NewUID: &cmd.Uid,
NewTitle: &cmd.Title,
NewDescription: &cmd.Description,
UID: cmd.UID,
OrgID: cmd.OrgID,
NewUID: cmd.NewUID,
NewTitle: cmd.NewTitle,
NewDescription: cmd.NewDescription,
SignedInUser: user,
})
if err != nil {
return nil, err
@@ -402,10 +402,10 @@ func (s *Service) Update(ctx context.Context, user *user.SignedInUser, orgID int
return foldr, nil
}
func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) (*folder.Folder, error) {
func (s *Service) legacyUpdate(ctx context.Context, cmd *folder.UpdateFolderCommand) (*folder.Folder, error) {
logger := s.log.FromContext(ctx)
query := models.GetDashboardQuery{OrgId: orgID, Uid: existingUid}
query := models.GetDashboardQuery{OrgId: cmd.OrgID, Uid: cmd.UID}
_, err := s.dashboardStore.GetDashboard(ctx, &query)
if err != nil {
return nil, toFolderError(err)
@@ -418,12 +418,17 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
return nil, dashboards.ErrFolderNotFound
}
cmd.UpdateDashboardModel(dashFolder, orgID, user.UserID)
if cmd.SignedInUser == nil {
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
}
user := cmd.SignedInUser
prepareForUpdate(dashFolder, cmd.OrgID, cmd.SignedInUser.UserID, cmd)
dto := &dashboards.SaveDashboardDTO{
Dashboard: dashFolder,
OrgId: orgID,
User: user,
OrgId: cmd.OrgID,
User: cmd.SignedInUser,
Overwrite: cmd.Overwrite,
}
@@ -438,7 +443,7 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
}
var foldr *folder.Folder
foldr, err = s.dashboardStore.GetFolderByID(ctx, orgID, dash.Id)
foldr, err = s.dashboardStore.GetFolderByID(ctx, cmd.OrgID, dash.Id)
if err != nil {
return nil, err
}
@@ -449,7 +454,7 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
Title: foldr.Title,
ID: dash.Id,
UID: dash.Uid,
OrgID: orgID,
OrgID: cmd.OrgID,
}); err != nil {
logger.Error("failed to publish FolderTitleUpdated event", "folder", foldr.Title, "user", user.UserID, "error", err)
}
@@ -457,6 +462,32 @@ func (s *Service) legacyUpdate(ctx context.Context, user *user.SignedInUser, org
return foldr, nil
}
// prepareForUpdate updates an existing dashboard model from command into model for folder update
func prepareForUpdate(dashFolder *models.Dashboard, orgId int64, userId int64, cmd *folder.UpdateFolderCommand) {
dashFolder.OrgId = orgId
title := dashFolder.Title
if cmd.NewTitle != nil && *cmd.NewTitle != "" {
title = *cmd.NewTitle
}
dashFolder.Title = strings.TrimSpace(title)
dashFolder.Data.Set("title", dashFolder.Title)
if cmd.NewUID != nil && *cmd.NewUID != "" {
dashFolder.SetUid(*cmd.NewUID)
}
dashFolder.SetVersion(cmd.Version)
dashFolder.IsFolder = true
if userId == 0 {
userId = -1
}
dashFolder.UpdatedBy = userId
dashFolder.UpdateSlug()
}
func (s *Service) DeleteFolder(ctx context.Context, cmd *folder.DeleteFolderCommand) error {
logger := s.log.FromContext(ctx)
if cmd.SignedInUser == nil {
@@ -501,23 +532,20 @@ func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*fol
return nil, folder.ErrBadRequest.Errorf("missing signed in user")
}
foldr, err := s.Get(ctx, &folder.GetFolderQuery{
UID: &cmd.UID,
OrgID: cmd.OrgID,
SignedInUser: cmd.SignedInUser,
})
g, err := guardian.NewByUID(ctx, cmd.UID, cmd.OrgID, cmd.SignedInUser)
if err != nil {
return nil, err
}
// if the new parent is the same as the current parent, we don't need to do anything
if foldr.ParentUID == cmd.NewParentUID {
return foldr, nil
if canSave, err := g.CanSave(); err != nil || !canSave {
if err != nil {
return nil, toFolderError(err)
}
return nil, dashboards.ErrFolderAccessDenied
}
// here we get the folder, we need to get the height of current folder
// and the depth of the new parent folder, the sum can't bypass 8
folderHeight, err := s.store.GetHeight(ctx, foldr.UID, cmd.OrgID, &cmd.NewParentUID)
folderHeight, err := s.store.GetHeight(ctx, cmd.UID, cmd.OrgID, &cmd.NewParentUID)
if err != nil {
return nil, err
}
@@ -533,13 +561,16 @@ func (s *Service) Move(ctx context.Context, cmd *folder.MoveFolderCommand) (*fol
// if the current folder is already a parent of newparent, we should return error
for _, parent := range parents {
if parent.UID == foldr.UID {
if parent.UID == cmd.UID {
return nil, folder.ErrCircularReference
}
}
return s.store.Update(ctx, folder.UpdateFolderCommand{
Folder: foldr,
UID: cmd.UID,
OrgID: cmd.OrgID,
NewParentUID: &cmd.NewParentUID,
SignedInUser: cmd.SignedInUser,
})
}