Skip to content

Commit 7501631

Browse files
authored
feat: basic support for exclusion in graph (#321)
2 parents 0745458 + fc6d925 commit 7501631

File tree

2 files changed

+108
-3
lines changed

2 files changed

+108
-3
lines changed

pkg/go/graph/graph_builder.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ type AuthorizationModelGraphBuilder struct {
2222
//
2323
// The edges are defined by the assignments, e.g.
2424
// `define viewer: [group]` defines an edge from group to document#viewer.
25-
// TODO expand when more use cases are added.
25+
// Conditions are not encoded in the graph,
26+
// and the two edges in an exclusion are not distinguished.
2627
func NewAuthorizationModelGraph(model *openfgav1.AuthorizationModel) (*AuthorizationModelGraph, error) {
2728
res, err := parseModel(model)
2829
if err != nil {
@@ -98,8 +99,12 @@ func checkRewrite(graphBuilder *AuthorizationModelGraphBuilder, parentNode *Auth
9899
operator = "intersection"
99100
children = rw.Intersection.GetChild()
100101

101-
default:
102-
panic("TODO handle difference")
102+
case *openfgav1.Userset_Difference:
103+
operator = "exclusion"
104+
children = []*openfgav1.Userset{
105+
rw.Difference.GetBase(),
106+
rw.Difference.GetSubtract(),
107+
}
103108
}
104109

105110
operatorNode := fmt.Sprintf("%s:%s", operator, ulid.Make().String())

pkg/go/graph/graph_builder_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,106 @@ rankdir=BT
537537
2 -> 1 [label=direct];
538538
2 -> 5 [label=direct];
539539
5 -> 4 [style=dashed];
540+
}`,
541+
},
542+
`exclusion_of_relations`: {
543+
model: `
544+
model
545+
schema 1.1
546+
type user
547+
type folder
548+
relations
549+
define a: [user]
550+
define b: [user]
551+
define c: a but not b`,
552+
expectedOutput: `digraph {
553+
graph [
554+
rankdir=BT
555+
];
556+
557+
// Node definitions.
558+
0 [label=folder];
559+
1 [label="folder#a"];
560+
2 [label=user];
561+
3 [label="folder#b"];
562+
4 [label="folder#c"];
563+
5 [label=exclusion];
564+
565+
// Edge definitions.
566+
1 -> 5 [style=dashed];
567+
2 -> 1 [label=direct];
568+
2 -> 3 [label=direct];
569+
3 -> 5 [style=dashed];
570+
5 -> 4 [style=dashed];
571+
}`,
572+
},
573+
`exclusion_of_relation_and_type`: {
574+
model: `
575+
model
576+
schema 1.1
577+
type user
578+
type folder
579+
relations
580+
define a: [user]
581+
define b: [user] but not a`,
582+
expectedOutput: `digraph {
583+
graph [
584+
rankdir=BT
585+
];
586+
587+
// Node definitions.
588+
0 [label=folder];
589+
1 [label="folder#a"];
590+
2 [label=user];
591+
3 [label="folder#b"];
592+
4 [label=exclusion];
593+
594+
// Edge definitions.
595+
1 -> 4 [style=dashed];
596+
2 -> 1 [label=direct];
597+
2 -> 4 [label=direct];
598+
4 -> 3 [style=dashed];
599+
}`,
600+
},
601+
`exclusion_with_parens`: {
602+
model: `
603+
model
604+
schema 1.1
605+
type user
606+
type folder
607+
relations
608+
define a: [user]
609+
define b: [user]
610+
define c: [user]
611+
define d: [user]
612+
define e: (a or b or c) but not d`,
613+
expectedOutput: `digraph {
614+
graph [
615+
rankdir=BT
616+
];
617+
618+
// Node definitions.
619+
0 [label=folder];
620+
1 [label="folder#a"];
621+
2 [label=user];
622+
3 [label="folder#b"];
623+
4 [label="folder#c"];
624+
5 [label="folder#d"];
625+
6 [label="folder#e"];
626+
7 [label=exclusion];
627+
8 [label=union];
628+
629+
// Edge definitions.
630+
1 -> 8 [style=dashed];
631+
2 -> 1 [label=direct];
632+
2 -> 3 [label=direct];
633+
2 -> 4 [label=direct];
634+
2 -> 5 [label=direct];
635+
3 -> 8 [style=dashed];
636+
4 -> 8 [style=dashed];
637+
5 -> 7 [style=dashed];
638+
7 -> 6 [style=dashed];
639+
8 -> 7 [style=dashed];
540640
}`,
541641
},
542642
}

0 commit comments

Comments
 (0)