package authorizer import ( "context" "fmt" "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/kit/platform" ) var _ influxdb.DocumentService = (*DocumentService)(nil) var _ influxdb.DocumentStore = (*documentStore)(nil) type DocumentService struct { s influxdb.DocumentService } // NewDocumentService constructs an instance of an authorizing document service. func NewDocumentService(s influxdb.DocumentService) influxdb.DocumentService { return &DocumentService{ s: s, } } func (s *DocumentService) CreateDocumentStore(ctx context.Context, name string) (influxdb.DocumentStore, error) { ds, err := s.s.CreateDocumentStore(ctx, name) if err != nil { return nil, err } return &documentStore{s: ds}, nil } func (s *DocumentService) FindDocumentStore(ctx context.Context, name string) (influxdb.DocumentStore, error) { ds, err := s.s.FindDocumentStore(ctx, name) if err != nil { return nil, err } return &documentStore{s: ds}, nil } type documentStore struct { s influxdb.DocumentStore } func newDocumentPermission(a influxdb.Action, orgID platform.ID, did *platform.ID) (*influxdb.Permission, error) { if did != nil { return influxdb.NewPermissionAtID(*did, a, influxdb.DocumentsResourceType, orgID) } return influxdb.NewPermission(a, influxdb.DocumentsResourceType, orgID) } func toPerms(action influxdb.Action, orgs map[platform.ID]influxdb.UserType, did *platform.ID) ([]influxdb.Permission, error) { ps := make([]influxdb.Permission, 0, len(orgs)) for orgID := range orgs { p, err := newDocumentPermission(action, orgID, did) if err != nil { return nil, err } ps = append(ps, *p) } return ps, nil } func (s *documentStore) CreateDocument(ctx context.Context, d *influxdb.Document) error { if len(d.Organizations) == 0 { return fmt.Errorf("cannot authorize document creation without any orgID") } ps, err := toPerms(influxdb.WriteAction, d.Organizations, nil) if err != nil { return err } if err := IsAllowedAny(ctx, ps); err != nil { return err } return s.s.CreateDocument(ctx, d) } func (s *documentStore) FindDocument(ctx context.Context, id platform.ID) (*influxdb.Document, error) { d, err := s.s.FindDocument(ctx, id) if err != nil { return nil, err } ps, err := toPerms(influxdb.ReadAction, d.Organizations, &id) if err != nil { return nil, err } if err := IsAllowedAny(ctx, ps); err != nil { return nil, err } return d, nil } func (s *documentStore) FindDocuments(ctx context.Context, oid platform.ID) ([]*influxdb.Document, error) { if _, _, err := AuthorizeOrgReadResource(ctx, influxdb.DocumentsResourceType, oid); err != nil { return nil, err } return s.s.FindDocuments(ctx, oid) }