feat(authorizer): authorize the look up of labels by resource

pull/11602/head
Leonardo Di Donato 2019-01-23 18:39:06 +01:00 committed by Leo Di Donato
parent bcabc0a085
commit bd8bb5cb52
2 changed files with 246 additions and 1 deletions

View File

@ -130,8 +130,33 @@ func (s *LabelService) FindLabels(ctx context.Context, filter influxdb.LabelFilt
return labels, nil
}
// FindResourceLabels retrieves all labels belonging to the filtering resource if the authorizer on context has read access to it.
// Then it filters the list down to only the labels that are authorized.
func (s *LabelService) FindResourceLabels(ctx context.Context, filter influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
panic("tbd")
if err := authorizeLabelMappingAction(ctx, influxdb.ReadAction, filter.ResourceID, filter.ResourceType); err != nil {
return nil, err
}
ls, err := s.s.FindResourceLabels(ctx, filter)
if err != nil {
return nil, err
}
labels := ls[:0]
for _, l := range ls {
err := authorizeReadLabel(ctx, l.ID)
if err != nil && influxdb.ErrorCode(err) != influxdb.EUnauthorized {
return nil, err
}
if influxdb.ErrorCode(err) == influxdb.EUnauthorized {
continue
}
labels = append(labels, l)
}
return labels, nil
}
// CreateLabel checks to see if the authorizer on context has write access to the global labels resource.

View File

@ -532,6 +532,226 @@ func TestLabelService_CreateLabel(t *testing.T) {
}
}
func TestLabelService_FindResourceLabels(t *testing.T) {
type fields struct {
LabelService influxdb.LabelService
}
type args struct {
filter influxdb.LabelMappingFilter
permissions []influxdb.Permission
}
type wants struct {
err error
labels []*influxdb.Label
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "authorized to see all labels belonging to a resource",
fields: fields{
LabelService: &mock.LabelService{
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
return []*influxdb.Label{
{
ID: 1,
},
{
ID: 2,
},
{
ID: 3,
},
}, nil
},
},
},
args: args{
filter: influxdb.LabelMappingFilter{
ResourceID: 10,
ResourceType: influxdb.BucketsResourceType,
},
permissions: []influxdb.Permission{
{
Action: "read",
Resource: influxdb.Resource{
Type: influxdb.LabelsResourceType,
},
},
{
Action: "read",
Resource: influxdb.Resource{
Type: influxdb.BucketsResourceType,
ID: influxdbtesting.IDPtr(10),
},
},
},
},
wants: wants{
err: nil,
labels: []*influxdb.Label{
{
ID: 1,
},
{
ID: 2,
},
{
ID: 3,
},
},
},
},
{
name: "authorized to access a single label",
fields: fields{
LabelService: &mock.LabelService{
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
return []*influxdb.Label{
{
ID: 1,
},
{
ID: 2,
},
{
ID: 3,
},
}, nil
},
},
},
args: args{
filter: influxdb.LabelMappingFilter{
ResourceID: 10,
ResourceType: influxdb.BucketsResourceType,
},
permissions: []influxdb.Permission{
{
Action: "read",
Resource: influxdb.Resource{
Type: influxdb.LabelsResourceType,
ID: influxdbtesting.IDPtr(3),
},
},
{
Action: "read",
Resource: influxdb.Resource{
Type: influxdb.BucketsResourceType,
ID: influxdbtesting.IDPtr(10),
},
},
},
},
wants: wants{
err: nil,
labels: []*influxdb.Label{
{
ID: 3,
},
},
},
},
{
name: "unable to access labels when missing read permission on labels",
fields: fields{
LabelService: &mock.LabelService{
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
return []*influxdb.Label{
{
ID: 1,
},
{
ID: 2,
},
{
ID: 3,
},
}, nil
},
},
},
args: args{
filter: influxdb.LabelMappingFilter{
ResourceID: 10,
ResourceType: influxdb.BucketsResourceType,
},
permissions: []influxdb.Permission{
{
Action: "read",
Resource: influxdb.Resource{
Type: influxdb.BucketsResourceType,
ID: influxdbtesting.IDPtr(10),
},
},
},
},
wants: wants{
// fixme(leodido) > should we return error in this case?
},
},
{
name: "unable to access labels when missing read permission on filtering resource",
fields: fields{
LabelService: &mock.LabelService{
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
return []*influxdb.Label{
{
ID: 1,
},
{
ID: 2,
},
{
ID: 3,
},
}, nil
},
},
},
args: args{
filter: influxdb.LabelMappingFilter{
ResourceID: 10,
ResourceType: influxdb.BucketsResourceType,
},
permissions: []influxdb.Permission{
{
Action: "read",
Resource: influxdb.Resource{
Type: influxdb.LabelsResourceType,
},
},
},
},
wants: wants{
err: &influxdb.Error{
Msg: "read:buckets/000000000000000a is unauthorized",
Code: influxdb.EUnauthorized,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := authorizer.NewLabelService(tt.fields.LabelService)
ctx := context.Background()
ctx = influxdbcontext.SetAuthorizer(ctx, &Authorizer{tt.args.permissions})
labels, err := s.FindResourceLabels(ctx, tt.args.filter)
influxdbtesting.ErrorsEqual(t, err, tt.wants.err)
if diff := cmp.Diff(labels, tt.wants.labels, labelCmpOptions...); diff != "" {
t.Errorf("labels are different -got/+want\ndiff %s", diff)
}
})
}
}
func TestLabelService_CreateLabelMapping(t *testing.T) {
type fields struct {
LabelService influxdb.LabelService