forked from Permify/permify
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschema.go
More file actions
121 lines (111 loc) · 3.26 KB
/
Copy pathschema.go
File metadata and controls
121 lines (111 loc) · 3.26 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package graph
import (
"errors"
"fmt"
"strings"
"github.com/rs/xid"
"github.com/Permify/permify/internal/schema"
base "github.com/Permify/permify/pkg/pb/base/v1"
"github.com/Permify/permify/pkg/tuple"
)
// SchemaToGraph - Convert schema to graph
func SchemaToGraph(schema *base.SchemaDefinition) (g Graph, err error) {
for _, en := range schema.GetEntityDefinitions() {
eg, err := EntityToGraph(en)
if err != nil {
return Graph{}, err
}
g.AddNodes(eg.Nodes())
g.AddEdges(eg.Edges())
}
return
}
// EntityToGraph - Convert entity to graph
func EntityToGraph(entity *base.EntityDefinition) (g Graph, err error) {
enNode := &Node{
Type: "entity",
ID: fmt.Sprintf("entity:%s", entity.GetName()),
Label: entity.GetName(),
}
g.AddNode(enNode)
for _, re := range entity.GetRelations() {
reNode := &Node{
Type: "relation",
ID: fmt.Sprintf("entity:%s:permission:%s", entity.GetName(), re.GetName()),
Label: re.Name,
}
g.AddNode(reNode)
g.AddEdge(enNode, reNode, nil)
}
for _, action := range entity.GetActions() {
acNode := &Node{
Type: "action",
ID: fmt.Sprintf("entity:%s:permission:%s", entity.GetName(), action.GetName()),
Label: action.GetName(),
}
g.AddNode(acNode)
g.AddEdge(enNode, acNode, nil)
ag, err := buildActionGraph(entity, acNode, []*base.Child{action.GetChild()})
if err != nil {
return Graph{}, err
}
g.AddNodes(ag.Nodes())
g.AddEdges(ag.Edges())
}
return
}
// buildActionGraph - creates action graph
func buildActionGraph(entity *base.EntityDefinition, from *Node, children []*base.Child) (g Graph, err error) {
for _, child := range children {
switch child.GetType().(type) {
case *base.Child_Rewrite:
rw := &Node{
Type: "logic",
ID: xid.New().String(),
Label: child.GetRewrite().GetRewriteOperation().String(),
}
g.AddNode(rw)
g.AddEdge(from, rw, nil)
ag, err := buildActionGraph(entity, rw, child.GetRewrite().GetChildren())
if err != nil {
return Graph{}, err
}
g.AddNodes(ag.Nodes())
g.AddEdges(ag.Edges())
case *base.Child_Leaf:
leaf := child.GetLeaf()
switch leaf.GetType().(type) {
case *base.Leaf_TupleToUserSet:
re, err := schema.GetRelationByNameInEntityDefinition(entity, leaf.GetTupleToUserSet().GetTupleSet().GetRelation())
if err != nil {
return Graph{}, errors.New(base.ErrorCode_ERROR_CODE_RELATION_DEFINITION_NOT_FOUND.String())
}
g.AddEdge(from, &Node{
Type: "relation",
ID: fmt.Sprintf("entity:%s:permission:%s", GetMainReference(re), leaf.GetTupleToUserSet().GetComputed().GetRelation()),
Label: leaf.GetTupleToUserSet().GetComputed().GetRelation(),
}, leaf.GetExclusion())
case *base.Leaf_ComputedUserSet:
g.AddEdge(from, &Node{
Type: "relation",
ID: fmt.Sprintf("entity:%s:permission:%s", entity.GetName(), leaf.GetComputedUserSet().GetRelation()),
Label: leaf.GetComputedUserSet().GetRelation(),
}, leaf.GetExclusion())
default:
break
}
}
}
return
}
// GetMainReference -
func GetMainReference(definition *base.RelationDefinition) string {
if len(definition.GetRelationReferences()) > 1 {
for _, ref := range definition.GetRelationReferences() {
if !strings.Contains(ref.String(), "#") {
return ref.String()
}
}
}
return tuple.USER
}