Skip to content

Commit

Permalink
fix: relax OPL parsing (#1059)
Browse files Browse the repository at this point in the history
* Allow semicolons in more places
* Allow commas in more places
  • Loading branch information
hperl committed Oct 10, 2022
1 parent 2b03d6f commit a15c5ad
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
{
"Resource": [
{
"name": "admins",
"types": [
{
"namespace": "Role",
"relation": "member"
}
]
},
{
"name": "supervisors",
"types": [
{
"namespace": "Role",
"relation": "member"
}
]
},
{
"name": "annotators",
"types": [
{
"namespace": "Role",
"relation": "member"
}
]
},
{
"name": "medicalAnnotators",
"types": [
{
"namespace": "Role",
"relation": "member"
}
]
},
{
"name": "read",
"rewrite": {
"operator": "or",
"children": [
{
"relation": "admins",
"computed_subject_set_relation": "member"
},
{
"relation": "annotators",
"computed_subject_set_relation": "member"
},
{
"relation": "medicalAnnotators",
"computed_subject_set_relation": "member"
},
{
"relation": "supervisors",
"computed_subject_set_relation": "member"
}
]
}
},
{
"name": "update",
"rewrite": {
"operator": "or",
"children": [
{
"relation": "admins",
"computed_subject_set_relation": "member"
},
{
"relation": "annotators",
"computed_subject_set_relation": "member"
},
{
"relation": "medicalAnnotators",
"computed_subject_set_relation": "member"
},
{
"relation": "supervisors",
"computed_subject_set_relation": "member"
}
]
}
},
{
"name": "create",
"rewrite": {
"operator": "or",
"children": [
{
"relation": "admins",
"computed_subject_set_relation": "member"
},
{
"relation": "annotators",
"computed_subject_set_relation": "member"
},
{
"relation": "supervisors",
"computed_subject_set_relation": "member"
}
]
}
},
{
"name": "approve",
"rewrite": {
"operator": "or",
"children": [
{
"relation": "admins",
"computed_subject_set_relation": "member"
},
{
"relation": "supervisors",
"computed_subject_set_relation": "member"
}
]
}
},
{
"name": "delete",
"rewrite": {
"operator": "or",
"children": [
{
"relation": "admins",
"computed_subject_set_relation": "member"
},
{
"relation": "supervisors",
"computed_subject_set_relation": "member"
}
]
}
}
],
"Role": [
{
"name": "member",
"types": [
{
"namespace": "Role"
}
]
}
]
}
23 changes: 12 additions & 11 deletions internal/schema/itemtype_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions internal/schema/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,16 @@ const (
itemKeywordCtx

// operators
itemOperatorAnd // "&&"
itemOperatorOr // "||"
itemOperatorNot // "!"
itemOperatorAssign // "="
itemOperatorArrow // "=>"
itemOperatorDot // "."
itemOperatorColon // ":"
itemOperatorComma // ","
itemTypeUnion // "|"
itemOperatorAnd // "&&"
itemOperatorOr // "||"
itemOperatorNot // "!"
itemOperatorAssign // "="
itemOperatorArrow // "=>"
itemOperatorDot // "."
itemOperatorColon // ":"
itemOperatorComma // ","
itemOperatorSemicolon // ";"
itemTypeUnion // "|"

// brackets
itemParenLeft // "("
Expand Down Expand Up @@ -217,6 +218,7 @@ var oneRuneTokens = map[rune]itemType{
'>': itemAngledRight,
'=': itemOperatorAssign,
',': itemOperatorComma,
';': itemOperatorSemicolon,
'|': itemTypeUnion,
'!': itemOperatorNot,
}
Expand Down
4 changes: 3 additions & 1 deletion internal/schema/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func (p *parser) parseClass() {
p.parseRelated()
case item.Val == "permits":
p.parsePermits()
case item.Typ == itemOperatorSemicolon:
continue
default:
p.addFatal(item, "expected 'permits' or 'related', got %q", item.Val)
return
Expand Down Expand Up @@ -205,7 +207,7 @@ func (p *parser) parseRelated() {
case itemParenLeft:
types = append(types, p.parseTypeUnion()...)
}
p.match("[", "]")
p.match("[", "]", optional(","))
p.namespace.Relations = append(p.namespace.Relations, ast.Relation{
Name: relation,
Types: types,
Expand Down
43 changes: 43 additions & 0 deletions internal/schema/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,49 @@ var parserTestCases = []struct {
this.related.siblings.traverse(s => s.permits.edit(ctx)),
}
}
`}, {"advanced typescript syntax",
`
import { Namespace, SubjectSet, Context } from '@ory/keto-namespace-types';
class Role implements Namespace {
related: {
member: Role[]
}
}
class Resource implements Namespace {
related: {
admins: SubjectSet<Role, 'member'>[],
supervisors: SubjectSet<Role, 'member'>[],
annotators: SubjectSet<Role, 'member'>[],
medicalAnnotators: SubjectSet<Role, 'member'>[],
};
permits = {
read: (ctx: Context) => this.related.admins.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.annotators.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.medicalAnnotators.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.supervisors.traverse((role) => role.related.member.includes(ctx.subject)),
// TODO: support referencing permits.
// comment: (ctx: Context) => this.permits.read(ctx),
update: (ctx: Context) => this.related.admins.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.annotators.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.medicalAnnotators.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.supervisors.traverse((role) => role.related.member.includes(ctx.subject)),
create: (ctx: Context) => this.related.admins.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.annotators.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.supervisors.traverse((role) => role.related.member.includes(ctx.subject)),
approve: (ctx: Context) => this.related.admins.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.supervisors.traverse((role) => role.related.member.includes(ctx.subject)),
delete: (ctx: Context) => this.related.admins.traverse((role) => role.related.member.includes(ctx.subject)) ||
this.related.supervisors.traverse((role) => role.related.member.includes(ctx.subject)),
};
}
`},
}

Expand Down

0 comments on commit a15c5ad

Please sign in to comment.