Adding FGAC annotations validation for creation and deletion (#46736)

Access Control: Adding FGAC annotations validation for creation and deletion
Co-authored-by: IevaVasiljeva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Ezequiel Victorero 2022-03-21 14:28:39 -03:00 committed by GitHub
parent 7ab1ef8d6e
commit c717320942
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 377 additions and 111 deletions

View File

@ -274,15 +274,17 @@ func (hs *HTTPServer) declareFixedRoles() error {
Grants: []string{string(models.ROLE_VIEWER)},
}
localAnnotationsWriterRole := ac.RoleRegistration{
dashboardAnnotationsWriterRole := ac.RoleRegistration{
Role: ac.RoleDTO{
Name: "fixed:annotations.local:writer",
DisplayName: "Local annotation writer",
Name: "fixed:annotations.dashboard:writer",
DisplayName: "Dashboard annotation writer",
Description: "Update annotations associated with dashboards.",
Group: "Annotations",
Version: 1,
Version: 2,
Permissions: []ac.Permission{
{Action: ac.ActionAnnotationsWrite, Scope: ac.ScopeAnnotationsTypeLocal},
{Action: ac.ActionAnnotationsCreate},
{Action: ac.ActionAnnotationsDelete, Scope: ac.ScopeAnnotationsTypeDashboard},
{Action: ac.ActionAnnotationsWrite, Scope: ac.ScopeAnnotationsTypeDashboard},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
@ -296,6 +298,8 @@ func (hs *HTTPServer) declareFixedRoles() error {
Group: "Annotations",
Version: 1,
Permissions: []ac.Permission{
{Action: ac.ActionAnnotationsCreate},
{Action: ac.ActionAnnotationsDelete, Scope: ac.ScopeAnnotationsAll},
{Action: ac.ActionAnnotationsWrite, Scope: ac.ScopeAnnotationsAll},
},
},
@ -405,7 +409,7 @@ func (hs *HTTPServer) declareFixedRoles() error {
provisioningWriterRole, datasourcesReaderRole, datasourcesWriterRole, datasourcesIdReaderRole,
datasourcesCompatibilityReaderRole, orgReaderRole, orgWriterRole,
orgMaintainerRole, teamsCreatorRole, teamsWriterRole, datasourcesExplorerRole,
annotationsReaderRole, localAnnotationsWriterRole, annotationsWriterRole,
annotationsReaderRole, dashboardAnnotationsWriterRole, annotationsWriterRole,
dashboardsCreatorRole, dashboardsReaderRole, dashboardsWriterRole,
foldersCreatorRole, foldersReaderRole, foldersWriterRole, apikeyWriterRole,
)

View File

@ -66,10 +66,18 @@ func (hs *HTTPServer) PostAnnotation(c *models.ReqContext) response.Response {
var canSave bool
var err error
if cmd.DashboardId != 0 {
canSave, err = canSaveLocalAnnotation(c, cmd.DashboardId)
} else {
canSave = canSaveGlobalAnnotation(c)
canSave, err = canSaveDashboardAnnotation(c, cmd.DashboardId)
} else { // organization annotations
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
canSave = canSaveOrganizationAnnotation(c)
} else {
// This is an additional validation needed only for FGAC Organization Annotations.
// It is not possible to do it in the middleware because we need to look
// into the request to determine if this is a Organization annotation or not
canSave, err = hs.canCreateOrganizationAnnotation(c)
}
}
if err != nil || !canSave {
return dashboardGuardianResponse(err)
}
@ -190,13 +198,14 @@ func (hs *HTTPServer) UpdateAnnotation(c *models.ReqContext) response.Response {
}
canSave := true
if annotation.GetType() == annotations.Local {
canSave, err = canSaveLocalAnnotation(c, annotation.DashboardId)
if annotation.GetType() == annotations.Dashboard {
canSave, err = canSaveDashboardAnnotation(c, annotation.DashboardId)
} else {
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
canSave = canSaveGlobalAnnotation(c)
canSave = canSaveOrganizationAnnotation(c)
}
}
if err != nil || !canSave {
return dashboardGuardianResponse(err)
}
@ -236,11 +245,11 @@ func (hs *HTTPServer) PatchAnnotation(c *models.ReqContext) response.Response {
}
canSave := true
if annotation.GetType() == annotations.Local {
canSave, err = canSaveLocalAnnotation(c, annotation.DashboardId)
if annotation.GetType() == annotations.Dashboard {
canSave, err = canSaveDashboardAnnotation(c, annotation.DashboardId)
} else {
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
canSave = canSaveGlobalAnnotation(c)
canSave = canSaveOrganizationAnnotation(c)
}
}
if err != nil || !canSave {
@ -314,12 +323,15 @@ func (hs *HTTPServer) DeleteAnnotationByID(c *models.ReqContext) response.Respon
return resp
}
var canSave bool
if annotation.GetType() == annotations.Local {
canSave, err = canSaveLocalAnnotation(c, annotation.DashboardId)
canSave := true
if annotation.GetType() == annotations.Dashboard {
canSave, err = canSaveDashboardAnnotation(c, annotation.DashboardId)
} else {
canSave = canSaveGlobalAnnotation(c)
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
canSave = canSaveOrganizationAnnotation(c)
}
}
if err != nil || !canSave {
return dashboardGuardianResponse(err)
}
@ -335,7 +347,7 @@ func (hs *HTTPServer) DeleteAnnotationByID(c *models.ReqContext) response.Respon
return response.Success("Annotation deleted")
}
func canSaveLocalAnnotation(c *models.ReqContext, dashboardID int64) (bool, error) {
func canSaveDashboardAnnotation(c *models.ReqContext, dashboardID int64) (bool, error) {
guard := guardian.New(c.Req.Context(), dashboardID, c.OrgId, c.SignedInUser)
if canEdit, err := guard.CanEdit(); err != nil || !canEdit {
return false, err
@ -344,7 +356,7 @@ func canSaveLocalAnnotation(c *models.ReqContext, dashboardID int64) (bool, erro
return true, nil
}
func canSaveGlobalAnnotation(c *models.ReqContext) bool {
func canSaveOrganizationAnnotation(c *models.ReqContext) bool {
return c.SignedInUser.HasRole(models.ROLE_EDITOR)
}
@ -399,11 +411,16 @@ func AnnotationTypeScopeResolver() (string, accesscontrol.AttributeScopeResolveF
return "", err
}
if annotation.GetType() == annotations.Global {
return accesscontrol.ScopeAnnotationsTypeGlobal, nil
if annotation.GetType() == annotations.Organization {
return accesscontrol.ScopeAnnotationsTypeOrganization, nil
} else {
return accesscontrol.ScopeAnnotationsTypeLocal, nil
return accesscontrol.ScopeAnnotationsTypeDashboard, nil
}
}
return accesscontrol.ScopeAnnotationsProvider.GetResourceScope(""), annotationTypeResolver
}
func (hs *HTTPServer) canCreateOrganizationAnnotation(c *models.ReqContext) (bool, error) {
evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeOrganization)
return hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator)
}

View File

@ -396,20 +396,47 @@ func TestAPI_Annotations_AccessControl(t *testing.T) {
_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID)
require.NoError(t, err)
repo := annotations.GetRepository()
dashboardAnnotation := annotations.ItemDTO{Id: 1, DashboardId: 1}
organizationAnnotation := annotations.ItemDTO{Id: 2, DashboardId: 0}
localAnnotation := annotations.Item{
OrgId: sc.initCtx.OrgId,
fakeAnnoRepo = &fakeAnnotationsRepo{
annotations: map[int64]annotations.ItemDTO{1: dashboardAnnotation, 2: organizationAnnotation},
}
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"},
DashboardId: 1,
}
globalAnnotation := annotations.Item{
OrgId: sc.initCtx.OrgId,
PanelId: 1,
}
err = repo.Save(&localAnnotation)
require.NoError(t, err)
err = repo.Save(&globalAnnotation)
require.NoError(t, err)
updateCmd := dtos.UpdateAnnotationsCmd{
Time: 1000,
Text: "annotation text",
Tags: []string{"tag1", "tag2"},
}
patchCmd := dtos.PatchAnnotationsCmd{
Time: 1000,
Text: "annotation text",
Tags: []string{"tag1", "tag2"},
}
postGraphiteCmd := dtos.PostGraphiteAnnotationsCmd{
When: 1000,
What: "annotation text",
Data: "Deploy",
Tags: []string{"tag1", "tag2"},
}
type args struct {
permissions []*accesscontrol.Permission
@ -459,10 +486,217 @@ func TestAPI_Annotations_AccessControl(t *testing.T) {
},
want: http.StatusForbidden,
},
{
name: "AccessControl update dashboard annotation with permissions is allowed",
args: args{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{},
url: "/api/annotations/1",
method: http.MethodPut,
body: mockRequestBody(updateCmd),
},
want: http.StatusForbidden,
},
{
name: "AccessControl update organization annotation with permissions is allowed",
args: args{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{},
url: "/api/annotations/1",
method: http.MethodPatch,
body: mockRequestBody(patchCmd),
},
want: http.StatusForbidden,
},
{
name: "AccessControl patch organization annotation with permissions is allowed",
args: args{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{},
url: "/api/annotations",
method: http.MethodPost,
body: mockRequestBody(postDashboardCmd),
},
want: http.StatusForbidden,
},
{
name: "AccessControl create organization annotation with permissions is allowed",
args: args{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{},
url: "/api/annotations/1",
method: http.MethodDelete,
},
want: http.StatusForbidden,
},
{
name: "AccessControl delete organization annotation with permissions is allowed",
args: args{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
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{
permissions: []*accesscontrol.Permission{{
Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeDashboard,
}},
url: "/api/annotations/graphite",
method: http.MethodPost,
body: mockRequestBody(postGraphiteCmd),
},
want: http.StatusForbidden,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
setUpACL()
sc.acmock.RegisterAttributeScopeResolver(AnnotationTypeScopeResolver())
setAccessControlPermissions(sc.acmock, tt.args.permissions, sc.initCtx.OrgId)
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)
})
@ -479,15 +713,15 @@ func TestService_AnnotationTypeScopeResolver(t *testing.T) {
testCases := []testCaseResolver{
{
desc: "correctly resolves local annotations",
desc: "correctly resolves dashboard annotations",
given: "annotations:id:1",
want: accesscontrol.ScopeAnnotationsTypeLocal,
want: accesscontrol.ScopeAnnotationsTypeDashboard,
wantErr: nil,
},
{
desc: "correctly resolves global annotations",
desc: "correctly resolves organization annotations",
given: "annotations:id:2",
want: accesscontrol.ScopeAnnotationsTypeGlobal,
want: accesscontrol.ScopeAnnotationsTypeOrganization,
wantErr: nil,
},
{
@ -504,11 +738,11 @@ func TestService_AnnotationTypeScopeResolver(t *testing.T) {
},
}
localAnnotation := annotations.ItemDTO{Id: 1, DashboardId: 1}
globalAnnotation := annotations.ItemDTO{Id: 2}
dashboardAnnotation := annotations.ItemDTO{Id: 1, DashboardId: 1}
organizationAnnotation := annotations.ItemDTO{Id: 2}
fakeAnnoRepo = &fakeAnnotationsRepo{
annotations: map[int64]annotations.ItemDTO{1: localAnnotation, 2: globalAnnotation},
annotations: map[int64]annotations.ItemDTO{1: dashboardAnnotation, 2: organizationAnnotation},
}
annotations.SetRepository(fakeAnnoRepo)

View File

@ -440,11 +440,11 @@ func (hs *HTTPServer) registerRoutes() {
apiRoute.Post("/annotations/mass-delete", reqOrgAdmin, routing.Wrap(hs.DeleteAnnotations))
apiRoute.Group("/annotations", func(annotationsRoute routing.RouteRegister) {
annotationsRoute.Post("/", routing.Wrap(hs.PostAnnotation))
annotationsRoute.Delete("/:annotationId", routing.Wrap(hs.DeleteAnnotationByID))
annotationsRoute.Post("/", authorize(reqSignedIn, ac.EvalPermission(ac.ActionAnnotationsCreate)), routing.Wrap(hs.PostAnnotation))
annotationsRoute.Delete("/:annotationId", authorize(reqSignedIn, ac.EvalPermission(ac.ActionAnnotationsDelete, ac.ScopeAnnotationsID)), routing.Wrap(hs.DeleteAnnotationByID))
annotationsRoute.Put("/:annotationId", authorize(reqSignedIn, ac.EvalPermission(ac.ActionAnnotationsWrite, ac.ScopeAnnotationsID)), routing.Wrap(hs.UpdateAnnotation))
annotationsRoute.Patch("/:annotationId", authorize(reqSignedIn, ac.EvalPermission(ac.ActionAnnotationsWrite, ac.ScopeAnnotationsID)), routing.Wrap(hs.PatchAnnotation))
annotationsRoute.Post("/graphite", reqEditorRole, routing.Wrap(hs.PostGraphiteAnnotation))
annotationsRoute.Post("/graphite", authorize(reqEditorRole, ac.EvalPermission(ac.ActionAnnotationsCreate, ac.ScopeAnnotationsTypeOrganization)), routing.Wrap(hs.PostGraphiteAnnotation))
annotationsRoute.Get("/tags", authorize(reqSignedIn, ac.EvalPermission(ac.ActionAnnotationsTagsRead, ac.ScopeAnnotationsTagsAll)), routing.Wrap(hs.GetAnnotationTags))
})

View File

@ -141,7 +141,7 @@ type GetAnnotationsParams struct {
// in:query
// required:false
Limit int64 `json:"limit"`
// Use this to filter global annotations. Global annotations are annotations from an annotation data source that are not connected specifically to a dashboard or panel. You can filter by multiple tags.
// Use this to filter global annotations. Organization annotations are annotations from an annotation data source that are not connected specifically to a dashboard or panel. You can filter by multiple tags.
// in:query
// required:false
// type: array

View File

@ -130,7 +130,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/v4/some/method", cfg, httpClientProvider,
&oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -143,7 +143,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path and has dynamic url", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/common/some/method", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
proxy.matchedRoute = routes[3]
@ -155,7 +155,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path with no url", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
proxy.matchedRoute = routes[4]
@ -166,7 +166,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path and has dynamic body", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/body", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
proxy.matchedRoute = routes[5]
@ -180,7 +180,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("Validating request", func(t *testing.T) {
t.Run("plugin route with valid role", func(t *testing.T) {
ctx, _ := setUp()
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/v4/some/method", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
err = proxy.validateRequest()
@ -189,7 +189,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("plugin route with admin role and user is editor", func(t *testing.T) {
ctx, _ := setUp()
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/admin", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
err = proxy.validateRequest()
@ -199,7 +199,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("plugin route with admin role and user is admin", func(t *testing.T) {
ctx, _ := setUp()
ctx.SignedInUser.OrgRole = models.ROLE_ADMIN
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/admin", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
err = proxy.validateRequest()
@ -290,7 +290,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
},
}
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "pathwithtoken1", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
ApplyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, routes[0], dsInfo, cfg)
@ -306,7 +306,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req, err := http.NewRequest("GET", "http://localhost/asd", nil)
require.NoError(t, err)
client = newFakeHTTPClient(t, json2)
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "pathwithtoken2", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
ApplyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, routes[1], dsInfo, cfg)
@ -323,7 +323,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
require.NoError(t, err)
client = newFakeHTTPClient(t, []byte{})
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "pathwithtoken1", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
ApplyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, routes[0], dsInfo, cfg)
@ -345,7 +345,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := &models.ReqContext{}
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{BuildVersion: "5.3.0"}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@ -371,7 +371,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := &models.ReqContext{}
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -395,7 +395,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := &models.ReqContext{}
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -423,7 +423,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := &models.ReqContext{}
var pluginRoutes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, pluginRoutes, ctx, "", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -446,7 +446,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
ctx := &models.ReqContext{}
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/to/folder/", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@ -510,7 +510,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/to/folder/", &setting.Cfg{}, httpClientProvider, &mockAuthToken, dsService, tracer, secretsService)
require.NoError(t, err)
req, err = http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@ -643,7 +643,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
ctx, ds := setUp(t)
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -661,7 +661,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
})
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -675,7 +675,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
ctx, ds := setUp(t)
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -697,7 +697,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
})
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -722,7 +722,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
ctx.Req = httptest.NewRequest("GET", "/api/datasources/proxy/1/path/%2Ftest%2Ftest%2F?query=%2Ftest%2Ftest%2F", nil)
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/%2Ftest%2Ftest%2F", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -746,7 +746,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
ctx.Req = httptest.NewRequest("GET", "/api/datasources/proxy/1/path/%2Ftest%2Ftest%2F?query=%2Ftest%2Ftest%2F", nil)
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/%2Ftest%2Ftest%2F", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -771,7 +771,7 @@ func TestNewDataSourceProxy_InvalidURL(t *testing.T) {
require.NoError(t, err)
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
_, err = NewDataSourceProxy(&ds, routes, &ctx, "api/method", &cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer, secretsService)
require.Error(t, err)
assert.True(t, strings.HasPrefix(err.Error(), `validation of data source URL "://host/root" failed`))
@ -792,7 +792,7 @@ func TestNewDataSourceProxy_ProtocolLessURL(t *testing.T) {
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
_, err = NewDataSourceProxy(&ds, routes, &ctx, "api/method", &cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -835,7 +835,7 @@ func TestNewDataSourceProxy_MSSQL(t *testing.T) {
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
p, err := NewDataSourceProxy(&ds, routes, &ctx, "api/method", &cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer, secretsService)
if tc.err == nil {
require.NoError(t, err)
@ -862,7 +862,7 @@ func getDatasourceProxiedRequest(t *testing.T, ctx *models.ReqContext, cfg *sett
var routes []*plugins.Route
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@ -986,7 +986,7 @@ func runDatasourceAuthTest(t *testing.T, secretsService secrets.Service, test *t
require.NoError(t, err)
var routes []*plugins.Route
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(test.datasource, routes, ctx, "", &setting.Cfg{}, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)
@ -1028,7 +1028,7 @@ func Test_PathCheck(t *testing.T) {
}
ctx, _ := setUp()
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
proxy, err := NewDataSourceProxy(&models.DataSource{}, routes, ctx, "b", &setting.Cfg{}, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer, secretsService)
require.NoError(t, err)

View File

@ -34,7 +34,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
hs := &HTTPServer{
Cfg: settings,
SQLStore: sqlStore,
AccessControl: &acmock.Mock{},
AccessControl: acmock.New(),
}
mockResult := models.SearchUserQueryResult{

View File

@ -46,6 +46,8 @@ type Mock struct {
GetUserBuiltInRolesFunc func(user *models.SignedInUser) []string
RegisterFixedRolesFunc func() error
RegisterAttributeScopeResolverFunc func(string, accesscontrol.AttributeScopeResolveFunc)
scopeResolver accesscontrol.ScopeResolver
}
// Ensure the mock stays in line with the interface
@ -53,10 +55,11 @@ var _ fullAccessControl = New()
func New() *Mock {
mock := &Mock{
Calls: Calls{},
disabled: false,
permissions: []*accesscontrol.Permission{},
builtInRoles: []string{},
Calls: Calls{},
disabled: false,
permissions: []*accesscontrol.Permission{},
builtInRoles: []string{},
scopeResolver: accesscontrol.NewScopeResolver(),
}
return mock
@ -90,13 +93,18 @@ func (m *Mock) Evaluate(ctx context.Context, user *models.SignedInUser, evaluato
if err != nil {
return false, err
}
return evaluator.Evaluate(accesscontrol.GroupScopesByAction(permissions))
attributeMutator := m.scopeResolver.GetResolveAttributeScopeMutator(user.OrgId)
resolvedEvaluator, err := evaluator.MutateScopes(ctx, attributeMutator)
if err != nil {
return false, err
}
return resolvedEvaluator.Evaluate(accesscontrol.GroupScopesByAction(permissions))
}
// GetUserPermissions returns user permissions.
// This mock return m.permissions unless an override is provided.
func (m *Mock) GetUserPermissions(ctx context.Context, user *models.SignedInUser,
opts accesscontrol.Options) ([]*accesscontrol.Permission, error) {
func (m *Mock) GetUserPermissions(ctx context.Context, user *models.SignedInUser, opts accesscontrol.Options) ([]*accesscontrol.Permission, error) {
m.Calls.GetUserPermissions = append(m.Calls.GetUserPermissions, []interface{}{ctx, user, opts})
// Use override if provided
if m.GetUserPermissionsFunc != nil {
@ -169,6 +177,7 @@ func (m *Mock) RegisterFixedRoles() error {
// RegisterAttributeScopeResolver allows the caller to register a scope resolver for a
// specific scope prefix (ex: datasources:name:)
func (m *Mock) RegisterAttributeScopeResolver(scopePrefix string, resolver accesscontrol.AttributeScopeResolveFunc) {
m.scopeResolver.AddAttributeResolver(scopePrefix, resolver)
m.Calls.RegisterAttributeScopeResolver = append(m.Calls.RegisterAttributeScopeResolver, []struct{}{})
// Use override if provided
if m.RegisterAttributeScopeResolverFunc != nil {

View File

@ -319,6 +319,8 @@ const (
ScopeTeamsAll = "teams:*"
// Annotations related actions
ActionAnnotationsCreate = "annotations:create"
ActionAnnotationsDelete = "annotations:delete"
ActionAnnotationsRead = "annotations:read"
ActionAnnotationsWrite = "annotations:write"
ActionAnnotationsTagsRead = "annotations.tags:read"
@ -373,12 +375,12 @@ var (
ScopeTeamsID = Scope("teams", "id", Parameter(":teamId"))
// Annotation scopes
ScopeAnnotationsRoot = "annotations"
ScopeAnnotationsProvider = NewScopeProvider(ScopeAnnotationsRoot)
ScopeAnnotationsAll = ScopeAnnotationsProvider.GetResourceAllScope()
ScopeAnnotationsID = Scope(ScopeAnnotationsRoot, "id", Parameter(":annotationId"))
ScopeAnnotationsTypeLocal = ScopeAnnotationsProvider.GetResourceScopeType("dashboard")
ScopeAnnotationsTypeGlobal = ScopeAnnotationsProvider.GetResourceScopeType("organization")
ScopeAnnotationsRoot = "annotations"
ScopeAnnotationsProvider = NewScopeProvider(ScopeAnnotationsRoot)
ScopeAnnotationsAll = ScopeAnnotationsProvider.GetResourceAllScope()
ScopeAnnotationsID = Scope(ScopeAnnotationsRoot, "id", Parameter(":annotationId"))
ScopeAnnotationsTypeDashboard = ScopeAnnotationsProvider.GetResourceScopeType("dashboard")
ScopeAnnotationsTypeOrganization = ScopeAnnotationsProvider.GetResourceScopeType("organization")
// Annotation tag scopes
ScopeAnnotationsTagsAll = "annotations:tags:*"

View File

@ -149,13 +149,13 @@ type ItemDTO struct {
type annotationType int
const (
Global annotationType = iota
Local
Organization annotationType = iota
Dashboard
)
func (annotation *ItemDTO) GetType() annotationType {
if annotation.DashboardId != 0 {
return Local
return Dashboard
}
return Global
return Organization
}

View File

@ -37,7 +37,7 @@ func TestService(t *testing.T) {
})
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
s := ProvideService(bus.New(), sqlStore, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
s := ProvideService(bus.New(), sqlStore, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
var ds *models.DataSource
@ -234,7 +234,7 @@ func TestService_GetHttpTransport(t *testing.T) {
}
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
rt1, err := dsService.GetHTTPTransport(&ds, provider)
require.NoError(t, err)
@ -267,7 +267,7 @@ func TestService_GetHttpTransport(t *testing.T) {
json.Set("tlsAuthWithCACert", true)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
tlsCaCert, err := secretsService.Encrypt(context.Background(), []byte(caCert), secrets.WithoutScope())
require.NoError(t, err)
@ -317,7 +317,7 @@ func TestService_GetHttpTransport(t *testing.T) {
json.Set("tlsAuth", true)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
tlsClientCert, err := secretsService.Encrypt(context.Background(), []byte(clientCert), secrets.WithoutScope())
require.NoError(t, err)
@ -360,7 +360,7 @@ func TestService_GetHttpTransport(t *testing.T) {
json.Set("serverName", "server-name")
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
tlsCaCert, err := secretsService.Encrypt(context.Background(), []byte(caCert), secrets.WithoutScope())
require.NoError(t, err)
@ -397,7 +397,7 @@ func TestService_GetHttpTransport(t *testing.T) {
json.Set("tlsSkipVerify", true)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
ds := models.DataSource{
Id: 1,
@ -428,7 +428,7 @@ func TestService_GetHttpTransport(t *testing.T) {
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
encryptedData, err := secretsService.Encrypt(context.Background(), []byte(`Bearer xf5yhfkpsnmgo`), secrets.WithoutScope())
require.NoError(t, err)
@ -487,7 +487,7 @@ func TestService_GetHttpTransport(t *testing.T) {
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
ds := models.DataSource{
Id: 1,
@ -520,7 +520,7 @@ func TestService_GetHttpTransport(t *testing.T) {
require.NoError(t, err)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
ds := models.DataSource{
Type: models.DS_ES,
@ -554,7 +554,7 @@ func TestService_getTimeout(t *testing.T) {
}
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
for _, tc := range testCases {
ds := &models.DataSource{
@ -567,7 +567,7 @@ func TestService_getTimeout(t *testing.T) {
func TestService_DecryptedValue(t *testing.T) {
t.Run("When datasource hasn't been updated, encrypted JSON should be fetched from cache", func(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
encryptedJsonData, err := secretsService.EncryptJsonData(
context.Background(),
@ -621,7 +621,7 @@ func TestService_DecryptedValue(t *testing.T) {
SecureJsonData: encryptedJsonData,
}
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
// Populate cache
password, ok := dsService.DecryptedValue(&ds, "password")
@ -657,7 +657,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
t.Cleanup(func() { ds.JsonData = emptyJsonData; ds.SecureJsonData = emptySecureJsonData })
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)
@ -675,7 +675,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)
@ -694,7 +694,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
_, err := dsService.httpClientOptions(&ds)
assert.Error(t, err)
@ -708,7 +708,7 @@ func TestService_HTTPClientOptions(t *testing.T) {
})
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
opts, err := dsService.httpClientOptions(&ds)
require.NoError(t, err)

View File

@ -56,7 +56,7 @@ func TestAnnotations(t *testing.T) {
assert.Equal(t, int64(20), annotation2.Epoch)
assert.Equal(t, int64(21), annotation2.EpochEnd)
globalAnnotation1 := &annotations.Item{
organizationAnnotation1 := &annotations.Item{
OrgId: 1,
UserId: 1,
Text: "deploy",
@ -64,9 +64,9 @@ func TestAnnotations(t *testing.T) {
Epoch: 15,
Tags: []string{"deploy"},
}
err = repo.Save(globalAnnotation1)
err = repo.Save(organizationAnnotation1)
require.NoError(t, err)
assert.Greater(t, globalAnnotation1.Id, int64(0))
assert.Greater(t, organizationAnnotation1.Id, int64(0))
globalAnnotation2 := &annotations.Item{
OrgId: 1,

View File

@ -37,7 +37,7 @@ func TestHandleRequest(t *testing.T) {
return backend.NewQueryDataResponse(), nil
}
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), &acmock.Mock{}, acmock.NewPermissionsServicesMock())
dsService := datasourceservice.ProvideService(bus.New(), nil, secretsService, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock())
s := ProvideService(client, nil, dsService)
ds := &models.DataSource{Id: 12, Type: "unregisteredType", JsonData: simplejson.New()}