in src/PSRule.Rules.Azure/Data/Policy/PolicyAssignmentVisitor.cs [1312:1499]
private static JObject VisitFieldTokens(PolicyAssignmentContext context, JObject condition, TokenStream tokens)
{
if (tokens.ConsumeFunction(PROPERTY_FIELD) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _) &&
tokens.ConsumeString(out var field) &&
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _))
{
// Handle [field('type')]
if (string.Equals(field, PROPERTY_TYPE, StringComparison.OrdinalIgnoreCase))
{
condition.RemoveProperty(PROPERTY_VALUE);
condition.Add(PROPERTY_TYPE, DOT);
}
else
{
condition.RemoveProperty(PROPERTY_VALUE);
field = context.TryPolicyAliasPath(field, out var aliasPath) ? TrimFieldName(context, aliasPath) : field;
condition.Add(PROPERTY_FIELD, field);
}
}
else if (tokens.ConsumeFunction(PROPERTY_IF) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
var original = condition;
// Condition
var leftCondition = VisitFieldTokens(context, new JObject(), tokens);
var rightCondition = ReverseCondition(Clone(leftCondition));
var leftEvaluation = VisitFieldTokens(context, Clone(original), tokens);
var rightEvaluation = VisitFieldTokens(context, Clone(original), tokens);
var left = new JObject
{
{ PROPERTY_FIELD, DOT },
{ PROPERTY_WHERE, leftCondition },
{ PROPERTY_ALLOF, new JArray(new[] { leftEvaluation }) }
};
var right = new JObject
{
{ PROPERTY_FIELD, DOT },
{ PROPERTY_WHERE, rightCondition },
{ PROPERTY_ALLOF, new JArray(new[] { rightEvaluation }) }
};
var result = OrCondition(left, right);
condition.Replace(result);
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
return result;
}
else if (tokens.ConsumeFunction(PROPERTY_EQUALS) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
VisitFieldTokens(context, condition, tokens);
if (tokens.ConsumeString(out var s))
{
condition.Add(PROPERTY_EQUALS, s);
}
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
else if (tokens.ConsumeFunction(PROPERTY_EMPTY) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
if (condition.TryBoolProperty(PROPERTY_EQUALS, out var emptyEquals))
{
condition.RemoveProperty(PROPERTY_EQUALS);
condition.Add(PROPERTY_HAS_VALUE, !emptyEquals.Value);
}
VisitFieldTokens(context, condition, tokens);
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
else if (tokens.ConsumeFunction(PROPERTY_LESS) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
VisitFieldTokens(context, condition, tokens);
if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
{
if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
{
condition.RemoveProperty(PROPERTY_EQUALS);
condition.Add(comparison.Value ? PROPERTY_LESS : PROPERTY_GREATEROREQUALS, comparisonInt.Value);
}
else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
{
condition.RemoveProperty(PROPERTY_NOTEQUALS);
condition.Add(comparison.Value ? PROPERTY_GREATEROREQUALS : PROPERTY_LESS, comparisonInt.Value);
}
}
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
else if (tokens.ConsumeFunction(PROPERTY_LESSOREQUALS) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
VisitFieldTokens(context, condition, tokens);
if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
{
if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
{
condition.RemoveProperty(PROPERTY_EQUALS);
condition.Add(comparison.Value ? PROPERTY_LESSOREQUALS : PROPERTY_GREATER, comparisonInt.Value);
}
else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
{
condition.RemoveProperty(PROPERTY_NOTEQUALS);
condition.Add(comparison.Value ? PROPERTY_GREATER : PROPERTY_LESSOREQUALS, comparisonInt.Value);
}
}
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
else if (tokens.ConsumeFunction(PROPERTY_GREATER) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
VisitFieldTokens(context, condition, tokens);
if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
{
if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
{
condition.RemoveProperty(PROPERTY_EQUALS);
condition.Add(comparison.Value ? PROPERTY_GREATER : PROPERTY_LESSOREQUALS, comparisonInt.Value);
}
else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
{
condition.RemoveProperty(PROPERTY_NOTEQUALS);
condition.Add(comparison.Value ? PROPERTY_LESSOREQUALS : PROPERTY_GREATER, comparisonInt.Value);
}
}
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
else if (tokens.ConsumeFunction(PROPERTY_GREATEROREQUALS) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
VisitFieldTokens(context, condition, tokens);
if (tokens.ConsumeInteger(out var comparisonInt) && comparisonInt.HasValue)
{
if (condition.TryBoolProperty(PROPERTY_EQUALS, out var comparison))
{
condition.RemoveProperty(PROPERTY_EQUALS);
condition.Add(comparison.Value ? PROPERTY_GREATEROREQUALS : PROPERTY_LESS, comparisonInt.Value);
}
else if (condition.TryBoolProperty(PROPERTY_NOTEQUALS, out comparison))
{
condition.RemoveProperty(PROPERTY_NOTEQUALS);
condition.Add(comparison.Value ? PROPERTY_LESS : PROPERTY_GREATEROREQUALS, comparisonInt.Value);
}
}
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
else if (tokens.ConsumeFunction(PROPERTY_LENGTH) &&
tokens.TryTokenType(ExpressionTokenType.GroupStart, out _))
{
VisitFieldTokens(context, condition, tokens);
if (condition.TryIntegerProperty(PROPERTY_EQUALS, out var comparison))
{
condition.RemoveProperty(PROPERTY_EQUALS);
condition.Add(PROPERTY_COUNT, comparison.Value);
}
else if (condition.TryIntegerProperty(PROPERTY_NOTEQUALS, out comparison))
{
condition.RemoveProperty(PROPERTY_NOTEQUALS);
condition.Add(PROPERTY_NOTCOUNT, comparison.Value);
}
tokens.TryTokenType(ExpressionTokenType.GroupEnd, out _);
}
return condition;
}