/
validation.go
75 lines (64 loc) · 1.59 KB
/
validation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package v0
import (
"context"
"fmt"
v0 "github.com/authzed/authzed-go/proto/authzed/api/v0"
"github.com/shopspring/decimal"
"github.com/authzed/spicedb/internal/namespace"
)
type invalidRelationError struct {
error
subject *v0.User
onr *v0.ObjectAndRelation
}
func validateTupleWrite(
ctx context.Context,
tpl *v0.RelationTuple,
nsm namespace.Manager,
revision decimal.Decimal,
) error {
if err := nsm.CheckNamespaceAndRelation(
ctx,
tpl.ObjectAndRelation.Namespace,
tpl.ObjectAndRelation.Relation,
false, // Disallow ellipsis
revision,
); err != nil {
return err
}
if err := nsm.CheckNamespaceAndRelation(
ctx,
tpl.User.GetUserset().Namespace,
tpl.User.GetUserset().Relation,
true, // Allow Ellipsis
revision,
); err != nil {
return err
}
_, ts, err := nsm.ReadNamespaceAndTypes(ctx, tpl.ObjectAndRelation.Namespace, revision)
if err != nil {
return err
}
if ts.IsPermission(tpl.ObjectAndRelation.Relation) {
return invalidRelationError{
error: fmt.Errorf("cannot write a relationship to permission %s", tpl.ObjectAndRelation),
subject: tpl.User,
onr: tpl.ObjectAndRelation,
}
}
isAllowed, err := ts.IsAllowedDirectRelation(
tpl.ObjectAndRelation.Relation,
tpl.User.GetUserset().Namespace,
tpl.User.GetUserset().Relation)
if err != nil {
return err
}
if isAllowed == namespace.DirectRelationNotValid {
return invalidRelationError{
error: fmt.Errorf("relation/permission %v is not allowed as the subject of %v", tpl.User, tpl.ObjectAndRelation),
subject: tpl.User,
onr: tpl.ObjectAndRelation,
}
}
return nil
}