Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions internal/schema/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
// AttrDecls := Name ['?'] ':' Type [',' | ',' AttrDecls]
// AppliesTo := 'appliesTo' '{' AppDecls '}'
// AppDecls := ('principal' | 'resource') ':' EntOrTyps [',' | ',' AppDecls]
// | 'context' ':' RecType [',' | ',' AppDecls]
// | 'context' ':' (Path | RecType) [',' | ',' AppDecls]
// Path := IDENT {'::' IDENT}
// Ref := Path '::' STR | Name
// RefOrRefs := Ref | '[' [RefOrRefs] ']'
Expand Down Expand Up @@ -339,9 +339,10 @@ type AppliesTo struct {
AppliesToTok token.Position
CloseBrace token.Position

Principal []*Path // one of required
Resource []*Path
Context *RecordType // nil if none
Principal []*Path // one of required
Resource []*Path
ContextPath *Path // nil if none
ContextRecord *RecordType // nil if none

Inline *Comment // after {
PrincipalComments NodeComments
Expand Down
6 changes: 4 additions & 2 deletions internal/schema/ast/convert_human.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ func convertNamespace(n *Namespace) *JSONNamespace {
for _, res := range astDecl.AppliesTo.Resource {
jsAction.AppliesTo.ResourceTypes = append(jsAction.AppliesTo.ResourceTypes, res.String())
}
if astDecl.AppliesTo.Context != nil {
jsAction.AppliesTo.Context = convertType(astDecl.AppliesTo.Context)
if astDecl.AppliesTo.ContextRecord != nil {
jsAction.AppliesTo.Context = convertType(astDecl.AppliesTo.ContextRecord)
} else if astDecl.AppliesTo.ContextPath != nil {
jsAction.AppliesTo.Context = convertType(astDecl.AppliesTo.ContextPath)
}
}
jsNamespace.Actions[astActionName.String()] = jsAction
Expand Down
7 changes: 5 additions & 2 deletions internal/schema/ast/convert_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,11 @@ func convertJSONAppliesTo(appliesTo *JSONAppliesTo) *AppliesTo {

// Convert context
if appliesTo.Context != nil {
if context, ok := convertJSONType(appliesTo.Context).(*RecordType); ok {
at.Context = context
switch t := convertJSONType(appliesTo.Context).(type) {
case *RecordType:
at.ContextRecord = t
case *Path:
at.ContextPath = t
}
}

Expand Down
8 changes: 6 additions & 2 deletions internal/schema/ast/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,14 @@ func (p *formatter) printAppliesTo(n *AppliesTo) {
}
p.write("\n")
}
if n.Context != nil {
if n.ContextRecord != nil || n.ContextPath != nil {
p.print(n.ContextComments.Before)
p.printInd("context: ")
p.print(n.Context)
if n.ContextRecord != nil {
p.print(n.ContextRecord)
} else {
p.print(n.ContextPath)
}
p.write(",")
if n.ContextComments.Inline != nil {
p.print(n.ContextComments.Inline)
Expand Down
11 changes: 5 additions & 6 deletions internal/schema/ast/testdata/convert/test.cedarschema
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,17 @@ namespace PhotoFlash {
},
}
};
type authenticatedContext = {
"authenticated": Bool,
};
action "viewPhoto" in [groupAction1, groupAction2, random::nested::name::"actionGroup"] appliesTo {
principal: User,
resource: Photo,
context: {
"authenticated": Bool,
}
context: authenticatedContext,
};
action "listAlbums" appliesTo {
principal: User,
resource: Account,
context: {
"authenticated": Bool,
}
context: authenticatedContext,
};
}
27 changes: 13 additions & 14 deletions internal/schema/ast/testdata/convert/test_want.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
"annotation1": "type",
"annotation2": "type"
}
},
"authenticatedContext": {
"type": "Record",
"attributes": {
"authenticated": {
"type": "Boolean",
"required": true
}
}
}
},
"entityTypes": {
Expand Down Expand Up @@ -162,13 +171,8 @@
"User"
],
"context": {
"type": "Record",
"attributes": {
"authenticated": {
"required": true,
"type": "Boolean"
}
}
"type": "EntityOrCommon",
"name": "authenticatedContext"
}
}
},
Expand Down Expand Up @@ -219,13 +223,8 @@
"User"
],
"context": {
"type": "Record",
"attributes": {
"authenticated": {
"required": true,
"type": "Boolean"
}
}
"type": "EntityOrCommon",
"name": "authenticatedContext"
}
},
"memberOf": [
Expand Down
9 changes: 5 additions & 4 deletions internal/schema/ast/testdata/format/test.cedarschema
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@ namespace PhotoFlash { // inline namespace comment
"authenticated": Bool, // attribute comment inline
}, // context comment
};
type authenticatedContext = {
"authenticated": Bool,
appliesTo: String, // keywords are valid identifiers
};
action "listAlbums" in "read" appliesTo {
principal: User,
resource: Account,
context: {
"authenticated": Bool,
appliesTo: String, // keywords are valid identifiers
},
context: authenticatedContext,
};
// Remainder comment block
// should also be kept around
Expand Down
7 changes: 5 additions & 2 deletions internal/schema/ast/walk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,11 @@ func (vis *visitor) walk(n ast.Node, open, exit func(ast.Node) bool) {
for _, r := range v.Resource {
vis.walk(r, open, exit)
}
if v.Context != nil {
vis.walk(v.Context, open, exit)
if v.ContextRecord != nil {
vis.walk(v.ContextRecord, open, exit)
}
if v.ContextPath != nil {
vis.walk(v.ContextPath, open, exit)
}
case *ast.RecordType:
for _, attr := range v.Attributes {
Expand Down
9 changes: 7 additions & 2 deletions internal/schema/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,14 @@ loop:
case token.CONTEXT:
p.eat()
p.eatOnly(token.COLON, "expected :")
appliesTo.Context = p.parseRecType()
if p.peek().Type == token.LEFTBRACE {
appliesTo.ContextRecord = p.parseRecType()
node = appliesTo.ContextRecord
} else {
appliesTo.ContextPath = p.parsePath()
node = appliesTo.ContextPath
}
nodeComments = &appliesTo.ContextComments
node = appliesTo.Context
case token.COMMENT:
comments = append(comments, p.parseComment())
continue
Expand Down
9 changes: 9 additions & 0 deletions internal/schema/parser/testdata/cases/example.cedarschema
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ namespace PhotoFlash { // inline namespace comment
appliesTo: String, // keywords are valid identifiers
},
};
type commonContext = {
"authenticated": Bool,
appliesTo: String, // keywords are valid identifiers
};
action "commonContext" appliesTo {
principal: User,
resource: Account,
context: commonContext,
};
// Remainder comment block
// should also be kept around
} // Footer comment on namespace
Expand Down
Loading