Access Control: Refactor scope resolvers with support to resolve into several scopes (#48202)
* Refactor Scope resolver to support resolving into several scopes * Change permission evaluator to match at least one of passed scopes
This commit is contained in:
+10
-10
@@ -401,20 +401,21 @@ func (hs *HTTPServer) GetAnnotationTags(c *models.ReqContext) response.Response
|
||||
return response.JSON(http.StatusOK, annotations.GetAnnotationTagsResponse{Result: result})
|
||||
}
|
||||
|
||||
// AnnotationTypeScopeResolver provides an AttributeScopeResolver able to
|
||||
// AnnotationTypeScopeResolver provides an ScopeAttributeResolver able to
|
||||
// resolve annotation types. Scope "annotations:id:<id>" will be translated to "annotations:type:<type>,
|
||||
// where <type> is the type of annotation with id <id>.
|
||||
func AnnotationTypeScopeResolver() (string, accesscontrol.AttributeScopeResolveFunc) {
|
||||
annotationTypeResolver := func(ctx context.Context, orgID int64, initialScope string) (string, error) {
|
||||
func AnnotationTypeScopeResolver() (string, accesscontrol.ScopeAttributeResolver) {
|
||||
prefix := accesscontrol.ScopeAnnotationsProvider.GetResourceScope("")
|
||||
return prefix, accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, initialScope string) ([]string, error) {
|
||||
scopeParts := strings.Split(initialScope, ":")
|
||||
if scopeParts[0] != accesscontrol.ScopeAnnotationsRoot || len(scopeParts) != 3 {
|
||||
return "", accesscontrol.ErrInvalidScope
|
||||
return nil, accesscontrol.ErrInvalidScope
|
||||
}
|
||||
|
||||
annotationIdStr := scopeParts[2]
|
||||
annotationId, err := strconv.Atoi(annotationIdStr)
|
||||
if err != nil {
|
||||
return "", accesscontrol.ErrInvalidScope
|
||||
return nil, accesscontrol.ErrInvalidScope
|
||||
}
|
||||
|
||||
// tempUser is used to resolve annotation type.
|
||||
@@ -431,16 +432,15 @@ func AnnotationTypeScopeResolver() (string, accesscontrol.AttributeScopeResolveF
|
||||
|
||||
annotation, resp := findAnnotationByID(ctx, annotations.GetRepository(), int64(annotationId), tempUser)
|
||||
if resp != nil {
|
||||
return "", errors.New("could not resolve annotation type")
|
||||
return nil, errors.New("could not resolve annotation type")
|
||||
}
|
||||
|
||||
if annotation.GetType() == annotations.Organization {
|
||||
return accesscontrol.ScopeAnnotationsTypeOrganization, nil
|
||||
return []string{accesscontrol.ScopeAnnotationsTypeOrganization}, nil
|
||||
} else {
|
||||
return accesscontrol.ScopeAnnotationsTypeDashboard, nil
|
||||
return []string{accesscontrol.ScopeAnnotationsTypeDashboard}, nil
|
||||
}
|
||||
}
|
||||
return accesscontrol.ScopeAnnotationsProvider.GetResourceScope(""), annotationTypeResolver
|
||||
})
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) canCreateAnnotation(c *models.ReqContext, dashboardId int64) (bool, error) {
|
||||
|
||||
@@ -722,7 +722,7 @@ func TestAPI_Annotations_AccessControl(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
setUpRBACGuardian(t)
|
||||
sc.acmock.
|
||||
RegisterAttributeScopeResolver(AnnotationTypeScopeResolver())
|
||||
RegisterScopeAttributeResolver(AnnotationTypeScopeResolver())
|
||||
setAccessControlPermissions(sc.acmock, tt.args.permissions, sc.initCtx.OrgId)
|
||||
|
||||
r := callAPI(sc.server, tt.args.method, tt.args.url, tt.args.body, t)
|
||||
@@ -780,13 +780,14 @@ func TestService_AnnotationTypeScopeResolver(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
resolved, err := resolver(context.Background(), 1, tc.given)
|
||||
resolved, err := resolver.Resolve(context.Background(), 1, tc.given)
|
||||
if tc.wantErr != nil {
|
||||
require.Error(t, err)
|
||||
require.Equal(t, tc.wantErr, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.want, resolved)
|
||||
require.Len(t, resolved, 1)
|
||||
require.Equal(t, tc.want, resolved[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
hs.registerRoutes()
|
||||
|
||||
// Register access control scope resolver for annotations
|
||||
hs.AccessControl.RegisterAttributeScopeResolver(AnnotationTypeScopeResolver())
|
||||
hs.AccessControl.RegisterScopeAttributeResolver(AnnotationTypeScopeResolver())
|
||||
|
||||
if err := hs.declareFixedRoles(); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user