diff --git a/go.mod b/go.mod index 128e356..bb50ea3 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/aserto-dev/aserto-grpc v0.2.3 github.com/aserto-dev/azm v0.1.10 github.com/aserto-dev/errors v0.0.8 - github.com/aserto-dev/go-directory v0.31.4 + github.com/aserto-dev/go-directory v0.31.5 github.com/bufbuild/protovalidate-go v0.6.2 github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a github.com/gonvenience/ytbx v1.4.4 @@ -27,7 +27,7 @@ require ( go.etcd.io/bbolt v1.3.10 golang.org/x/sync v0.7.0 google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 + google.golang.org/protobuf v1.34.2 ) require ( diff --git a/go.sum b/go.sum index 5ff259a..20d4d78 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/aserto-dev/azm v0.1.10 h1:5WflOnWKQgIlODeXvcZb5XD4eVUK+gIDN1j06b/M0do github.com/aserto-dev/azm v0.1.10/go.mod h1:q9hcNvUbhvy3JvGYOwRq/UT8JKRFBV2aA/3UtcQunzg= github.com/aserto-dev/errors v0.0.8 h1:lqfCc3n8f2VIrsj0hOEmktnqYUS6tffl+w1yJftBhp8= github.com/aserto-dev/errors v0.0.8/go.mod h1:wiQ68oKTyAQVAv+SvB5GyuAD6PewalA/D6Fq30gNUbQ= -github.com/aserto-dev/go-directory v0.31.4 h1:UIs1ArjnyFSay24rJgpIrp4/ttk+xAIqgS5IE954Wfs= -github.com/aserto-dev/go-directory v0.31.4/go.mod h1:fgIT515NcK+4m1UyriBCPMwFHl3DHPaa8yBLbEb9r/I= +github.com/aserto-dev/go-directory v0.31.5 h1:DPGE8SGW2Z3EFS7VB6v0ds81meKXtHGpI0YYrZ7Ea80= +github.com/aserto-dev/go-directory v0.31.5/go.mod h1:fgIT515NcK+4m1UyriBCPMwFHl3DHPaa8yBLbEb9r/I= github.com/aserto-dev/header v0.0.7 h1:hlo5/zYsBOsxzPxtve7LRbXyBbQmKSPAyOfmPhGgirM= github.com/aserto-dev/header v0.0.7/go.mod h1:wDF2S9k2q3lbilNb9q20vPpX8uvlSLYGa4F7p9GtGy4= github.com/aserto-dev/logger v0.0.3 h1:lBB5LMdOsHCJKfEej2xY7s4OzCWUWCBhkhUU6RJ4LbM= @@ -262,8 +262,9 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/directory/v3/importer.go b/pkg/directory/v3/importer.go index 8081453..88f0059 100644 --- a/pkg/directory/v3/importer.go +++ b/pkg/directory/v3/importer.go @@ -91,6 +91,12 @@ func (s *Importer) handleImportRequest(ctx context.Context, tx *bolt.Tx, req *ds return err } + if req.OpCode == dsi3.Opcode_OPCODE_DELETE_WITH_RELATIONS { + err = s.objectDeleteWithRelationsHandler(ctx, tx, m.Object) + res.Object = updateCounter(res.Object, req.OpCode, err) + return err + } + return derr.ErrUnknownOpCode.Msgf("%s - %d", req.OpCode.Enum().String, int32(req.OpCode)) case *dsi3.ImportRequest_Relation: @@ -106,6 +112,10 @@ func (s *Importer) handleImportRequest(ctx context.Context, tx *bolt.Tx, req *ds return err } + if req.OpCode == dsi3.Opcode_OPCODE_DELETE_WITH_RELATIONS { + return derr.ErrInvalidOpCode.Msgf("%s for type relation", req.OpCode.Enum().String) + } + return derr.ErrUnknownOpCode.Msgf("%s - %d", req.OpCode.Enum().String, int32(req.OpCode)) default: @@ -175,6 +185,68 @@ func (s *Importer) objectDeleteHandler(ctx context.Context, tx *bolt.Tx, req *ds return nil } +func (s *Importer) objectDeleteWithRelationsHandler(ctx context.Context, tx *bolt.Tx, req *dsc3.Object) error { + s.logger.Debug().Interface("object", req).Msg("ImportObject") + + if req == nil { + return derr.ErrInvalidObject.Msg("nil") + } + + if err := s.Validate(req); err != nil { + return derr.ErrProtoValidate.Msg(err.Error()) + } + + obj := ds.Object(req) + if err := obj.Validate(s.store.MC()); err != nil { + return err + } + + if err := bdb.Delete(ctx, tx, bdb.ObjectsPath, obj.Key()); err != nil { + return derr.ErrInvalidObject.Msg("delete") + } + + { + // incoming object relations of object instance (result.type == incoming.subject.type && result.key == incoming.subject.key) + iter, err := bdb.NewScanIterator[dsc3.Relation](ctx, tx, bdb.RelationsSubPath, bdb.WithKeyFilter(obj.Key()+ds.InstanceSeparator)) + if err != nil { + return err + } + + for iter.Next() { + rel := ds.Relation(iter.Value()) + if err := bdb.Delete(ctx, tx, bdb.RelationsObjPath, rel.ObjKey()); err != nil { + return err + } + + if err := bdb.Delete(ctx, tx, bdb.RelationsSubPath, rel.SubKey()); err != nil { + return err + } + } + } + + { + // outgoing object relations of object instance (result.type == outgoing.object.type && result.key == outgoing.object.key) + iter, err := bdb.NewScanIterator[dsc3.Relation](ctx, tx, bdb.RelationsObjPath, bdb.WithKeyFilter(obj.Key()+ds.InstanceSeparator)) + if err != nil { + return err + } + + for iter.Next() { + rel := ds.Relation(iter.Value()) + + if err := bdb.Delete(ctx, tx, bdb.RelationsObjPath, rel.ObjKey()); err != nil { + return err + } + + if err := bdb.Delete(ctx, tx, bdb.RelationsSubPath, rel.SubKey()); err != nil { + return err + } + } + } + + return nil +} + func (s *Importer) relationSetHandler(ctx context.Context, tx *bolt.Tx, req *dsc3.Relation) error { s.logger.Debug().Interface("relation", req).Msg("ImportRelation")