| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-12-01 22:43:31 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 	"github.com/stretchr/testify/mock" | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol" | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/annotations" | 
					
						
							| 
									
										
										
										
											2022-09-19 15:54:37 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/annotations/annotationstest" | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/dashboards" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/folder" | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/folder/foldertest" | 
					
						
							| 
									
										
										
										
											2022-03-21 17:49:49 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/guardian" | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/web/webtest" | 
					
						
							| 
									
										
										
										
											2017-12-21 07:52:21 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 16:58:57 +08:00
										 |  |  | func TestAPI_Annotations(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 	dashUID := "test-dash" | 
					
						
							|  |  |  | 	folderUID := "test-folder" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 	type testCase struct { | 
					
						
							|  |  |  | 		desc         string | 
					
						
							|  |  |  | 		path         string | 
					
						
							|  |  |  | 		method       string | 
					
						
							|  |  |  | 		body         string | 
					
						
							|  |  |  | 		expectedCode int | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		featureFlags []any | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 		permissions  []accesscontrol.Permission | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 	tests := []testCase{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to fetch annotations with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: accesscontrol.ScopeAnnotationsAll}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to fetch annotations without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to fetch annotation by id with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: accesscontrol.ScopeAnnotationsAll}}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to fetch annotation by id without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to fetch dashboard annotation by id with correct dashboard scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dashUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to fetch dashboard annotation by id with correct folder scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not be able to fetch dashboard annotation by id with the old dashboard scope when annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to fetch annotation tags with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/tags", | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsRead}}, | 
					
						
							| 
									
										
										
										
											2022-05-16 23:16:36 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to fetch annotation tags without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/tags", | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to update dashboard annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to update dashboard annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to update dashboard annotation with correct dashboard scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dashUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to update dashboard annotation with correct folder scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not be able to update dashboard annotation with the old dashboard scope when annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to update organization annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to update organization annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to patch dashboard annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to patch dashboard annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to patch dashboard annotation with correct dashboard scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dashUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to patch dashboard annotation with correct folder scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not be able to patch dashboard annotation with the old dashboard scope when annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to patch organization annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to patch organization annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodPatch, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsWrite, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to create dashboard annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2,\"text\": \"test\"}", | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to create dashboard annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2,\"text\": \"test\"}", | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to create dashboard annotation with correct dashboard scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2,\"text\": \"test\"}", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dashUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to create dashboard annotation with correct folder scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2,\"text\": \"test\"}", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not be able to create dashboard annotation with the old dashboard scope when annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2,\"text\": \"test\"}", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to create organization annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"text\": \"test\"}", | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-04-20 15:43:42 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to create organization annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         "{\"text\": \"test\"}", | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-04-20 15:43:42 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to delete dashboard annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to delete dashboard annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to delete dashboard annotation with correct dashboard scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dashUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to delete dashboard annotation with correct folder scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not be able to delete dashboard annotation with the old dashboard scope when annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/2", | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to delete organization annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to delete organization annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/1", | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to create graphite annotation with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/graphite", | 
					
						
							|  |  |  | 			body:         "{\"what\": \"test\", \"tags\": []}", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to create graphite annotation without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/graphite", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should be able to mass delete dashboard annotations with correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2, \"panelId\": 1}", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			desc:         "should not be able to mass delete dashboard annotations without correct permission", | 
					
						
							|  |  |  | 			path:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2, \"panelId\": 1}", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeOrganization}}, | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to mass delete dashboard annotation with correct dashboard scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2, \"panelId\": 1}", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dashUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should be able to mass delete dashboard annotation with correct folder scope with annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2, \"panelId\": 1}", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID)}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:         "should not be able to mass delete dashboard annotation with the old dashboard scope when annotationPermissionUpdate enabled", | 
					
						
							|  |  |  | 			path:         "/api/annotations/mass-delete", | 
					
						
							|  |  |  | 			body:         "{\"dashboardId\": 2, \"panelId\": 1}", | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			featureFlags: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 			permissions:  []accesscontrol.Permission{{Action: accesscontrol.ActionAnnotationsDelete, Scope: accesscontrol.ScopeAnnotationsTypeDashboard}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 	for _, tt := range tests { | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 			// Don't need access to dashboards if annotationPermissionUpdate is enabled
 | 
					
						
							|  |  |  | 			if len(tt.featureFlags) == 0 { | 
					
						
							|  |  |  | 				setUpRBACGuardian(t) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			server := SetupAPITestServer(t, func(hs *HTTPServer) { | 
					
						
							|  |  |  | 				hs.Cfg = setting.NewCfg() | 
					
						
							|  |  |  | 				repo := annotationstest.NewFakeAnnotationsRepo() | 
					
						
							| 
									
										
										
										
											2023-02-04 00:23:09 +08:00
										 |  |  | 				_ = repo.Save(context.Background(), &annotations.Item{ID: 1, DashboardID: 0}) | 
					
						
							|  |  |  | 				_ = repo.Save(context.Background(), &annotations.Item{ID: 2, DashboardID: 1}) | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 				hs.annotationsRepo = repo | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 				hs.Features = featuremgmt.WithFeatures(tt.featureFlags...) | 
					
						
							|  |  |  | 				dashService := &dashboards.FakeDashboardService{} | 
					
						
							|  |  |  | 				dashService.On("GetDashboard", mock.Anything, mock.Anything).Return(&dashboards.Dashboard{UID: dashUID, FolderUID: folderUID, FolderID: 1}, nil) | 
					
						
							|  |  |  | 				folderService := &foldertest.FakeService{} | 
					
						
							|  |  |  | 				folderService.ExpectedFolder = &folder.Folder{UID: folderUID, ID: 1} | 
					
						
							|  |  |  | 				folderDB := &foldertest.FakeFolderStore{} | 
					
						
							|  |  |  | 				folderDB.On("GetFolderByID", mock.Anything, mock.Anything, mock.Anything).Return(&folder.Folder{UID: folderUID, ID: 1}, nil) | 
					
						
							|  |  |  | 				hs.DashboardService = dashService | 
					
						
							|  |  |  | 				hs.folderService = folderService | 
					
						
							| 
									
										
										
										
											2025-01-14 17:26:15 +08:00
										 |  |  | 				hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2024-12-31 00:48:35 +08:00
										 |  |  | 				hs.AccessControl.RegisterScopeAttributeResolver(AnnotationTypeScopeResolver(hs.annotationsRepo, hs.Features, dashService, folderService)) | 
					
						
							|  |  |  | 				hs.AccessControl.RegisterScopeAttributeResolver(dashboards.NewDashboardIDScopeResolver(folderDB, dashService, folderService)) | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 			var body io.Reader | 
					
						
							|  |  |  | 			if tt.body != "" { | 
					
						
							|  |  |  | 				body = strings.NewReader(tt.body) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-03-22 01:28:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 			req := webtest.RequestWithSignedInUser(server.NewRequest(tt.method, tt.path, body), authedUserWithPermissions(1, 1, tt.permissions)) | 
					
						
							| 
									
										
										
										
											2023-01-09 16:59:14 +08:00
										 |  |  | 			res, err := server.SendJSON(req) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 			require.NoError(t, res.Body.Close()) | 
					
						
							| 
									
										
										
										
											2022-02-12 02:43:29 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-11-23 18:47:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | func TestService_AnnotationTypeScopeResolver(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 	rootDashUID := "root-dashboard" | 
					
						
							|  |  |  | 	folderDashUID := "folder-dashboard" | 
					
						
							|  |  |  | 	folderUID := "folder" | 
					
						
							|  |  |  | 	dashSvc := &dashboards.FakeDashboardService{} | 
					
						
							|  |  |  | 	rootDash := &dashboards.Dashboard{ID: 1, OrgID: 1, UID: rootDashUID} | 
					
						
							|  |  |  | 	folderDash := &dashboards.Dashboard{ID: 2, OrgID: 1, UID: folderDashUID, FolderUID: folderUID} | 
					
						
							|  |  |  | 	dashSvc.On("GetDashboard", context.Background(), &dashboards.GetDashboardQuery{ID: rootDash.ID, OrgID: 1}).Return(rootDash, nil) | 
					
						
							|  |  |  | 	dashSvc.On("GetDashboard", context.Background(), &dashboards.GetDashboardQuery{ID: folderDash.ID, OrgID: 1}).Return(folderDash, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rootDashboardAnnotation := annotations.Item{ID: 1, DashboardID: rootDash.ID} | 
					
						
							|  |  |  | 	folderDashboardAnnotation := annotations.Item{ID: 3, DashboardID: folderDash.ID} | 
					
						
							|  |  |  | 	organizationAnnotation := annotations.Item{ID: 2} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fakeAnnoRepo := annotationstest.NewFakeAnnotationsRepo() | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(context.Background(), &rootDashboardAnnotation) | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(context.Background(), &folderDashboardAnnotation) | 
					
						
							|  |  |  | 	_ = fakeAnnoRepo.Save(context.Background(), &organizationAnnotation) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	type testCaseResolver struct { | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 		desc           string | 
					
						
							|  |  |  | 		given          string | 
					
						
							|  |  |  | 		featureToggles []any | 
					
						
							|  |  |  | 		want           []string | 
					
						
							|  |  |  | 		wantErr        error | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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", | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 			want:    []string{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", | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 			want:    []string{accesscontrol.ScopeAnnotationsTypeOrganization}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			wantErr: nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:    "invalid annotation ID", | 
					
						
							|  |  |  | 			given:   "annotations:id:123abc", | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 			want:    []string{""}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			wantErr: accesscontrol.ErrInvalidScope, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:    "malformed scope", | 
					
						
							|  |  |  | 			given:   "annotations:1", | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 			want:    []string{""}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 			wantErr: accesscontrol.ErrInvalidScope, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:           "correctly resolves organization annotations with feature toggle", | 
					
						
							|  |  |  | 			given:          "annotations:id:2", | 
					
						
							|  |  |  | 			featureToggles: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			want:           []string{accesscontrol.ScopeAnnotationsTypeOrganization}, | 
					
						
							|  |  |  | 			wantErr:        nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:           "correctly resolves annotations from root dashboard with feature toggle", | 
					
						
							|  |  |  | 			given:          "annotations:id:1", | 
					
						
							|  |  |  | 			featureToggles: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			want: []string{ | 
					
						
							|  |  |  | 				dashboards.ScopeDashboardsProvider.GetResourceScopeUID(rootDashUID), | 
					
						
							|  |  |  | 				dashboards.ScopeFoldersProvider.GetResourceScopeUID(accesscontrol.GeneralFolderUID), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			wantErr: nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc:           "correctly resolves annotations from dashboard in a folder with feature toggle", | 
					
						
							|  |  |  | 			given:          "annotations:id:3", | 
					
						
							|  |  |  | 			featureToggles: []any{featuremgmt.FlagAnnotationPermissionUpdate}, | 
					
						
							|  |  |  | 			want: []string{ | 
					
						
							|  |  |  | 				dashboards.ScopeDashboardsProvider.GetResourceScopeUID(folderDashUID), | 
					
						
							|  |  |  | 				dashboards.ScopeFoldersProvider.GetResourceScopeUID(folderUID), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			wantErr: nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tc := range testCases { | 
					
						
							|  |  |  | 		t.Run(tc.desc, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 			features := featuremgmt.WithFeatures(tc.featureToggles...) | 
					
						
							| 
									
										
										
										
											2024-12-31 00:48:35 +08:00
										 |  |  | 			prefix, resolver := AnnotationTypeScopeResolver(fakeAnnoRepo, features, dashSvc, &foldertest.FakeService{}) | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 			require.Equal(t, "annotations:id:", prefix) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2023-11-17 17:57:25 +08:00
										 |  |  | 				require.Len(t, resolved, len(tc.want)) | 
					
						
							|  |  |  | 				require.Equal(t, tc.want, resolved) | 
					
						
							| 
									
										
										
										
											2022-03-19 00:33:21 +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 | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-08 22:28:49 +08:00
										 |  |  | 	guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanEditValue: true, CanViewValue: true}) | 
					
						
							| 
									
										
										
										
											2022-03-24 05:39:00 +08:00
										 |  |  | } |