Skip to content

Commit d842a97

Browse files
authored
chore: implement self in schemav2 (#2887)
1 parent 7f9bd27 commit d842a97

File tree

8 files changed

+93
-1
lines changed

8 files changed

+93
-1
lines changed

pkg/schema/arrows.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ func (as *ArrowSet) collectArrowInformationForSetOperation(ctx context.Context,
180180
case *core.SetOperation_Child_XNil:
181181
// Nothing to do
182182

183+
case *core.SetOperation_Child_XSelf:
184+
// Nothing to do
185+
183186
default:
184187
return fmt.Errorf("unknown set operation child `%T` in addArrowRelationsInSetOperation", child)
185188
}

pkg/schema/full_reachability.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ func setOperationReferencesRelation(ctx context.Context, so *core.SetOperation,
220220
case *core.SetOperation_Child_XNil:
221221
// Nothing to do
222222

223+
case *core.SetOperation_Child_XSelf:
224+
// Nothing to do
225+
223226
default:
224227
return false, fmt.Errorf("unknown set operation child `%T` in setOperationReferencesRelation", child)
225228
}

pkg/schema/v2/flatten.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ func flattenOperation(op Operation, def *Definition, baseName string, options Fl
185185
// Nil reference is a leaf node, no flattening needed
186186
return o, nil, nil
187187

188+
case *SelfReference:
189+
// Self reference is a leaf node, no flattening needed
190+
return o, nil, nil
191+
188192
case *UnionOperation:
189193
// Flatten children first
190194
flattenedChildren := make([]Operation, len(o.children))

pkg/schema/v2/flatten_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ definition user {}`,
3232
3333
definition user {}`,
3434
},
35+
{
36+
name: "self permission",
37+
schemaString: `use self
38+
definition user {
39+
permission view = self
40+
}`,
41+
expectedString: `use self
42+
definition user {
43+
permission view = self
44+
}`,
45+
},
3546
{
3647
name: "nested union in permission",
3748
schemaString: `definition document {

pkg/schema/v2/resolved.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ func resolveOperation(op Operation, def *Definition) (Operation, error) {
151151
// NilReference is not replaced during resolution
152152
return o, nil
153153

154+
case *SelfReference:
155+
// SelfReference is not replaced during resolution
156+
return o, nil
157+
154158
default:
155159
return nil, fmt.Errorf("unknown operation type: %T", op)
156160
}

pkg/schema/v2/resolved_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,35 @@ func TestResolveSchema_Empty(t *testing.T) {
2929
require.Empty(t, resolved.Schema().definitions)
3030
}
3131

32+
func TestResolveSchema_SelfReference(t *testing.T) {
33+
schema := &Schema{
34+
definitions: map[string]*Definition{
35+
"user": {
36+
name: "user",
37+
permissions: map[string]*Permission{
38+
"view": {
39+
name: "view",
40+
operation: &SelfReference{},
41+
},
42+
},
43+
},
44+
},
45+
}
46+
47+
resolved, err := ResolveSchema(schema)
48+
require.NoError(t, err)
49+
require.NotNil(t, resolved)
50+
51+
// Check that the original schema is unchanged
52+
originalPerm := schema.definitions["user"].permissions["view"]
53+
require.IsType(t, &SelfReference{}, originalPerm.operation)
54+
55+
// Check that the resolved schema has ResolvedRelationReference
56+
resolvedDef := resolved.Schema().definitions["user"]
57+
resolvedPerm := resolvedDef.permissions["view"]
58+
require.IsType(t, &SelfReference{}, resolvedPerm.operation)
59+
}
60+
3261
func TestResolveSchema_SimpleRelationReference(t *testing.T) {
3362
rel := &Relation{
3463
name: "viewer",

pkg/schema/v2/tocorev1.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,19 @@ func operationToUsersetRewrite(op Operation) (*core.UsersetRewrite, error) {
344344
},
345345
}, nil
346346

347+
case *SelfReference:
348+
return &core.UsersetRewrite{
349+
RewriteOperation: &core.UsersetRewrite_Union{
350+
Union: &core.SetOperation{
351+
Child: []*core.SetOperation_Child{
352+
{
353+
ChildType: &core.SetOperation_Child_XSelf{},
354+
},
355+
},
356+
},
357+
},
358+
}, nil
359+
347360
default:
348361
return nil, fmt.Errorf("unknown operation type: %T", op)
349362
}
@@ -462,6 +475,11 @@ func operationToChild(op Operation) (*core.SetOperation_Child, error) {
462475
ChildType: &core.SetOperation_Child_XNil{},
463476
}, nil
464477

478+
case *SelfReference:
479+
return &core.SetOperation_Child{
480+
ChildType: &core.SetOperation_Child_XSelf{},
481+
}, nil
482+
465483
default:
466484
return nil, fmt.Errorf("unknown operation type: %T", op)
467485
}

pkg/schema/v2/tocorev1_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ func TestAsCompiledSchema(t *testing.T) {
119119
expectedDefinitionNames: []string{"user", "organization", "resource"},
120120
expectedCaveatNames: []string{},
121121
},
122+
{
123+
name: "schema with self",
124+
schemaText: `
125+
use self
126+
127+
definition user {
128+
relation viewer: user
129+
permission view = viewer + self
130+
}
131+
`,
132+
expectedNumDefinitions: 1,
133+
expectedNumCaveats: 0,
134+
expectedDefinitionNames: []string{"user"},
135+
expectedCaveatNames: []string{},
136+
},
122137
}
123138

124139
for _, tc := range tcs {
@@ -172,11 +187,16 @@ func TestAsCompiledSchemaRoundTrip(t *testing.T) {
172187
t.Parallel()
173188

174189
schemaText := `
190+
use self
191+
175192
caveat ip_check(ip string) {
176193
ip == "192.168.1.1"
177194
}
178195
179-
definition user {}
196+
definition user {
197+
relation viewer: user
198+
permission view = viewer + self
199+
}
180200
181201
definition organization {
182202
relation member: user

0 commit comments

Comments
 (0)