diff --git a/pkg/api/dashboard_snapshot.go b/pkg/api/dashboard_snapshot.go index ff7d8da6124..aa8033a2d5c 100644 --- a/pkg/api/dashboard_snapshot.go +++ b/pkg/api/dashboard_snapshot.go @@ -114,9 +114,9 @@ func (hs *HTTPServer) CreateDashboardSnapshot(c *models.ReqContext) response.Res } var snapshotUrl string - cmd.ExternalUrl = "" - cmd.OrgId = c.OrgID - cmd.UserId = c.UserID + cmd.ExternalURL = "" + cmd.OrgID = c.OrgID + cmd.UserID = c.UserID originalDashboardURL, err := createOriginalDashboardURL(hs.Cfg.AppURL, &cmd) if err != nil { return response.Error(http.StatusInternalServerError, "Invalid app URL", err) @@ -137,8 +137,8 @@ func (hs *HTTPServer) CreateDashboardSnapshot(c *models.ReqContext) response.Res snapshotUrl = response.Url cmd.Key = response.Key cmd.DeleteKey = response.DeleteKey - cmd.ExternalUrl = response.Url - cmd.ExternalDeleteUrl = response.DeleteUrl + cmd.ExternalURL = response.Url + cmd.ExternalDeleteURL = response.DeleteUrl cmd.Dashboard = simplejson.New() metrics.MApiDashboardSnapshotExternal.Inc() @@ -168,7 +168,8 @@ func (hs *HTTPServer) CreateDashboardSnapshot(c *models.ReqContext) response.Res metrics.MApiDashboardSnapshotCreate.Inc() } - if err := hs.dashboardsnapshotsService.CreateDashboardSnapshot(c.Req.Context(), &cmd); err != nil { + result, err := hs.dashboardsnapshotsService.CreateDashboardSnapshot(c.Req.Context(), &cmd) + if err != nil { c.JsonApiErr(http.StatusInternalServerError, "Failed to create snapshot", err) return nil } @@ -178,7 +179,7 @@ func (hs *HTTPServer) CreateDashboardSnapshot(c *models.ReqContext) response.Res "deleteKey": cmd.DeleteKey, "url": snapshotUrl, "deleteUrl": setting.ToAbsUrl("api/snapshots-delete/" + cmd.DeleteKey), - "id": cmd.Result.Id, + "id": result.ID, }) return nil } @@ -201,12 +202,12 @@ func (hs *HTTPServer) GetDashboardSnapshot(c *models.ReqContext) response.Respon query := &dashboardsnapshots.GetDashboardSnapshotQuery{Key: key} - err := hs.dashboardsnapshotsService.GetDashboardSnapshot(c.Req.Context(), query) + queryResult, err := hs.dashboardsnapshotsService.GetDashboardSnapshot(c.Req.Context(), query) if err != nil { return response.Err(err) } - snapshot := query.Result + snapshot := queryResult // expired snapshots should also be removed from db if snapshot.Expires.Before(time.Now()) { @@ -279,19 +280,19 @@ func (hs *HTTPServer) DeleteDashboardSnapshotByDeleteKey(c *models.ReqContext) r } query := &dashboardsnapshots.GetDashboardSnapshotQuery{DeleteKey: key} - err := hs.dashboardsnapshotsService.GetDashboardSnapshot(c.Req.Context(), query) + queryResult, err := hs.dashboardsnapshotsService.GetDashboardSnapshot(c.Req.Context(), query) if err != nil { return response.Err(err) } - if query.Result.External { - err := deleteExternalDashboardSnapshot(query.Result.ExternalDeleteUrl) + if queryResult.External { + err := deleteExternalDashboardSnapshot(queryResult.ExternalDeleteURL) if err != nil { return response.Error(500, "Failed to delete external dashboard", err) } } - cmd := &dashboardsnapshots.DeleteDashboardSnapshotCommand{DeleteKey: query.Result.DeleteKey} + cmd := &dashboardsnapshots.DeleteDashboardSnapshotCommand{DeleteKey: queryResult.DeleteKey} if err := hs.dashboardsnapshotsService.DeleteDashboardSnapshot(c.Req.Context(), cmd); err != nil { return response.Error(500, "Failed to delete dashboard snapshot", err) @@ -299,7 +300,7 @@ func (hs *HTTPServer) DeleteDashboardSnapshotByDeleteKey(c *models.ReqContext) r return response.JSON(http.StatusOK, util.DynMap{ "message": "Snapshot deleted. It might take an hour before it's cleared from any CDN caches.", - "id": query.Result.Id, + "id": queryResult.ID, }) } @@ -320,16 +321,16 @@ func (hs *HTTPServer) DeleteDashboardSnapshot(c *models.ReqContext) response.Res query := &dashboardsnapshots.GetDashboardSnapshotQuery{Key: key} - err := hs.dashboardsnapshotsService.GetDashboardSnapshot(c.Req.Context(), query) + queryResult, err := hs.dashboardsnapshotsService.GetDashboardSnapshot(c.Req.Context(), query) if err != nil { return response.Err(err) } - if query.Result == nil { + if queryResult == nil { return response.Error(http.StatusNotFound, "Failed to get dashboard snapshot", nil) } - if query.Result.External { - err := deleteExternalDashboardSnapshot(query.Result.ExternalDeleteUrl) + if queryResult.External { + err := deleteExternalDashboardSnapshot(queryResult.ExternalDeleteURL) if err != nil { return response.Error(http.StatusInternalServerError, "Failed to delete external dashboard", err) } @@ -339,7 +340,7 @@ func (hs *HTTPServer) DeleteDashboardSnapshot(c *models.ReqContext) response.Res // which before RBAC would result in a dashboard which has no ACL. A dashboard without an ACL would fallback // to the user’s org role, which for editors and admins would essentially always be allowed here. With RBAC, // all permissions must be explicit, so the lack of a rule for dashboard 0 means the guardian will reject. - dashboardID := query.Result.Dashboard.Get("id").MustInt64() + dashboardID := queryResult.Dashboard.Get("id").MustInt64() if dashboardID != 0 { guardian, err := guardian.New(c.Req.Context(), dashboardID, c.OrgID, c.SignedInUser) @@ -353,12 +354,12 @@ func (hs *HTTPServer) DeleteDashboardSnapshot(c *models.ReqContext) response.Res return response.Error(http.StatusInternalServerError, "Error while checking permissions for snapshot", err) } - if !canEdit && query.Result.UserId != c.SignedInUser.UserID && !errors.Is(err, dashboards.ErrDashboardNotFound) { + if !canEdit && queryResult.UserID != c.SignedInUser.UserID && !errors.Is(err, dashboards.ErrDashboardNotFound) { return response.Error(http.StatusForbidden, "Access denied to this snapshot", nil) } } - cmd := &dashboardsnapshots.DeleteDashboardSnapshotCommand{DeleteKey: query.Result.DeleteKey} + cmd := &dashboardsnapshots.DeleteDashboardSnapshotCommand{DeleteKey: queryResult.DeleteKey} if err := hs.dashboardsnapshotsService.DeleteDashboardSnapshot(c.Req.Context(), cmd); err != nil { return response.Error(http.StatusInternalServerError, "Failed to delete dashboard snapshot", err) @@ -366,7 +367,7 @@ func (hs *HTTPServer) DeleteDashboardSnapshot(c *models.ReqContext) response.Res return response.JSON(http.StatusOK, util.DynMap{ "message": "Snapshot deleted. It might take an hour before it's cleared from any CDN caches.", - "id": query.Result.Id, + "id": queryResult.ID, }) } @@ -388,25 +389,25 @@ func (hs *HTTPServer) SearchDashboardSnapshots(c *models.ReqContext) response.Re searchQuery := dashboardsnapshots.GetDashboardSnapshotsQuery{ Name: query, Limit: limit, - OrgId: c.OrgID, + OrgID: c.OrgID, SignedInUser: c.SignedInUser, } - err := hs.dashboardsnapshotsService.SearchDashboardSnapshots(c.Req.Context(), &searchQuery) + searchQueryResult, err := hs.dashboardsnapshotsService.SearchDashboardSnapshots(c.Req.Context(), &searchQuery) if err != nil { return response.Error(500, "Search failed", err) } - dtos := make([]*dashboardsnapshots.DashboardSnapshotDTO, len(searchQuery.Result)) - for i, snapshot := range searchQuery.Result { + dtos := make([]*dashboardsnapshots.DashboardSnapshotDTO, len(searchQueryResult)) + for i, snapshot := range searchQueryResult { dtos[i] = &dashboardsnapshots.DashboardSnapshotDTO{ - Id: snapshot.Id, + ID: snapshot.ID, Name: snapshot.Name, Key: snapshot.Key, - OrgId: snapshot.OrgId, - UserId: snapshot.UserId, + OrgID: snapshot.OrgID, + UserID: snapshot.UserID, External: snapshot.External, - ExternalUrl: snapshot.ExternalUrl, + ExternalURL: snapshot.ExternalURL, Expires: snapshot.Expires, Created: snapshot.Created, Updated: snapshot.Updated, diff --git a/pkg/api/dashboard_snapshot_test.go b/pkg/api/dashboard_snapshot_test.go index f6afee1cf02..a80eec50d8b 100644 --- a/pkg/api/dashboard_snapshot_test.go +++ b/pkg/api/dashboard_snapshot_test.go @@ -41,25 +41,22 @@ func TestDashboardSnapshotAPIEndpoint_singleSnapshot(t *testing.T) { dashSnapSvc := dashboardsnapshots.NewMockService(t) dashSnapSvc.On("DeleteDashboardSnapshot", mock.Anything, mock.AnythingOfType("*dashboardsnapshots.DeleteDashboardSnapshotCommand")).Return(nil).Maybe() - dashSnapSvc.On("GetDashboardSnapshot", mock.Anything, mock.AnythingOfType("*dashboardsnapshots.GetDashboardSnapshotQuery")).Run(func(args mock.Arguments) { - q := args.Get(1).(*dashboardsnapshots.GetDashboardSnapshotQuery) - res := &dashboardsnapshots.DashboardSnapshot{ - Id: 1, - Key: "12345", - DeleteKey: "54321", - Dashboard: jsonModel, - Expires: time.Now().Add(time.Duration(1000) * time.Second), - UserId: 999999, - } - if userId != 0 { - res.UserId = userId - } - if deleteUrl != "" { - res.External = true - res.ExternalDeleteUrl = deleteUrl - } - q.Result = res - }).Return(nil) + res := &dashboardsnapshots.DashboardSnapshot{ + ID: 1, + Key: "12345", + DeleteKey: "54321", + Dashboard: jsonModel, + Expires: time.Now().Add(time.Duration(1000) * time.Second), + UserID: 999999, + } + if userId != 0 { + res.UserID = userId + } + if deleteUrl != "" { + res.External = true + res.ExternalDeleteURL = deleteUrl + } + dashSnapSvc.On("GetDashboardSnapshot", mock.Anything, mock.AnythingOfType("*dashboardsnapshots.GetDashboardSnapshotQuery")).Return(res, nil) dashSnapSvc.On("DeleteDashboardSnapshot", mock.Anything, mock.AnythingOfType("*dashboardsnapshots.DeleteDashboardSnapshotCommand")).Return(nil).Maybe() return dashSnapSvc } @@ -256,7 +253,7 @@ func TestGetDashboardSnapshotNotFound(t *testing.T) { dashSnapSvc. On("GetDashboardSnapshot", mock.Anything, mock.AnythingOfType("*dashboardsnapshots.GetDashboardSnapshotQuery")). Run(func(args mock.Arguments) {}). - Return(dashboardsnapshots.ErrBaseNotFound.Errorf("")) + Return(nil, dashboardsnapshots.ErrBaseNotFound.Errorf("")) return dashSnapSvc } @@ -305,7 +302,7 @@ func TestGetDashboardSnapshotFailure(t *testing.T) { dashSnapSvc. On("GetDashboardSnapshot", mock.Anything, mock.AnythingOfType("*dashboardsnapshots.GetDashboardSnapshotQuery")). Run(func(args mock.Arguments) {}). - Return(errors.New("something went wrong")) + Return(nil, errors.New("something went wrong")) return dashSnapSvc } diff --git a/pkg/services/dashboardsnapshots/database/database.go b/pkg/services/dashboardsnapshots/database/database.go index 443f1ea9077..a303b3810a1 100644 --- a/pkg/services/dashboardsnapshots/database/database.go +++ b/pkg/services/dashboardsnapshots/database/database.go @@ -45,8 +45,9 @@ func (d *DashboardSnapshotStore) DeleteExpiredSnapshots(ctx context.Context, cmd }) } -func (d *DashboardSnapshotStore) CreateDashboardSnapshot(ctx context.Context, cmd *dashboardsnapshots.CreateDashboardSnapshotCommand) error { - return d.store.WithTransactionalDbSession(ctx, func(sess *db.Session) error { +func (d *DashboardSnapshotStore) CreateDashboardSnapshot(ctx context.Context, cmd *dashboardsnapshots.CreateDashboardSnapshotCommand) (*dashboardsnapshots.DashboardSnapshot, error) { + var result *dashboardsnapshots.DashboardSnapshot + err := d.store.WithTransactionalDbSession(ctx, func(sess *db.Session) error { var expires = time.Now().Add(time.Hour * 24 * 365 * 50) if cmd.Expires > 0 { expires = time.Now().Add(time.Second * time.Duration(cmd.Expires)) @@ -56,11 +57,11 @@ func (d *DashboardSnapshotStore) CreateDashboardSnapshot(ctx context.Context, cm Name: cmd.Name, Key: cmd.Key, DeleteKey: cmd.DeleteKey, - OrgId: cmd.OrgId, - UserId: cmd.UserId, + OrgID: cmd.OrgID, + UserID: cmd.UserID, External: cmd.External, - ExternalUrl: cmd.ExternalUrl, - ExternalDeleteUrl: cmd.ExternalDeleteUrl, + ExternalURL: cmd.ExternalURL, + ExternalDeleteURL: cmd.ExternalDeleteURL, Dashboard: simplejson.New(), DashboardEncrypted: cmd.DashboardEncrypted, Expires: expires, @@ -68,10 +69,14 @@ func (d *DashboardSnapshotStore) CreateDashboardSnapshot(ctx context.Context, cm Updated: time.Now(), } _, err := sess.Insert(snapshot) - cmd.Result = snapshot + result = snapshot return err }) + if err != nil { + return nil, err + } + return result, nil } func (d *DashboardSnapshotStore) DeleteDashboardSnapshot(ctx context.Context, cmd *dashboardsnapshots.DeleteDashboardSnapshotCommand) error { @@ -82,8 +87,9 @@ func (d *DashboardSnapshotStore) DeleteDashboardSnapshot(ctx context.Context, cm }) } -func (d *DashboardSnapshotStore) GetDashboardSnapshot(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotQuery) error { - return d.store.WithDbSession(ctx, func(sess *db.Session) error { +func (d *DashboardSnapshotStore) GetDashboardSnapshot(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotQuery) (*dashboardsnapshots.DashboardSnapshot, error) { + var queryResult *dashboardsnapshots.DashboardSnapshot + err := d.store.WithDbSession(ctx, func(sess *db.Session) error { snapshot := dashboardsnapshots.DashboardSnapshot{Key: query.Key, DeleteKey: query.DeleteKey} has, err := sess.Get(&snapshot) @@ -93,15 +99,20 @@ func (d *DashboardSnapshotStore) GetDashboardSnapshot(ctx context.Context, query return dashboardsnapshots.ErrBaseNotFound.Errorf("dashboard snapshot not found") } - query.Result = &snapshot + queryResult = &snapshot return nil }) + if err != nil { + return nil, err + } + return queryResult, nil } // SearchDashboardSnapshots returns a list of all snapshots for admins // for other roles, it returns snapshots created by the user -func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotsQuery) error { - return d.store.WithDbSession(ctx, func(sess *db.Session) error { +func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotsQuery) (dashboardsnapshots.DashboardSnapshotsList, error) { + var queryResult dashboardsnapshots.DashboardSnapshotsList + err := d.store.WithDbSession(ctx, func(sess *db.Session) error { var snapshots = make(dashboardsnapshots.DashboardSnapshotsList, 0) if query.Limit > 0 { sess.Limit(query.Limit) @@ -115,16 +126,20 @@ func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, q // admins can see all snapshots, everyone else can only see their own snapshots switch { case query.SignedInUser.OrgRole == org.RoleAdmin: - sess.Where("org_id = ?", query.OrgId) + sess.Where("org_id = ?", query.OrgID) case !query.SignedInUser.IsAnonymous: - sess.Where("org_id = ? AND user_id = ?", query.OrgId, query.SignedInUser.UserID) + sess.Where("org_id = ? AND user_id = ?", query.OrgID, query.SignedInUser.UserID) default: - query.Result = snapshots + queryResult = snapshots return nil } err := sess.Find(&snapshots) - query.Result = snapshots + queryResult = snapshots return err }) + if err != nil { + return dashboardsnapshots.DashboardSnapshotsList{}, err + } + return queryResult, nil } diff --git a/pkg/services/dashboardsnapshots/database/database_test.go b/pkg/services/dashboardsnapshots/database/database_test.go index 5d8d052175a..6df8b42bcca 100644 --- a/pkg/services/dashboardsnapshots/database/database_test.go +++ b/pkg/services/dashboardsnapshots/database/database_test.go @@ -43,23 +43,23 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { cmd := dashboardsnapshots.CreateDashboardSnapshotCommand{ Key: "hej", DashboardEncrypted: encryptedDashboard, - UserId: 1000, - OrgId: 1, + UserID: 1000, + OrgID: 1, } - err = dashStore.CreateDashboardSnapshot(context.Background(), &cmd) + result, err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd) require.NoError(t, err) t.Run("Should be able to get snapshot by key", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotQuery{Key: "hej"} - err := dashStore.GetDashboardSnapshot(context.Background(), &query) + queryResult, err := dashStore.GetDashboardSnapshot(context.Background(), &query) require.NoError(t, err) - assert.NotNil(t, query.Result) + assert.NotNil(t, queryResult) decryptedDashboard, err := secretsService.Decrypt( context.Background(), - query.Result.DashboardEncrypted, + queryResult.DashboardEncrypted, ) require.NoError(t, err) @@ -71,43 +71,43 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { t.Run("And the user has the admin role", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: 1, + OrgID: 1, SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin}, } - err := dashStore.SearchDashboardSnapshots(context.Background(), &query) + queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) t.Run("Should return all the snapshots", func(t *testing.T) { - assert.NotNil(t, query.Result) - assert.Len(t, query.Result, 1) + assert.NotNil(t, queryResult) + assert.Len(t, queryResult, 1) }) }) t.Run("And the user has the editor role and has created a snapshot", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: 1, + OrgID: 1, SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserID: 1000}, } - err := dashStore.SearchDashboardSnapshots(context.Background(), &query) + queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) t.Run("Should return all the snapshots", func(t *testing.T) { - require.NotNil(t, query.Result) - assert.Len(t, query.Result, 1) + require.NotNil(t, queryResult) + assert.Len(t, queryResult, 1) }) }) t.Run("And the user has the editor role and has not created any snapshot", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: 1, + OrgID: 1, SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserID: 2}, } - err := dashStore.SearchDashboardSnapshots(context.Background(), &query) + queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) t.Run("Should not return any snapshots", func(t *testing.T) { - require.NotNil(t, query.Result) - assert.Empty(t, query.Result) + require.NotNil(t, queryResult) + assert.Empty(t, queryResult) }) }) @@ -118,29 +118,29 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) { Dashboard: simplejson.NewFromAny(map[string]interface{}{ "hello": "mupp", }), - UserId: 0, - OrgId: 1, + UserID: 0, + OrgID: 1, } - err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd) + _, err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd) require.NoError(t, err) t.Run("Should not return any snapshots", func(t *testing.T) { query := dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: 1, + OrgID: 1, SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, IsAnonymous: true, UserID: 0}, } - err := dashStore.SearchDashboardSnapshots(context.Background(), &query) + queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) - require.NotNil(t, query.Result) - assert.Empty(t, query.Result) + require.NotNil(t, queryResult) + assert.Empty(t, queryResult) }) }) t.Run("Should have encrypted dashboard data", func(t *testing.T) { decryptedDashboard, err := secretsService.Decrypt( context.Background(), - cmd.Result.DashboardEncrypted, + result.DashboardEncrypted, ) require.NoError(t, err) @@ -167,27 +167,27 @@ func TestIntegrationDeleteExpiredSnapshots(t *testing.T) { require.NoError(t, err) query := dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: 1, + OrgID: 1, SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin}, } - err = dashStore.SearchDashboardSnapshots(context.Background(), &query) + queryResult, err := dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) - assert.Len(t, query.Result, 1) - assert.Equal(t, nonExpiredSnapshot.Key, query.Result[0].Key) + assert.Len(t, queryResult, 1) + assert.Equal(t, nonExpiredSnapshot.Key, queryResult[0].Key) err = dashStore.DeleteExpiredSnapshots(context.Background(), &dashboardsnapshots.DeleteExpiredSnapshotsCommand{}) require.NoError(t, err) query = dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: 1, + OrgID: 1, SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin}, } - err = dashStore.SearchDashboardSnapshots(context.Background(), &query) + queryResult, err = dashStore.SearchDashboardSnapshots(context.Background(), &query) require.NoError(t, err) - require.Len(t, query.Result, 1) - require.Equal(t, nonExpiredSnapshot.Key, query.Result[0].Key) + require.Len(t, queryResult, 1) + require.Equal(t, nonExpiredSnapshot.Key, queryResult[0].Key) }) } @@ -198,22 +198,22 @@ func createTestSnapshot(t *testing.T, dashStore *DashboardSnapshotStore, key str Dashboard: simplejson.NewFromAny(map[string]interface{}{ "hello": "mupp", }), - UserId: 1000, - OrgId: 1, + UserID: 1000, + OrgID: 1, Expires: expires, } - err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd) + result, err := dashStore.CreateDashboardSnapshot(context.Background(), &cmd) require.NoError(t, err) // Set expiry date manually - to be able to create expired snapshots if expires < 0 { expireDate := time.Now().Add(time.Second * time.Duration(expires)) err = dashStore.store.WithDbSession(context.Background(), func(sess *db.Session) error { - _, err := sess.Exec("UPDATE dashboard_snapshot SET expires = ? WHERE id = ?", expireDate, cmd.Result.Id) + _, err := sess.Exec("UPDATE dashboard_snapshot SET expires = ? WHERE id = ?", expireDate, result.ID) return err }) require.NoError(t, err) } - return cmd.Result + return result } diff --git a/pkg/services/dashboardsnapshots/models.go b/pkg/services/dashboardsnapshots/models.go index b527c6dcfc0..e145113b73c 100644 --- a/pkg/services/dashboardsnapshots/models.go +++ b/pkg/services/dashboardsnapshots/models.go @@ -9,15 +9,15 @@ import ( // DashboardSnapshot model type DashboardSnapshot struct { - Id int64 + ID int64 `xorm:"pk autoincr 'id'"` Name string Key string DeleteKey string - OrgId int64 - UserId int64 + OrgID int64 `xorm:"org_id"` + UserID int64 `xorm:"user_id"` External bool - ExternalUrl string - ExternalDeleteUrl string + ExternalURL string `xorm:"external_url"` + ExternalDeleteURL string `xorm:"external_delete_url"` Expires time.Time Created time.Time @@ -29,13 +29,13 @@ type DashboardSnapshot struct { // DashboardSnapshotDTO without dashboard map type DashboardSnapshotDTO struct { - Id int64 `json:"id"` + ID int64 `json:"id" xorm:"id"` Name string `json:"name"` Key string `json:"key"` - OrgId int64 `json:"orgId"` - UserId int64 `json:"userId"` + OrgID int64 `json:"orgId" xorm:"org_id"` + UserID int64 `json:"userId" xorm:"user_id"` External bool `json:"external"` - ExternalUrl string `json:"externalUrl"` + ExternalURL string `json:"externalUrl" xorm:"external_url"` Expires time.Time `json:"expires"` Created time.Time `json:"created"` @@ -63,8 +63,8 @@ type CreateDashboardSnapshotCommand struct { // required:false // default: false External bool `json:"external"` - ExternalUrl string `json:"-"` - ExternalDeleteUrl string `json:"-"` + ExternalURL string `json:"-"` + ExternalDeleteURL string `json:"-"` // Define the unique key. Required if `external` is `true`. // required:false @@ -73,12 +73,10 @@ type CreateDashboardSnapshotCommand struct { // required:false DeleteKey string `json:"deleteKey"` - OrgId int64 `json:"-"` - UserId int64 `json:"-"` + OrgID int64 `json:"-"` + UserID int64 `json:"-"` DashboardEncrypted []byte `json:"-"` - - Result *DashboardSnapshot } type DeleteDashboardSnapshotCommand struct { @@ -92,8 +90,6 @@ type DeleteExpiredSnapshotsCommand struct { type GetDashboardSnapshotQuery struct { Key string DeleteKey string - - Result *DashboardSnapshot } type DashboardSnapshotsList []*DashboardSnapshotDTO @@ -101,8 +97,6 @@ type DashboardSnapshotsList []*DashboardSnapshotDTO type GetDashboardSnapshotsQuery struct { Name string Limit int - OrgId int64 + OrgID int64 SignedInUser *user.SignedInUser - - Result DashboardSnapshotsList } diff --git a/pkg/services/dashboardsnapshots/service.go b/pkg/services/dashboardsnapshots/service.go index dd63c6476d9..ae229d27fed 100644 --- a/pkg/services/dashboardsnapshots/service.go +++ b/pkg/services/dashboardsnapshots/service.go @@ -6,9 +6,9 @@ import ( //go:generate mockery --name Service --structname MockService --inpackage --filename service_mock.go type Service interface { - CreateDashboardSnapshot(context.Context, *CreateDashboardSnapshotCommand) error + CreateDashboardSnapshot(context.Context, *CreateDashboardSnapshotCommand) (*DashboardSnapshot, error) DeleteDashboardSnapshot(context.Context, *DeleteDashboardSnapshotCommand) error DeleteExpiredSnapshots(context.Context, *DeleteExpiredSnapshotsCommand) error - GetDashboardSnapshot(context.Context, *GetDashboardSnapshotQuery) error - SearchDashboardSnapshots(context.Context, *GetDashboardSnapshotsQuery) error + GetDashboardSnapshot(context.Context, *GetDashboardSnapshotQuery) (*DashboardSnapshot, error) + SearchDashboardSnapshots(context.Context, *GetDashboardSnapshotsQuery) (DashboardSnapshotsList, error) } diff --git a/pkg/services/dashboardsnapshots/service/service.go b/pkg/services/dashboardsnapshots/service/service.go index 4a8b26cae87..247f0e7aec9 100644 --- a/pkg/services/dashboardsnapshots/service/service.go +++ b/pkg/services/dashboardsnapshots/service/service.go @@ -25,15 +25,15 @@ func ProvideService(store dashboardsnapshots.Store, secretsService secrets.Servi return s } -func (s *ServiceImpl) CreateDashboardSnapshot(ctx context.Context, cmd *dashboardsnapshots.CreateDashboardSnapshotCommand) error { +func (s *ServiceImpl) CreateDashboardSnapshot(ctx context.Context, cmd *dashboardsnapshots.CreateDashboardSnapshotCommand) (*dashboardsnapshots.DashboardSnapshot, error) { marshalledData, err := cmd.Dashboard.Encode() if err != nil { - return err + return nil, err } encryptedDashboard, err := s.secretsService.Encrypt(ctx, marshalledData, secrets.WithoutScope()) if err != nil { - return err + return nil, err } cmd.DashboardEncrypted = encryptedDashboard @@ -41,34 +41,34 @@ func (s *ServiceImpl) CreateDashboardSnapshot(ctx context.Context, cmd *dashboar return s.store.CreateDashboardSnapshot(ctx, cmd) } -func (s *ServiceImpl) GetDashboardSnapshot(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotQuery) error { - err := s.store.GetDashboardSnapshot(ctx, query) +func (s *ServiceImpl) GetDashboardSnapshot(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotQuery) (*dashboardsnapshots.DashboardSnapshot, error) { + queryResult, err := s.store.GetDashboardSnapshot(ctx, query) if err != nil { - return err + return nil, err } - if query.Result.DashboardEncrypted != nil { - decryptedDashboard, err := s.secretsService.Decrypt(ctx, query.Result.DashboardEncrypted) + if queryResult.DashboardEncrypted != nil { + decryptedDashboard, err := s.secretsService.Decrypt(ctx, queryResult.DashboardEncrypted) if err != nil { - return err + return nil, err } dashboard, err := simplejson.NewJson(decryptedDashboard) if err != nil { - return err + return nil, err } - query.Result.Dashboard = dashboard + queryResult.Dashboard = dashboard } - return err + return queryResult, err } func (s *ServiceImpl) DeleteDashboardSnapshot(ctx context.Context, cmd *dashboardsnapshots.DeleteDashboardSnapshotCommand) error { return s.store.DeleteDashboardSnapshot(ctx, cmd) } -func (s *ServiceImpl) SearchDashboardSnapshots(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotsQuery) error { +func (s *ServiceImpl) SearchDashboardSnapshots(ctx context.Context, query *dashboardsnapshots.GetDashboardSnapshotsQuery) (dashboardsnapshots.DashboardSnapshotsList, error) { return s.store.SearchDashboardSnapshots(ctx, query) } diff --git a/pkg/services/dashboardsnapshots/service/service_test.go b/pkg/services/dashboardsnapshots/service/service_test.go index 88a72ee6273..27ef9761518 100644 --- a/pkg/services/dashboardsnapshots/service/service_test.go +++ b/pkg/services/dashboardsnapshots/service/service_test.go @@ -42,10 +42,10 @@ func TestDashboardSnapshotsService(t *testing.T) { Dashboard: dashboard, } - err = s.CreateDashboardSnapshot(ctx, &cmd) + result, err := s.CreateDashboardSnapshot(ctx, &cmd) require.NoError(t, err) - decrypted, err := s.secretsService.Decrypt(ctx, cmd.Result.DashboardEncrypted) + decrypted, err := s.secretsService.Decrypt(ctx, result.DashboardEncrypted) require.NoError(t, err) require.Equal(t, rawDashboard, decrypted) @@ -59,10 +59,10 @@ func TestDashboardSnapshotsService(t *testing.T) { DeleteKey: dashboardKey, } - err := s.GetDashboardSnapshot(ctx, &query) + queryResult, err := s.GetDashboardSnapshot(ctx, &query) require.NoError(t, err) - decrypted, err := query.Result.Dashboard.Encode() + decrypted, err := queryResult.Dashboard.Encode() require.NoError(t, err) require.Equal(t, rawDashboard, decrypted) diff --git a/pkg/services/dashboardsnapshots/service_mock.go b/pkg/services/dashboardsnapshots/service_mock.go index efca62367bf..95ae9708c92 100644 --- a/pkg/services/dashboardsnapshots/service_mock.go +++ b/pkg/services/dashboardsnapshots/service_mock.go @@ -1,10 +1,9 @@ -// Code generated by mockery v2.12.2. DO NOT EDIT. +// Code generated by mockery v2.16.0. DO NOT EDIT. package dashboardsnapshots import ( context "context" - testing "testing" mock "github.com/stretchr/testify/mock" ) @@ -15,17 +14,26 @@ type MockService struct { } // CreateDashboardSnapshot provides a mock function with given fields: _a0, _a1 -func (_m *MockService) CreateDashboardSnapshot(_a0 context.Context, _a1 *CreateDashboardSnapshotCommand) error { +func (_m *MockService) CreateDashboardSnapshot(_a0 context.Context, _a1 *CreateDashboardSnapshotCommand) (*DashboardSnapshot, error) { ret := _m.Called(_a0, _a1) - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *CreateDashboardSnapshotCommand) error); ok { + var r0 *DashboardSnapshot + if rf, ok := ret.Get(0).(func(context.Context, *CreateDashboardSnapshotCommand) *DashboardSnapshot); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*DashboardSnapshot) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *CreateDashboardSnapshotCommand) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // DeleteDashboardSnapshot provides a mock function with given fields: _a0, _a1 @@ -57,35 +65,58 @@ func (_m *MockService) DeleteExpiredSnapshots(_a0 context.Context, _a1 *DeleteEx } // GetDashboardSnapshot provides a mock function with given fields: _a0, _a1 -func (_m *MockService) GetDashboardSnapshot(_a0 context.Context, _a1 *GetDashboardSnapshotQuery) error { +func (_m *MockService) GetDashboardSnapshot(_a0 context.Context, _a1 *GetDashboardSnapshotQuery) (*DashboardSnapshot, error) { ret := _m.Called(_a0, _a1) - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *GetDashboardSnapshotQuery) error); ok { + var r0 *DashboardSnapshot + if rf, ok := ret.Get(0).(func(context.Context, *GetDashboardSnapshotQuery) *DashboardSnapshot); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*DashboardSnapshot) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *GetDashboardSnapshotQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // SearchDashboardSnapshots provides a mock function with given fields: _a0, _a1 -func (_m *MockService) SearchDashboardSnapshots(_a0 context.Context, _a1 *GetDashboardSnapshotsQuery) error { +func (_m *MockService) SearchDashboardSnapshots(_a0 context.Context, _a1 *GetDashboardSnapshotsQuery) (DashboardSnapshotsList, error) { ret := _m.Called(_a0, _a1) - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *GetDashboardSnapshotsQuery) error); ok { + var r0 DashboardSnapshotsList + if rf, ok := ret.Get(0).(func(context.Context, *GetDashboardSnapshotsQuery) DashboardSnapshotsList); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(DashboardSnapshotsList) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *GetDashboardSnapshotsQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// NewMockService creates a new instance of MockService. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations. -func NewMockService(t testing.TB) *MockService { +type mockConstructorTestingTNewMockService interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockService(t mockConstructorTestingTNewMockService) *MockService { mock := &MockService{} mock.Mock.Test(t) diff --git a/pkg/services/dashboardsnapshots/store.go b/pkg/services/dashboardsnapshots/store.go index 392c21f795d..b11c0189aef 100644 --- a/pkg/services/dashboardsnapshots/store.go +++ b/pkg/services/dashboardsnapshots/store.go @@ -5,9 +5,9 @@ import ( ) type Store interface { - CreateDashboardSnapshot(context.Context, *CreateDashboardSnapshotCommand) error + CreateDashboardSnapshot(context.Context, *CreateDashboardSnapshotCommand) (*DashboardSnapshot, error) DeleteDashboardSnapshot(context.Context, *DeleteDashboardSnapshotCommand) error DeleteExpiredSnapshots(context.Context, *DeleteExpiredSnapshotsCommand) error - GetDashboardSnapshot(context.Context, *GetDashboardSnapshotQuery) error - SearchDashboardSnapshots(context.Context, *GetDashboardSnapshotsQuery) error + GetDashboardSnapshot(context.Context, *GetDashboardSnapshotQuery) (*DashboardSnapshot, error) + SearchDashboardSnapshots(context.Context, *GetDashboardSnapshotsQuery) (DashboardSnapshotsList, error) } diff --git a/pkg/services/export/entity_store.go b/pkg/services/export/entity_store.go index c6f3af1a4d3..57bd79eae94 100644 --- a/pkg/services/export/entity_store.go +++ b/pkg/services/export/entity_store.go @@ -256,34 +256,34 @@ func (e *entityStoreJob) start(ctx context.Context) { rowUser.OrgID = orgId rowUser.UserID = 1 cmd := &dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: orgId, + OrgID: orgId, Limit: 500000, SignedInUser: rowUser, } - err := e.dashboardsnapshots.SearchDashboardSnapshots(ctx, cmd) + result, err := e.dashboardsnapshots.SearchDashboardSnapshots(ctx, cmd) if err != nil { e.status.Status = "error: " + err.Error() return } - for _, dto := range cmd.Result { + for _, dto := range result { m := snapshot.Model{ Name: dto.Name, - ExternalURL: dto.ExternalUrl, + ExternalURL: dto.ExternalURL, Expires: dto.Expires.UnixMilli(), } - rowUser.OrgID = dto.OrgId - rowUser.UserID = dto.UserId + rowUser.OrgID = dto.OrgID + rowUser.UserID = dto.UserID snapcmd := &dashboardsnapshots.GetDashboardSnapshotQuery{ Key: dto.Key, } - err = e.dashboardsnapshots.GetDashboardSnapshot(ctx, snapcmd) + snapcmdResult, err := e.dashboardsnapshots.GetDashboardSnapshot(ctx, snapcmd) if err == nil { - res := snapcmd.Result + res := snapcmdResult m.DeleteKey = res.DeleteKey - m.ExternalURL = res.ExternalUrl + m.ExternalURL = res.ExternalURL snap := res.Dashboard m.DashboardUID = snap.Get("uid").MustString("") diff --git a/pkg/services/export/export_snapshots.go b/pkg/services/export/export_snapshots.go index 24195a23693..715e93d087d 100644 --- a/pkg/services/export/export_snapshots.go +++ b/pkg/services/export/export_snapshots.go @@ -10,7 +10,7 @@ import ( func exportSnapshots(helper *commitHelper, job *gitExportJob) error { cmd := &dashboardsnapshots.GetDashboardSnapshotsQuery{ - OrgId: helper.orgID, + OrgID: helper.orgID, Limit: 500000, SignedInUser: nil, } @@ -18,12 +18,12 @@ func exportSnapshots(helper *commitHelper, job *gitExportJob) error { return fmt.Errorf("snapshots requires an admin user") } - err := job.dashboardsnapshotsService.SearchDashboardSnapshots(helper.ctx, cmd) + result, err := job.dashboardsnapshotsService.SearchDashboardSnapshots(helper.ctx, cmd) if err != nil { return err } - if len(cmd.Result) < 1 { + if len(result) < 1 { return nil // nothing } @@ -32,9 +32,9 @@ func exportSnapshots(helper *commitHelper, job *gitExportJob) error { comment: "Export snapshots", } - for _, snapshot := range cmd.Result { + for _, snapshot := range result { gitcmd.body = append(gitcmd.body, commitBody{ - fpath: filepath.Join(helper.orgDir, "snapshot", fmt.Sprintf("%d-snapshot.json", snapshot.Id)), + fpath: filepath.Join(helper.orgDir, "snapshot", fmt.Sprintf("%d-snapshot.json", snapshot.ID)), body: prettyJSON(snapshot), }) }