66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package query
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/influxdata/flux"
|
|
"github.com/influxdata/platform"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// PreAuthorizer provides a method for ensuring that the buckets accessed by a query spec
|
|
// are allowed access by the given Authorization. This is a pre-check provided as a way for
|
|
// callers to fail early for operations that are not allowed. However, it's still possible
|
|
// for authorization to be denied at runtime even if this check passes.
|
|
type PreAuthorizer interface {
|
|
PreAuthorize(ctx context.Context, spec *flux.Spec, auth *platform.Authorization) error
|
|
}
|
|
|
|
// NewPreAuthorizer creates a new PreAuthorizer
|
|
func NewPreAuthorizer(bucketService platform.BucketService) PreAuthorizer {
|
|
return &preAuthorizer{bucketService: bucketService}
|
|
}
|
|
|
|
type preAuthorizer struct {
|
|
bucketService platform.BucketService
|
|
}
|
|
|
|
// PreAuthorize finds all the buckets read and written by the given spec, and ensures that execution is allowed
|
|
// given the Authorization. Returns nil on success, and an error with an appropriate message otherwise.
|
|
func (a *preAuthorizer) PreAuthorize(ctx context.Context, spec *flux.Spec, auth *platform.Authorization) error {
|
|
|
|
readBuckets, writeBuckets, err := BucketsAccessed(spec)
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, "Could not retrieve buckets for query.Spec")
|
|
}
|
|
|
|
for _, readBucketFilter := range readBuckets {
|
|
bucket, err := a.bucketService.FindBucket(ctx, readBucketFilter)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "Bucket service error")
|
|
} else if bucket == nil {
|
|
return errors.New("bucket service returned nil bucket")
|
|
}
|
|
|
|
reqPerm := platform.ReadBucketPermission(bucket.ID)
|
|
if !auth.Allowed(reqPerm) {
|
|
return errors.New("no read permission for bucket: \"" + bucket.Name + "\"")
|
|
}
|
|
}
|
|
|
|
for _, writeBucketFilter := range writeBuckets {
|
|
bucket, err := a.bucketService.FindBucket(context.Background(), writeBucketFilter)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "Could not find bucket %v", writeBucketFilter)
|
|
}
|
|
|
|
reqPerm := platform.WriteBucketPermission(bucket.ID)
|
|
if !auth.Allowed(reqPerm) {
|
|
return errors.New("no write permission for bucket: \"" + bucket.Name + "\"")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|