-
Notifications
You must be signed in to change notification settings - Fork 23
Specification
See PML [lexer](TODO INSERT PATH TO lexer) and [grammar](path to grammar) for full documentation and details. The below ANTLR4 definitions have been slightly modified for readability.
The syntax for basic PML statements is loosely based on Golang)
// this is line comment
/*
this is a block comment
*/
ID: [a-zA-Z0-9_]+;
variableType:
string
| bool
| []variableType
| map[variableType]variableType
| any ;
The any
type will compile without error regardless of expected type. However, during execution if the evaluated type does not match the expected, an error will occur.
Expressions are the fundamental way to define values in PML statements. Each expression has a type. Some statements will only support expressions of a certain type.
literal:
stringLiteral
| boolLiteral
| mapLiteral
| arrayLiteral ;
stringLiteral: '"' (~["\\\r\n] | EscapeSequence)* '"' ;
boolLiteral: (true | false) ;
mapLiteral: '[' expression (',' expression)* ']' ;
arrayLiteral: '{' expression: expression (',' expression: expression)* '}' ;
fragment EscapeSequence
: '\\' [btnfr"'\\]
| '\\' ([0-3]? [0-7])? [0-7]
| '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit
;
fragment HexDigits
: HexDigit ((HexDigit | '_')* HexDigit)?
;
fragment HexDigit
: [0-9a-fA-F]
;
- Array elements are expressions
- Map key and value elements are expressions
expression ('&&' | '||') expression
(expression)
expression ('==' | '!=') expression
expression + expression
Only string expressions are supported.
!expression
The negation expression when evaluated will only affect the result if the expression is a boolean expression. For example if the expression evaluates to true, the negated expression will evaluate to false. For any other type, the negation is ignored.
variableReference:
ID
| variableReference index;
index:
'[' expression ']' #BracketNotation
| '.' ID;
RefByIndex
requires the variableReference
to be of type map
. To use the DotNotation
the variable must be map with string keys.
ID '(' (expression (',' expression)*)? ')'
'var' ID = expression
ID := expression
'var ('
(ID '=' expression)*
')'
ID '=' expression
The variable to be reassigned must already exist.
ID '+=' expression
The variable must already exist AND be of type string.
'if' expression '{' statement* '}'
('else if {' statement* '}' )*
(else {' statement* '}' )?
Use break
and continue
to short circuit
'foreach' ID (',' ID)? 'in' expression '{' statement* '}' ;
for x in ["a", "b", "c"] {
...
}
x
will hold the current element in the array during iteration.
for x, y in {"key1": "value1", "key2": "value2"} {
...
}
x
will hold the current key in the map during iteration.
y
will hold the current value in the map during iteration.
('operation' | 'routine') ID '(' ('nodeop'? variableType ID (',' 'nodeop'? variableType ID)*)? ')' variableType? '{' checkStatement* '}' '{' statement* '}' ;
-
nodeop
denotes if the operand is a node operand.
Check if a user has an access right on a node or array of nodes. The first expression is the access right the second is the node or array of nodes. This statement will only take affect in an Operation, not a routine.
check expression on expression
Function that returns a string
.
operation op1(a string, b []string, c map[string]string) string {
check "assign" on a
check "assign_to" on b
} {
/*
pml statements
*/
}
Create a policy class node with the given name, properties (optional) and attribute hierarchy (optional).
'create policy class' name=expression
Create a node of type object attribute, user attribute, object, or user with properties (optional) and assign it to a set of existing nodes.
'create' ('object attribute' | 'user attribute' | 'object' | 'user') name=expression
'in' assignTo=expression
-
name
is a string expression. -
properties
is a map[string]string expression. -
assignTo
is a []string expression.
Set the properties for a node. This will overwrite any existing properties.
'set properties of' name=expression 'to' properties=expression
-
name
is a string expression. -
properties
is a map[string]string expression.
Assign a node to a set of nodes.
'assign' childNode=expression 'to' parentNodes=expression
-
childNode
is a string expression. -
parentNodes
is a []string expression.
Deassign a node from a set of nodes.
'deassign' childNode=expression 'from' parentNodes=expression
-
childNode
is a string expression. -
parentNodes
is a []string expression.
Create an association between two nodes with an access right set.
'associate' ua=expression 'and' target=expression 'with' accessRights=expression
-
ua
is a string expression. -
target
is a string expression. -
accessRights
is a []string expression.
Delete an association.
'dissociate' ua=expression 'and' target=expression
-
ua
is a string expression. -
target
is a string expression.
Create a new prohibition.
'create prohibition' name=expression
'deny' ('user' | 'user attribute' | 'process') subject=expression
'access rights' accessRights=expression
'on' ('intersection'|'union') 'of' containers=expression ;
-
name
is a string expression. -
subject
is a string expression. -
accessRights
is a []string expression. -
containers
is a []string expression. Complement containers are specified using a negation expression, where the negated expression is a string. For example,!"oa1"
Create new obligation. The author of the obligation will be the user that compiles and executes the PML.
createObligationStatement:
'create obligation' name=expression '{' createRuleStatement* '}';
createRuleStatement:
'create rule' ruleName=expression
'when' subjectPattern
'performs' operationPattern
('on' operandPattern)?
response ;
// subject
subjectPattern:
'any user' #AnyUserPattern
| 'user' subjectPatternExpression #UserPattern;
subjectPatternExpression:
basicSubjectPatternExpr
| '!' subjectPatternExpression
| '(' subjectPatternExpression ')'
| left=subjectPatternExpression ('&&' | '||') right=subjectPatternExpression ;
basicSubjectPatternExpr:
'in' stringLit // contained in
| stringLit // equals
| 'process' stringLit ;
// operation
operationPattern:
'any operation'
| stringLit ;
// operands
operandPattern: '{' (operandPatternElement (',' operandPatternElement)*)? '}' ;
operandPatternElement: key=ID ':' (single=operandPatternExpression | multiple=operandPatternExpressionArray);
operandPatternExpressionArray: '[' operandPatternExpression (',' operandPatternExpression)* ']' ;
operandPatternExpression:
basicOperandPatternExpr
| '!' operandPatternExpression
| '(' operandPatternExpression ')'
| left=operandPatternExpression ('&&' | '||') right=operandPatternExpression ;
basicOperandPatternExpr:
'any'
| 'in' stringLit // contained in
| stringLit // equals ;
// response
response:
'do (' ID ')' responseBlock;
responseBlock:
'{' responseStatement* '}' ;
responseStatement:
statement
| createRuleStatement
| deleteRuleStatement ;
-
name
is a string expression. -
ruleName
is a string expression. - operand pattern expressions can only be defined for node operands of the given operation. Any non node operations (i.e. access rights) will be ignored.
- if an event context operand is an array of nodes and
- the operand expression is a single expression, the single expression will only need to match one element in the array
- the operand expression is multiple expressions, each expression will be compared to the array as if it was a single expression
Delete a node, prohibition, or obligation.
'delete'
('policy class' | 'object attribute' | 'user attribute' | 'object' | 'user' | 'obligation' | 'prohibition') expression
-
expression
is a string expression.
Delete a rule from an obligation. Can only be called from an obligation response block.
'delete rule' ruleName=expression 'from obligation' obligationName=expression ;
-
ruleName
is a string expression. -
obligationName
is a string expression.
- Variables cannot be referenced from inside operations and routines.
- A user context is needed when executing PML. This is only used for obligations to define the user to execute the response on behalf of in the EPP.
- This user must exist before any obligation is created.
String pml = "...";
pap.executePML(new UserContext("user1", pml));
- Any operations and routines will be stored in the policy store.
- All [admin policy nodes](INSERT. LINK) will be defined as constants during compilation and execution.
create object attribute "oa1" assign to [PM_ADMIN_OBJECT]