| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-12-01 22:43:31 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 	"github.com/stretchr/testify/mock" | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/dtos" | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/response" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/api/routing" | 
					
						
							| 
									
										
										
										
											2020-03-04 19:57:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol" | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/annotations" | 
					
						
							| 
									
										
										
										
											2022-05-18 02:52:22 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/dashboards" | 
					
						
							| 
									
										
										
										
											2022-03-21 17:49:49 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/guardian" | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/org" | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore" | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore/mockstore" | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | func TestAnnotationsAPIEndpoint(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	hs := setupSimpleHTTPServer(nil) | 
					
						
							|  |  |  | 	store := sqlstore.InitTestDB(t) | 
					
						
							|  |  |  | 	store.Cfg = hs.Cfg | 
					
						
							|  |  |  | 	hs.SQLStore = store | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	t.Run("Given an annotation without a dashboard ID", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		cmd := dtos.PostAnnotationsCmd{ | 
					
						
							| 
									
										
										
										
											2019-08-16 16:49:30 +08:00
										 |  |  | 			Time: 1000, | 
					
						
							|  |  |  | 			Text: "annotation text", | 
					
						
							|  |  |  | 			Tags: []string{"tag1", "tag2"}, | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		updateCmd := dtos.UpdateAnnotationsCmd{ | 
					
						
							| 
									
										
										
										
											2019-08-16 16:49:30 +08:00
										 |  |  | 			Time: 1000, | 
					
						
							|  |  |  | 			Text: "annotation text", | 
					
						
							|  |  |  | 			Tags: []string{"tag1", "tag2"}, | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 		patchCmd := dtos.PatchAnnotationsCmd{ | 
					
						
							|  |  |  | 			Time: 1000, | 
					
						
							|  |  |  | 			Text: "annotation text", | 
					
						
							|  |  |  | 			Tags: []string{"tag1", "tag2"}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		t.Run("When user is an Org Viewer", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 			role := org.RoleViewer | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 			t.Run("Should not be allowed to save an annotation", func(t *testing.T) { | 
					
						
							|  |  |  | 				postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 					cmd, store, nil, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 403, sc.resp.Code) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				putAnnotationScenario(t, "When calling PUT on", "/api/annotations/1", "/api/annotations/:annotationId", | 
					
						
							|  |  |  | 					role, updateCmd, func(sc *scenarioContext) { | 
					
						
							|  |  |  | 						sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 403, sc.resp.Code) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				patchAnnotationScenario(t, "When calling PATCH on", "/api/annotations/1", | 
					
						
							|  |  |  | 					"/api/annotations/:annotationId", role, patchCmd, func(sc *scenarioContext) { | 
					
						
							|  |  |  | 						sc.fakeReqWithParams("PATCH", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 403, sc.resp.Code) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 				mock := mockstore.NewSQLStoreMock() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/annotations/1", | 
					
						
							|  |  |  | 					"/api/annotations/:annotationId", role, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 						fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						annotations.SetRepository(fakeAnnoRepo) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 						sc.handlerFunc = hs.DeleteAnnotationByID | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 403, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 					}, mock) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		t.Run("When user is an Org Editor", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 			role := org.RoleEditor | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 			t.Run("Should be able to save an annotation", func(t *testing.T) { | 
					
						
							|  |  |  | 				postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 					cmd, store, nil, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				putAnnotationScenario(t, "When calling PUT on", "/api/annotations/1", "/api/annotations/:annotationId", role, updateCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 					sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				patchAnnotationScenario(t, "When calling PATCH on", "/api/annotations/1", "/api/annotations/:annotationId", role, patchCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 					sc.fakeReqWithParams("PATCH", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 				mock := mockstore.NewSQLStoreMock() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/annotations/1", | 
					
						
							|  |  |  | 					"/api/annotations/:annotationId", role, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 						fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						annotations.SetRepository(fakeAnnoRepo) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 						sc.handlerFunc = hs.DeleteAnnotationByID | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 					}, mock) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	t.Run("Given an annotation with a dashboard ID and the dashboard does not have an ACL", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		cmd := dtos.PostAnnotationsCmd{ | 
					
						
							|  |  |  | 			Time:        1000, | 
					
						
							|  |  |  | 			Text:        "annotation text", | 
					
						
							|  |  |  | 			Tags:        []string{"tag1", "tag2"}, | 
					
						
							|  |  |  | 			DashboardId: 1, | 
					
						
							|  |  |  | 			PanelId:     1, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 		dashboardUIDCmd := dtos.PostAnnotationsCmd{ | 
					
						
							|  |  |  | 			Time:         1000, | 
					
						
							|  |  |  | 			Text:         "annotation text", | 
					
						
							|  |  |  | 			Tags:         []string{"tag1", "tag2"}, | 
					
						
							|  |  |  | 			DashboardUID: "home", | 
					
						
							|  |  |  | 			PanelId:      1, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		updateCmd := dtos.UpdateAnnotationsCmd{ | 
					
						
							| 
									
										
										
										
											2019-08-16 16:49:30 +08:00
										 |  |  | 			Time: 1000, | 
					
						
							|  |  |  | 			Text: "annotation text", | 
					
						
							|  |  |  | 			Tags: []string{"tag1", "tag2"}, | 
					
						
							|  |  |  | 			Id:   1, | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 		patchCmd := dtos.PatchAnnotationsCmd{ | 
					
						
							|  |  |  | 			Time: 8000, | 
					
						
							|  |  |  | 			Text: "annotation text 50", | 
					
						
							|  |  |  | 			Tags: []string{"foo", "bar"}, | 
					
						
							|  |  |  | 			Id:   1, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		deleteCmd := dtos.MassDeleteAnnotationsCmd{ | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 			DashboardId: 1, | 
					
						
							|  |  |  | 			PanelId:     1, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 		deleteWithDashboardUIDCmd := dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 			DashboardUID: "home", | 
					
						
							|  |  |  | 			PanelId:      1, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		t.Run("When user is an Org Viewer", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 			role := org.RoleViewer | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 			t.Run("Should not be allowed to save an annotation", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 				postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 					sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 403, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				putAnnotationScenario(t, "When calling PUT on", "/api/annotations/1", "/api/annotations/:annotationId", role, updateCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 					sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 403, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				patchAnnotationScenario(t, "When calling PATCH on", "/api/annotations/1", "/api/annotations/:annotationId", role, patchCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 					sc.fakeReqWithParams("PATCH", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 403, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 				mock := mockstore.NewSQLStoreMock() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/annotations/1", | 
					
						
							|  |  |  | 					"/api/annotations/:annotationId", role, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 						setUpACL() | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 						fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						annotations.SetRepository(fakeAnnoRepo) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 						sc.handlerFunc = hs.DeleteAnnotationByID | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 403, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 					}, mock) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		t.Run("When user is an Org Editor", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 			role := org.RoleEditor | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 			t.Run("Should be able to save an annotation", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 				postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 					sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				putAnnotationScenario(t, "When calling PUT on", "/api/annotations/1", "/api/annotations/:annotationId", role, updateCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 					sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				patchAnnotationScenario(t, "When calling PATCH on", "/api/annotations/1", "/api/annotations/:annotationId", role, patchCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 					sc.fakeReqWithParams("PATCH", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 				mock := mockstore.NewSQLStoreMock() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				loggedInUserScenarioWithRole(t, "When calling DELETE on", "DELETE", "/api/annotations/1", | 
					
						
							|  |  |  | 					"/api/annotations/:annotationId", role, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 						setUpACL() | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 						fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						annotations.SetRepository(fakeAnnoRepo) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 						sc.handlerFunc = hs.DeleteAnnotationByID | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 					}, mock) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		t.Run("When user is an Admin", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 			role := org.RoleAdmin | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 			mockStore := mockstore.NewSQLStoreMock() | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 			t.Run("Should be able to do anything", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 				postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, cmd, store, nil, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 					setUpACL() | 
					
						
							|  |  |  | 					sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 				dashSvc := dashboards.NewFakeDashboardService(t) | 
					
						
							|  |  |  | 				dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) { | 
					
						
							|  |  |  | 					q := args.Get(1).(*models.GetDashboardQuery) | 
					
						
							|  |  |  | 					q.Result = &models.Dashboard{ | 
					
						
							|  |  |  | 						Id:  q.Id, | 
					
						
							|  |  |  | 						Uid: q.Uid, | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}).Return(nil) | 
					
						
							|  |  |  | 				postAnnotationScenario(t, "When calling POST on", "/api/annotations", "/api/annotations", role, dashboardUIDCmd, mockStore, dashSvc, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 					sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 					dashSvc.AssertCalled(t, "GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")) | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				putAnnotationScenario(t, "When calling PUT on", "/api/annotations/1", "/api/annotations/:annotationId", role, updateCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 					sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				patchAnnotationScenario(t, "When calling PATCH on", "/api/annotations/1", "/api/annotations/:annotationId", role, patchCmd, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 					setUpACL() | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 					sc.fakeReqWithParams("PATCH", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 				deleteAnnotationsScenario(t, "When calling POST on", "/api/annotations/mass-delete", | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 					"/api/annotations/mass-delete", role, deleteCmd, store, nil, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 						setUpACL() | 
					
						
							|  |  |  | 						sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 				dashSvc = dashboards.NewFakeDashboardService(t) | 
					
						
							|  |  |  | 				dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) { | 
					
						
							|  |  |  | 					q := args.Get(1).(*models.GetDashboardQuery) | 
					
						
							|  |  |  | 					q.Result = &models.Dashboard{ | 
					
						
							|  |  |  | 						Id:  1, | 
					
						
							|  |  |  | 						Uid: deleteWithDashboardUIDCmd.DashboardUID, | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}).Return(nil) | 
					
						
							| 
									
										
										
										
											2022-05-02 17:35:36 +08:00
										 |  |  | 				deleteAnnotationsScenario(t, "When calling POST with dashboardUID on", "/api/annotations/mass-delete", | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 					"/api/annotations/mass-delete", role, deleteWithDashboardUIDCmd, mockStore, dashSvc, func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 						setUpACL() | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 						sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 						assert.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 						dashSvc.AssertCalled(t, "GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")) | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 					}) | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type fakeAnnotationsRepo struct { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	annotations map[int64]annotations.Item | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewFakeAnnotationsRepo() *fakeAnnotationsRepo { | 
					
						
							|  |  |  | 	return &fakeAnnotationsRepo{ | 
					
						
							|  |  |  | 		annotations: map[int64]annotations.Item{}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-26 01:23:09 +08:00
										 |  |  | func (repo *fakeAnnotationsRepo) Delete(_ context.Context, params *annotations.DeleteParams) error { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	if params.Id != 0 { | 
					
						
							|  |  |  | 		delete(repo.annotations, params.Id) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		for _, v := range repo.annotations { | 
					
						
							|  |  |  | 			if params.DashboardId == v.DashboardId && params.PanelId == v.PanelId { | 
					
						
							|  |  |  | 				delete(repo.annotations, v.Id) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func (repo *fakeAnnotationsRepo) Save(item *annotations.Item) error { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	if item.Id == 0 { | 
					
						
							|  |  |  | 		item.Id = int64(len(repo.annotations) + 1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	repo.annotations[item.Id] = *item | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-22 19:20:57 +08:00
										 |  |  | func (repo *fakeAnnotationsRepo) Update(_ context.Context, item *annotations.Item) error { | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-22 19:20:57 +08:00
										 |  |  | func (repo *fakeAnnotationsRepo) Find(_ context.Context, query *annotations.ItemQuery) ([]*annotations.ItemDTO, error) { | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	if annotation, has := repo.annotations[query.AnnotationId]; has { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		return []*annotations.ItemDTO{{Id: annotation.Id, DashboardId: annotation.DashboardId}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	annotations := []*annotations.ItemDTO{{Id: 1, DashboardId: 0}} | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	return annotations, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-26 01:23:09 +08:00
										 |  |  | func (repo *fakeAnnotationsRepo) FindTags(_ context.Context, query *annotations.TagsQuery) (annotations.FindTagsResult, error) { | 
					
						
							| 
									
										
										
										
											2021-06-30 19:42:54 +08:00
										 |  |  | 	result := annotations.FindTagsResult{ | 
					
						
							|  |  |  | 		Tags: []*annotations.TagsDTO{}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | func (repo *fakeAnnotationsRepo) LoadItems() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | var fakeAnnoRepo *fakeAnnotationsRepo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | func postAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType, | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 	cmd dtos.PostAnnotationsCmd, store sqlstore.Store, dashSvc dashboards.DashboardService, fn scenarioFunc) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 		hs := setupSimpleHTTPServer(nil) | 
					
						
							|  |  |  | 		hs.SQLStore = store | 
					
						
							| 
									
										
										
										
											2022-07-07 02:42:39 +08:00
										 |  |  | 		hs.DashboardService = dashSvc | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		sc := setupScenarioContext(t, url) | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 		sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			c.Req.Body = mockRequestBody(cmd) | 
					
						
							| 
									
										
										
										
											2022-02-09 20:44:38 +08:00
										 |  |  | 			c.Req.Header.Add("Content-Type", "application/json") | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			sc.context = c | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			sc.context.UserID = testUserID | 
					
						
							|  |  |  | 			sc.context.OrgID = testOrgID | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			sc.context.OrgRole = role | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			return hs.PostAnnotation(c) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sc.m.Post(routePattern, sc.defaultHandler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		fn(sc) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | func putAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType, | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	cmd dtos.UpdateAnnotationsCmd, fn scenarioFunc) { | 
					
						
							|  |  |  | 	t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 		hs := setupSimpleHTTPServer(nil) | 
					
						
							|  |  |  | 		store := sqlstore.InitTestDB(t) | 
					
						
							|  |  |  | 		store.Cfg = hs.Cfg | 
					
						
							|  |  |  | 		hs.SQLStore = store | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		sc := setupScenarioContext(t, url) | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 		sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			c.Req.Body = mockRequestBody(cmd) | 
					
						
							| 
									
										
										
										
											2022-02-09 20:44:38 +08:00
										 |  |  | 			c.Req.Header.Add("Content-Type", "application/json") | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			sc.context = c | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			sc.context.UserID = testUserID | 
					
						
							|  |  |  | 			sc.context.OrgID = testOrgID | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 			sc.context.OrgRole = role | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			return hs.UpdateAnnotation(c) | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 		annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sc.m.Put(routePattern, sc.defaultHandler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		fn(sc) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | func patchAnnotationScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType, cmd dtos.PatchAnnotationsCmd, fn scenarioFunc) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 		hs := setupSimpleHTTPServer(nil) | 
					
						
							|  |  |  | 		store := sqlstore.InitTestDB(t) | 
					
						
							|  |  |  | 		store.Cfg = hs.Cfg | 
					
						
							|  |  |  | 		hs.SQLStore = store | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		sc := setupScenarioContext(t, url) | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 		sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			c.Req.Body = mockRequestBody(cmd) | 
					
						
							| 
									
										
										
										
											2022-02-09 20:44:38 +08:00
										 |  |  | 			c.Req.Header.Add("Content-Type", "application/json") | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 			sc.context = c | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			sc.context.UserID = testUserID | 
					
						
							|  |  |  | 			sc.context.OrgID = testOrgID | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 			sc.context.OrgRole = role | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			return hs.PatchAnnotation(c) | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2019-01-27 19:49:22 +08:00
										 |  |  | 		annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sc.m.Patch(routePattern, sc.defaultHandler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		fn(sc) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | func deleteAnnotationsScenario(t *testing.T, desc string, url string, routePattern string, role org.RoleType, | 
					
						
							| 
									
										
										
										
											2022-05-23 23:14:27 +08:00
										 |  |  | 	cmd dtos.MassDeleteAnnotationsCmd, store sqlstore.Store, dashSvc dashboards.DashboardService, fn scenarioFunc) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 		hs := setupSimpleHTTPServer(nil) | 
					
						
							|  |  |  | 		hs.SQLStore = store | 
					
						
							| 
									
										
										
										
											2022-07-07 02:42:39 +08:00
										 |  |  | 		hs.DashboardService = dashSvc | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		sc := setupScenarioContext(t, url) | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 		sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			c.Req.Body = mockRequestBody(cmd) | 
					
						
							| 
									
										
										
										
											2022-02-09 20:44:38 +08:00
										 |  |  | 			c.Req.Header.Add("Content-Type", "application/json") | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 			sc.context = c | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			sc.context.UserID = testUserID | 
					
						
							|  |  |  | 			sc.context.OrgID = testOrgID | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 			sc.context.OrgRole = role | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 			return hs.MassDeleteAnnotations(c) | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2018-06-25 19:58:49 +08:00
										 |  |  | 		annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sc.m.Post(routePattern, sc.defaultHandler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		fn(sc) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestAPI_Annotations_AccessControl(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-11 21:37:31 +08:00
										 |  |  | 	sc := setupHTTPServer(t, true) | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	setInitCtxSignedInEditor(sc.initCtx) | 
					
						
							|  |  |  | 	_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID) | 
					
						
							|  |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	dashboardAnnotation := &annotations.Item{Id: 1, DashboardId: 1} | 
					
						
							|  |  |  | 	organizationAnnotation := &annotations.Item{Id: 2, DashboardId: 0} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(dashboardAnnotation) | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(organizationAnnotation) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 	annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	postOrganizationCmd := dtos.PostAnnotationsCmd{ | 
					
						
							|  |  |  | 		Time:    1000, | 
					
						
							|  |  |  | 		Text:    "annotation text", | 
					
						
							|  |  |  | 		Tags:    []string{"tag1", "tag2"}, | 
					
						
							|  |  |  | 		PanelId: 1, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	postDashboardCmd := dtos.PostAnnotationsCmd{ | 
					
						
							|  |  |  | 		Time:        1000, | 
					
						
							|  |  |  | 		Text:        "annotation text", | 
					
						
							|  |  |  | 		Tags:        []string{"tag1", "tag2"}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 		DashboardId: 1, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		PanelId:     1, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	updateCmd := dtos.UpdateAnnotationsCmd{ | 
					
						
							|  |  |  | 		Time: 1000, | 
					
						
							|  |  |  | 		Text: "annotation text", | 
					
						
							|  |  |  | 		Tags: []string{"tag1", "tag2"}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	patchCmd := dtos.PatchAnnotationsCmd{ | 
					
						
							|  |  |  | 		Time: 1000, | 
					
						
							|  |  |  | 		Text: "annotation text", | 
					
						
							|  |  |  | 		Tags: []string{"tag1", "tag2"}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 	postGraphiteCmd := dtos.PostGraphiteAnnotationsCmd{ | 
					
						
							|  |  |  | 		When: 1000, | 
					
						
							|  |  |  | 		What: "annotation text", | 
					
						
							|  |  |  | 		Data: "Deploy", | 
					
						
							|  |  |  | 		Tags: []string{"tag1", "tag2"}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	type args struct { | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 		permissions []accesscontrol.Permission | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		url         string | 
					
						
							|  |  |  | 		body        io.Reader | 
					
						
							|  |  |  | 		method      string | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tests := []struct { | 
					
						
							|  |  |  | 		name string | 
					
						
							|  |  |  | 		args args | 
					
						
							|  |  |  | 		want int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl getting annotations with correct permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: accesscontrol.ScopeAnnotationsAll}}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 				url:         "/api/annotations", | 
					
						
							|  |  |  | 				method:      http.MethodGet, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			want: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl getting annotations without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 				url:         "/api/annotations", | 
					
						
							|  |  |  | 				method:      http.MethodGet, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			want: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl getting annotation by ID with correct permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: accesscontrol.ScopeAnnotationsAll}}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 				url:         "/api/annotations/1", | 
					
						
							|  |  |  | 				method:      http.MethodGet, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl getting annotation by ID without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 				url:         "/api/annotations", | 
					
						
							|  |  |  | 				method:      http.MethodGet, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl getting tags for annotations with correct permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead}}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 				url:         "/api/annotations/tags", | 
					
						
							|  |  |  | 				method:      http.MethodGet, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			want: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl getting tags for annotations without correct permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite}}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 				url:         "/api/annotations/tags", | 
					
						
							|  |  |  | 				method:      http.MethodGet, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			want: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl update dashboard annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/1", | 
					
						
							|  |  |  | 				method: http.MethodPut, | 
					
						
							|  |  |  | 				body:   mockRequestBody(updateCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl update dashboard annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 				url:         "/api/annotations/1", | 
					
						
							|  |  |  | 				method:      http.MethodPut, | 
					
						
							|  |  |  | 				body:        mockRequestBody(updateCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl update organization annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsAll, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/2", | 
					
						
							|  |  |  | 				method: http.MethodPut, | 
					
						
							|  |  |  | 				body:   mockRequestBody(updateCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl update organization annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/2", | 
					
						
							|  |  |  | 				method: http.MethodPut, | 
					
						
							|  |  |  | 				body:   mockRequestBody(updateCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl patch dashboard annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/1", | 
					
						
							|  |  |  | 				method: http.MethodPatch, | 
					
						
							|  |  |  | 				body:   mockRequestBody(patchCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl patch dashboard annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 				url:         "/api/annotations/1", | 
					
						
							|  |  |  | 				method:      http.MethodPatch, | 
					
						
							|  |  |  | 				body:        mockRequestBody(patchCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl patch organization annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsAll, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/2", | 
					
						
							|  |  |  | 				method: http.MethodPatch, | 
					
						
							|  |  |  | 				body:   mockRequestBody(patchCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl patch organization annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/2", | 
					
						
							|  |  |  | 				method: http.MethodPatch, | 
					
						
							|  |  |  | 				body:   mockRequestBody(patchCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create dashboard annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations", | 
					
						
							|  |  |  | 				method: http.MethodPost, | 
					
						
							|  |  |  | 				body:   mockRequestBody(postDashboardCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create dashboard annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 				url:         "/api/annotations", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body:        mockRequestBody(postDashboardCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-04-20 15:43:42 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create dashboard annotation with incorrect permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-04-20 15:43:42 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeOrganization, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations", | 
					
						
							|  |  |  | 				method: http.MethodPost, | 
					
						
							|  |  |  | 				body:   mockRequestBody(postDashboardCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create organization annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsAll, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations", | 
					
						
							|  |  |  | 				method: http.MethodPost, | 
					
						
							|  |  |  | 				body:   mockRequestBody(postOrganizationCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create organization annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations", | 
					
						
							|  |  |  | 				method: http.MethodPost, | 
					
						
							|  |  |  | 				body:   mockRequestBody(postOrganizationCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl delete dashboard annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/1", | 
					
						
							|  |  |  | 				method: http.MethodDelete, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl delete dashboard annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 				url:         "/api/annotations/1", | 
					
						
							|  |  |  | 				method:      http.MethodDelete, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl delete organization annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsAll, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/2", | 
					
						
							|  |  |  | 				method: http.MethodDelete, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl delete organization annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/2", | 
					
						
							|  |  |  | 				method: http.MethodDelete, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create graphite annotation with permissions is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsAll, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/graphite", | 
					
						
							|  |  |  | 				method: http.MethodPost, | 
					
						
							|  |  |  | 				body:   mockRequestBody(postGraphiteCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl create organization annotation without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 					Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				url:    "/api/annotations/graphite", | 
					
						
							|  |  |  | 				method: http.MethodPost, | 
					
						
							|  |  |  | 				body:   mockRequestBody(postGraphiteCmd), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.name, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-21 20:31:02 +08:00
										 |  |  | 			setUpRBACGuardian(t) | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 			sc.acmock. | 
					
						
							| 
									
										
										
										
											2022-05-02 15:29:30 +08:00
										 |  |  | 				RegisterScopeAttributeResolver(AnnotationTypeScopeResolver()) | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			setAccessControlPermissions(sc.acmock, tt.args.permissions, sc.initCtx.OrgID) | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 			r := callAPI(sc.server, tt.args.method, tt.args.url, tt.args.body, t) | 
					
						
							|  |  |  | 			assert.Equalf(t, tt.want, r.Code, "Annotations API(%v)", tt.args.url) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | func TestService_AnnotationTypeScopeResolver(t *testing.T) { | 
					
						
							|  |  |  | 	type testCaseResolver struct { | 
					
						
							|  |  |  | 		desc    string | 
					
						
							|  |  |  | 		given   string | 
					
						
							|  |  |  | 		want    string | 
					
						
							|  |  |  | 		wantErr error | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []testCaseResolver{ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 			desc:    "correctly resolves dashboard annotations", | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			given:   "annotations:id:1", | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 			want:    accesscontrol.ScopeAnnotationsTypeDashboard, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			wantErr: nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 			desc:    "correctly resolves organization annotations", | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			given:   "annotations:id:2", | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 			want:    accesscontrol.ScopeAnnotationsTypeOrganization, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			wantErr: nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:    "invalid annotation ID", | 
					
						
							|  |  |  | 			given:   "annotations:id:123abc", | 
					
						
							|  |  |  | 			want:    "", | 
					
						
							|  |  |  | 			wantErr: accesscontrol.ErrInvalidScope, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:    "malformed scope", | 
					
						
							|  |  |  | 			given:   "annotations:1", | 
					
						
							|  |  |  | 			want:    "", | 
					
						
							|  |  |  | 			wantErr: accesscontrol.ErrInvalidScope, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	dashboardAnnotation := annotations.Item{Id: 1, DashboardId: 1} | 
					
						
							|  |  |  | 	organizationAnnotation := annotations.Item{Id: 2} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(&dashboardAnnotation) | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(&organizationAnnotation) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	prefix, resolver := AnnotationTypeScopeResolver() | 
					
						
							|  |  |  | 	require.Equal(t, "annotations:id:", prefix) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tc := range testCases { | 
					
						
							|  |  |  | 		t.Run(tc.desc, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-05-02 15:29:30 +08:00
										 |  |  | 			resolved, err := resolver.Resolve(context.Background(), 1, tc.given) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			if tc.wantErr != nil { | 
					
						
							|  |  |  | 				require.Error(t, err) | 
					
						
							|  |  |  | 				require.Equal(t, tc.wantErr, err) | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-05-02 15:29:30 +08:00
										 |  |  | 				require.Len(t, resolved, 1) | 
					
						
							|  |  |  | 				require.Equal(t, tc.want, resolved[0]) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | func TestAPI_MassDeleteAnnotations_AccessControl(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-08-11 21:37:31 +08:00
										 |  |  | 	sc := setupHTTPServer(t, true) | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	setInitCtxSignedInEditor(sc.initCtx) | 
					
						
							|  |  |  | 	_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID) | 
					
						
							|  |  |  | 	require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	type args struct { | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 		permissions []accesscontrol.Permission | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 		url         string | 
					
						
							|  |  |  | 		body        io.Reader | 
					
						
							|  |  |  | 		method      string | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tests := []struct { | 
					
						
							|  |  |  | 		name string | 
					
						
							|  |  |  | 		args args | 
					
						
							|  |  |  | 		want int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "Mass delete dashboard annotations without dashboardId is not allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					DashboardId: 0, | 
					
						
							|  |  |  | 					PanelId:     1, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "Mass delete dashboard annotations without panelId is not allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					DashboardId: 10, | 
					
						
							|  |  |  | 					PanelId:     0, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl mass delete dashboard annotations with correct dashboardId and panelId as input is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					DashboardId: 1, | 
					
						
							|  |  |  | 					PanelId:     1, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "Mass delete organization annotations without input to delete all organization annotations is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					DashboardId: 0, | 
					
						
							|  |  |  | 					PanelId:     0, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "Mass delete organization annotations without permissions is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					DashboardId: 0, | 
					
						
							|  |  |  | 					PanelId:     0, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl mass delete dashboard annotations with correct annotationId as input is allowed", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					AnnotationId: 1, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl mass delete annotation without access to dashboard annotations is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					AnnotationId: 1, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "AccessControl mass delete annotation without access to organization annotations is forbidden", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 				url:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 				method:      http.MethodPost, | 
					
						
							|  |  |  | 				body: mockRequestBody(dtos.MassDeleteAnnotationsCmd{ | 
					
						
							|  |  |  | 					AnnotationId: 2, | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.name, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-21 20:31:02 +08:00
										 |  |  | 			setUpRBACGuardian(t) | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			setAccessControlPermissions(sc.acmock, tt.args.permissions, sc.initCtx.OrgID) | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 			dashboardAnnotation := &annotations.Item{Id: 1, DashboardId: 1} | 
					
						
							|  |  |  | 			organizationAnnotation := &annotations.Item{Id: 2, DashboardId: 0} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			fakeAnnoRepo = NewFakeAnnotationsRepo() | 
					
						
							|  |  |  | 			_ = fakeAnnoRepo.Save(dashboardAnnotation) | 
					
						
							|  |  |  | 			_ = fakeAnnoRepo.Save(organizationAnnotation) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			annotations.SetRepository(fakeAnnoRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			r := callAPI(sc.server, tt.args.method, tt.args.url, tt.args.body, t) | 
					
						
							|  |  |  | 			assert.Equalf(t, tt.want, r.Code, "Annotations API(%v)", tt.args.url) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | func setUpACL() { | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 	viewerRole := org.RoleViewer | 
					
						
							|  |  |  | 	editorRole := org.RoleEditor | 
					
						
							| 
									
										
										
										
											2022-03-21 17:49:49 +08:00
										 |  |  | 	store := mockstore.NewSQLStoreMock() | 
					
						
							|  |  |  | 	store.ExpectedTeamsByUser = []*models.TeamDTO{} | 
					
						
							| 
									
										
										
										
											2022-06-02 02:16:26 +08:00
										 |  |  | 	dashSvc := &dashboards.FakeDashboardService{} | 
					
						
							| 
									
										
										
										
											2022-07-18 21:14:58 +08:00
										 |  |  | 	dashSvc.On("GetDashboardACLInfoList", mock.Anything, mock.AnythingOfType("*models.GetDashboardACLInfoListQuery")).Run(func(args mock.Arguments) { | 
					
						
							|  |  |  | 		q := args.Get(1).(*models.GetDashboardACLInfoListQuery) | 
					
						
							|  |  |  | 		q.Result = []*models.DashboardACLInfoDTO{ | 
					
						
							| 
									
										
										
										
											2022-06-02 02:16:26 +08:00
										 |  |  | 			{Role: &viewerRole, Permission: models.PERMISSION_VIEW}, | 
					
						
							|  |  |  | 			{Role: &editorRole, Permission: models.PERMISSION_EDIT}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}).Return(nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	guardian.InitLegacyGuardian(store, dashSvc) | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-21 20:31:02 +08:00
										 |  |  | func setUpRBACGuardian(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | 	origNewGuardian := guardian.New | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							|  |  |  | 		guardian.New = origNewGuardian | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanEditValue: true}) | 
					
						
							|  |  |  | } |