-
Notifications
You must be signed in to change notification settings - Fork 11
Feat/grouping userset ttus #493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds new logical node and edge types, updates weighted-graph algorithms to treat them as logical/union operators, and modifies the builder to insert grouping nodes (LogicalUserset, LogicalTTU) that consolidate multiple related edges. Tests are updated to reflect new intermediate nodes, edge routing, and revised error messages. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant P as Parent Node
participant B as Builder
participant LU as LogicalUserset (group)
participant LT as LogicalTTU (group)
participant C as Child Nodes
rect rgba(90,120,180,0.08)
note over B: Direct relation grouping
B->>B: Detect multiple directlyRelated entries
B->>LU: Create LogicalUserset node
P-->>LU: Upsert DirectLogicalEdge
LU-->>C: Upsert DirectEdge to each target
end
rect rgba(120,90,180,0.08)
note over B: TTU relation grouping
B->>B: Detect multiple type tupleset relations
B->>LT: Create LogicalTTU node
P-->>LT: Upsert TTULogicalEdge (labeled by tupleset relation)
LT-->>C: Upsert TTUEdge to each target
end
sequenceDiagram
autonumber
participant WG as WeightedGraph
participant N as Node
participant E as Edges
rect rgba(90,180,120,0.08)
note over WG: AssignWeights / traversal
WG->>N: Visit node
alt isLogicalOperator(N)
WG-->>N: Defer weight assignment
else
WG->>E: calculateNodeWeightFromTheEdges
alt isLogicalUnionOperator(N)
WG-->>N: Union-based cycle/weight handling
else
WG-->>N: Standard edge-based weights
end
end
end
rect rgba(180,140,90,0.08)
note over WG: Strategies
WG->>N: MixedStrategy
N->>E: Require exactly two edges
E-->>N: Merge weights by key (max)
WG->>N: EnforceTypeStrategy
E-->>N: Derive rewriteWeights from common keys across edges
WG-->>N: Assign pruned rewriteWeights
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Pre-merge checks (1 passed, 1 warning, 1 inconclusive)❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/go/graph/weighted_graph_builder.go (1)
144-159
: Remove conditions from TTU edges
Replace the condition argument with an empty string so TTU edges remain condition-agnostic:- wg.UpsertEdge(node, nodeSource, TTUEdge, typeTuplesetRelation, relatedType.GetCondition()) + // TTU edges represent rewrite hops; conditions live on direct relation edges. + wg.UpsertEdge(node, nodeSource, TTUEdge, typeTuplesetRelation, "")
🧹 Nitpick comments (8)
pkg/go/graph/graph_node.go (1)
15-16
: Tighten comments; fix typo ("wherer") and clarify examples.Small doc nits only; enums look fine. Recommend correcting the TTU comment and making both examples consistent.
Apply this diff:
- LogicalUserset NodeType = 4 // e.g. `[user, employee, type1#rel]` - LogicalTTU NodeType = 5 // e.g. `member from parent, wherer parent can have multiple terminal types` + LogicalUserset NodeType = 4 // e.g., `[user, employee, type1#rel]` + LogicalTTU NodeType = 5 // e.g., `viewer from parent`, where parent can resolve to multiple terminal typesOptional: add a String() for NodeType (or use
stringer
) to improve logs/graph dumps.pkg/go/graph/graph_edge.go (1)
11-16
: Add DOT attributes for new logical edges
DirectLogicalEdge and TTULogicalEdge are emitted by the builder but currently fall through to an empty Attributes() case—update the EdgeType Attributes() method in pkg/go/graph/graph_edge.go to return distinct labels (e.g."logical"
and"logical-ttu"
).pkg/go/graph/weighted_graph_builder_test.go (2)
601-603
: Avoid brittle total node/edge counts; assert structure instead.Grouping nodes will keep evolving; fixed totals tend to break. Prefer asserting presence of key nodes/edges/weights (e.g., LogicalUserset node exists, edge types/conditions correct) rather than
require.Len(graph.nodes, 13)
andrequire.Len(graph.edges, 9)
.Example:
// Assert at least one LogicalUserset exists and conditions merged: found := false for _, n := range graph.nodes { if n.nodeType == LogicalUserset { found = true break } } require.True(t, found) ```<!-- review_comment_end --> --- `1222-1222`: **Reduce reliance on global node/edge counts across intersection suites.** The added `require.Len(graph.nodes, X)` and `require.Len(graph.edges, Y)` are fragile with grouping changes. Keep assertions that truly define correctness (weights, types, operator labels), and drop or relax these totals. Example pattern: ```go // Instead of total counts: andEdge := graph.edges["document#viewer"][0] require.Equal(t, OperatorNode, andEdge.to.nodeType) require.Equal(t, "intersection", andEdge.to.label) require.Equal(t, expected, andEdge.GetWeights()) ```<!-- review_comment_end --> Also applies to: 1247-1247, 1270-1270, 1396-1396, 1489-1491, 1514-1516 </blockquote></details> <details> <summary>pkg/go/graph/weighted_graph.go (4)</summary><blockquote> `132-136`: **Deferring logical nodes during initial pass is fine; fix typo** Typo: “Inititally” → “Initially”. --- `153-160`: **Helper for logical-operator detection is correct; fix minor typos** Typos in comments: “asignations” → “assignments”. --- `161-168`: **Helper for union-like logical operators is correct; fix minor typos** Same typo note as above. --- `467-486`: **Cycle handling for union-like logical nodes: LGTM; fix typo** Typo: “depencies” → “dependencies”. </blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: CodeRabbit UI **Review profile**: CHILL **Plan**: Pro <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 222b2371c53f943473b90a323c3dd3d3ec7b92a9 and 2e7e449a39fab2a75b8913ab42d37fa25857ab43. </details> <details> <summary>📒 Files selected for processing (5)</summary> * `pkg/go/graph/graph_edge.go` (1 hunks) * `pkg/go/graph/graph_node.go` (1 hunks) * `pkg/go/graph/weighted_graph.go` (8 hunks) * `pkg/go/graph/weighted_graph_builder.go` (5 hunks) * `pkg/go/graph/weighted_graph_builder_test.go` (12 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🧬 Code graph analysis (3)</summary> <details> <summary>pkg/go/graph/weighted_graph_builder.go (2)</summary><blockquote> <details> <summary>pkg/go/graph/graph_node.go (3)</summary> * `SpecificTypeAndRelation` (12-12) * `LogicalTTU` (16-16) * `LogicalUserset` (15-15) </details> <details> <summary>pkg/go/graph/graph_edge.go (4)</summary> * `TTULogicalEdge` (16-16) * `TTUEdge` (13-13) * `DirectLogicalEdge` (15-15) * `DirectEdge` (11-11) </details> </blockquote></details> <details> <summary>pkg/go/graph/weighted_graph_builder_test.go (3)</summary><blockquote> <details> <summary>pkg/go/graph/graph_node.go (1)</summary> * `LogicalUserset` (15-15) </details> <details> <summary>pkg/go/transformer/dsltojson.go (1)</summary> * `MustTransformDSLToProto` (553-560) </details> <details> <summary>pkg/go/graph/weighted_graph_builder.go (1)</summary> * `NewWeightedAuthorizationModelGraphBuilder` (19-21) </details> </blockquote></details> <details> <summary>pkg/go/graph/weighted_graph.go (2)</summary><blockquote> <details> <summary>pkg/go/graph/weighted_graph_node.go (1)</summary> * `WeightedAuthorizationModelNode` (3-11) </details> <details> <summary>pkg/go/graph/graph_node.go (5)</summary> * `OperatorNode` (13-13) * `LogicalTTU` (16-16) * `LogicalUserset` (15-15) * `UnionOperator` (18-18) * `SpecificTypeAndRelation` (12-12) </details> </blockquote></details> </details> </details> <details> <summary>🔇 Additional comments (7)</summary><blockquote> <details> <summary>pkg/go/graph/weighted_graph_builder_test.go (2)</summary><blockquote> `1203-1216`: **Non-functional DSL formatting only.** These model string edits are cosmetic; no issues. <!-- review_comment_end --> Also applies to: 1231-1241, 1260-1264, 1280-1291, 1303-1314, 1329-1340, 1354-1365, 1379-1390, 1404-1415, 1473-1484, 1498-1508 --- `1445-1445`: **Good switch to ErrorContains for message assertions.** Less brittle than exact equality; keeps tests resilient to wording tweaks. <!-- review_comment_end --> Also applies to: 1465-1465 </blockquote></details> <details> <summary>pkg/go/graph/weighted_graph_builder.go (3)</summary><blockquote> `124-133`: **TTU logical-grouping creation looks good** Condition and labeling are sensible; node reuse via a deterministic uniqueLabel is fine. --- `182-189`: **Direct logical-grouping creation looks good** Creation gate (non-STR parent + >1 directlyRelated) and edge type are correct. --- `209-209`: **Direct edge upsert with condition is correct** De-dupes and aggregates conditions as expected. </blockquote></details> <details> <summary>pkg/go/graph/weighted_graph.go (2)</summary><blockquote> `456-466`: **Cycle handling for non-logical nodes: LGTM** Branching to max-strategy when not logical is consistent. --- `573-574`: **Intersection strategy assignment: LGTM** Directly assigning rewriteWeights is correct. </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
3aa835c
to
360c743
Compare
@yissellokta is it accurate to say that
|
To simplify graph operations, the system now introduces logical nodes (LogicalUsersetNode, LogicalTTUNode) to group related edges together. 🤝
Previously, multiple direct user assignments or multiple "tuple-to-userset" (TTU) edges were treated individually, which complicated algorithms, especially during algebraic operations.
Now, these new "union" nodes are created dynamically to consolidate multiple edges into a single logical unit, significantly reducing complexity for core processes like Check and ListObjects.
Description
The Challenge: Simplifying Complex Edge Relationships
The previous weighted graph model did not inherently group multiple direct userset assignments or multiple "tuple-to-userset" (TTU) edges, even when they originated from the same definition. This created significant implementation challenges for core algorithms in OpenFGA, especially when performing algebraic operations. Essentially, the system failed to treat multiple direct edges or multiple TTU edges as a single logical union, unnecessarily increasing complexity.
The Solution: Introducing Logical Nodes and Edges
To reduce complexity in the Check, ListObjects, and indexer compilation algorithms, we are introducing two new types of "union" nodes and two corresponding "rewrite" edges. These new structures help group related edges into single, manageable units.
New Node Types:
LogicalUsersetNode: Consolidates multiple direct user assignments.
LogicalTTUNode: Consolidates multiple TTU edges that belong to the same definition.
New Edge Types:
DirectLogicalEdge: A rewrite edge connecting to a LogicalUsersetNode.
TTULogicalEdge: A rewrite edge connecting to a LogicalTTUNode.
How It Works: Creation Logic
These new logical nodes are created dynamically under specific conditions:
A LogicalUsersetNode is created when an algebraic operation involves more than one direct edge. All relevant direct edges are then extracted and connected to this new logical node.
A LogicalTTUNode is created when an algebraic operation involves more than one TTU edge from the same definition. These TTU edges are then extracted and grouped under the new logical node.
What problem is being solved?
References
Review Checklist
main
Summary by CodeRabbit