Skip to content

Commit

Permalink
Merge pull request #70 from aserto-dev/validate-relation
Browse files Browse the repository at this point in the history
Validate relation and handle model version updates
  • Loading branch information
ronenh authored Dec 22, 2023
2 parents 134ec42 + d31f579 commit e98c03a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 8 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ go 1.20

require (
github.com/Masterminds/semver v1.5.0
github.com/aserto-dev/azm v0.0.18-0.20231215145029-08d85340740a
github.com/aserto-dev/azm v0.0.18-0.20231219183923-e16ead528b5a
github.com/aserto-dev/errors v0.0.6
github.com/aserto-dev/go-directory v0.30.6
github.com/bufbuild/protovalidate-go v0.4.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/aserto-dev/azm v0.0.18-0.20231215145029-08d85340740a h1:JKYmrI0RsbsQaHUaYrnT46dIfBUs0yeMgiQXtEprZeo=
github.com/aserto-dev/azm v0.0.18-0.20231215145029-08d85340740a/go.mod h1:t/+CxbaWuS8qzwrVZZefHSNtQf8aK44imB+/rC4uOyw=
github.com/aserto-dev/azm v0.0.18-0.20231219183923-e16ead528b5a h1:kVqe06zry7JrAB9IUKdji4mMpwW049EZMu/Se3XiUr0=
github.com/aserto-dev/azm v0.0.18-0.20231219183923-e16ead528b5a/go.mod h1:t/+CxbaWuS8qzwrVZZefHSNtQf8aK44imB+/rC4uOyw=
github.com/aserto-dev/errors v0.0.6 h1:iH5fkJwBGFPbcdS4B8mwvNdwODlhDEXXPduZtjLh6vo=
github.com/aserto-dev/errors v0.0.6/go.mod h1:kenI1gamsemaR2wS+M2un0kXIJ9exTrmeRT/fCFwlWc=
github.com/aserto-dev/go-directory v0.30.6 h1:JdxofQIHyqrHJxn1L/vxiYamCYFX6rGeuMUkkQkai7g=
Expand Down
49 changes: 45 additions & 4 deletions pkg/bdb/model.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package bdb

import (
"context"
"bytes"
"encoding/json"

"github.com/aserto-dev/azm/model"
v3 "github.com/aserto-dev/azm/v3"
bolt "go.etcd.io/bbolt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand All @@ -13,21 +15,37 @@ import (
// and swaps the model instance in the cache.Cache using
// cache.UpdateModel.
func (s *BoltDB) LoadModel() error {
ctx := context.Background()

err := s.db.View(func(tx *bolt.Tx) error {
if ok, _ := BucketExists(tx, ManifestPath); !ok {
return nil
}

mod, err := GetAny[model.Model](ctx, tx, ManifestPath, ModelKey)
buf, version, err := readModel(tx)
switch {
case status.Code(err) == codes.NotFound:
return nil
case err != nil:
return err
}

var mod *model.Model

switch version {
case model.ModelVersion:
// The serialized model is on the latest version
var m model.Model
if err := json.Unmarshal(buf, &m); err != nil {
return err
}
mod = &m
default:
// need to reload the model from the manifest
mod, err = fromManifest(tx)
if err != nil {
return err
}
}

if err := s.mc.UpdateModel(mod); err != nil {
return err
}
Expand All @@ -37,3 +55,26 @@ func (s *BoltDB) LoadModel() error {

return err
}

func readModel(tx *bolt.Tx) ([]byte, int, error) {
buf, err := GetKey(tx, ManifestPath, ModelKey)
if err != nil {
return nil, 0, err
}

var m map[string]any
if err := json.Unmarshal(buf, &m); err != nil {
return nil, 0, err
}

return buf, int(m["version"].(float64)), nil
}

func fromManifest(tx *bolt.Tx) (*model.Model, error) {
manifest, err := GetKey(tx, ManifestPath, BodyKey)
if err != nil {
return nil, err
}

return v3.Load(bytes.NewReader(manifest))
}
5 changes: 5 additions & 0 deletions pkg/directory/v3/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ func (s *Importer) relationSetHandler(ctx context.Context, tx *bolt.Tx, req *dsc
return derr.ErrProtoValidate.Msg(err.Error())
}

if err := s.store.MC().ValidateRelation(req); err != nil {
// The relation violates the model.
return err
}

etag := ds.Relation(req).Hash()

updReq, err := bdb.UpdateMetadata(ctx, tx, bdb.RelationsObjPath, ds.Relation(req).ObjKey(), req)
Expand Down
5 changes: 5 additions & 0 deletions pkg/directory/v3/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ func (s *Writer) SetRelation(ctx context.Context, req *dsw3.SetRelationRequest)
return resp, derr.ErrProtoValidate.Msg(err.Error())
}

if err := s.store.MC().ValidateRelation(req.Relation); err != nil {
// The relation violates the model.
return resp, err
}

etag := ds.Relation(req.Relation).Hash()

err := s.store.DB().Update(func(tx *bolt.Tx) error {
Expand Down
4 changes: 3 additions & 1 deletion tests/manifest_v3_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ model:
# object type definitions
types:
# user represents a user that can be granted role(s)
user: {}
user:
relations:
manager: user

# group represents a collection of users and/or (nested) groups
group:
Expand Down
1 change: 1 addition & 0 deletions tests/relation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ var relationTestCasesWithID = []*TestCase{
},
},
Checks: func(t *testing.T, msg proto.Message, tErr error) func(proto.Message) {
require.NoError(t, tErr)
require.NotNil(t, msg)
switch resp := msg.(type) {
case *dsw2.SetRelationResponse:
Expand Down
2 changes: 2 additions & 0 deletions tests/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ func testRunner(t *testing.T, tcs []*TestCase) {

ctx := context.Background()

t.Run("set manifest", testSetManifest(client, "./manifest_v3_test.yaml"))

var apply func(proto.Message)

for _, tc := range tcs {
Expand Down

0 comments on commit e98c03a

Please sign in to comment.