Validate rules in DNF
Ensure that rules passed to the evaluation engine are in DNF before being evaluated against app install metadata. Bug: 141971373 Test: atest FrameworksServicesTests:RuleEvaluatorTest Change-Id: I42d1353ef13c1c9ccb6e6b4ecea5d58c8fc5dab5
This commit is contained in:
@@ -37,6 +37,9 @@ final class RuleEvaluator {
|
||||
/**
|
||||
* Match the list of rules against an app install metadata.
|
||||
*
|
||||
* <p>Rules must be in disjunctive normal form (DNF). A rule should contain AND'ed formulas
|
||||
* only. All rules are OR'ed together by default.
|
||||
*
|
||||
* @param rules The list of rules to evaluate.
|
||||
* @param appInstallMetadata Metadata of the app to be installed, and to evaluate the rules
|
||||
* against.
|
||||
@@ -45,7 +48,7 @@ final class RuleEvaluator {
|
||||
*/
|
||||
static Rule evaluateRules(List<Rule> rules, AppInstallMetadata appInstallMetadata) {
|
||||
for (Rule rule : rules) {
|
||||
if (isMatch(rule, appInstallMetadata)) {
|
||||
if (isConjunctionOfFormulas(rule.getFormula()) && isMatch(rule, appInstallMetadata)) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
@@ -99,4 +102,25 @@ final class RuleEvaluator {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isConjunctionOfFormulas(Formula formula) {
|
||||
if (formula == null) {
|
||||
return false;
|
||||
}
|
||||
if (isAtomicFormula(formula)) {
|
||||
return true;
|
||||
}
|
||||
OpenFormula openFormula = (OpenFormula) formula;
|
||||
return openFormula.getConnector() == OpenFormula.Connector.AND
|
||||
&& openFormula.getFormulas().stream().allMatch(RuleEvaluator::isAtomicFormula);
|
||||
}
|
||||
|
||||
private static boolean isAtomicFormula(Formula formula) {
|
||||
if (formula instanceof AtomicFormula) {
|
||||
return true;
|
||||
}
|
||||
OpenFormula openFormula = (OpenFormula) formula;
|
||||
return openFormula.getConnector() == OpenFormula.Connector.NOT
|
||||
&& openFormula.getFormulas().get(0) instanceof AtomicFormula;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,4 +127,57 @@ public class RuleEvaluatorTest {
|
||||
|
||||
assertEquals(rule1, matchedRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchRules_validForm() {
|
||||
OpenFormula openFormula = new OpenFormula(OpenFormula.Connector.AND, Arrays.asList(
|
||||
new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
|
||||
PACKAGE_NAME_1),
|
||||
new AtomicFormula(AtomicFormula.Key.APP_CERTIFICATE,
|
||||
AtomicFormula.Operator.EQ,
|
||||
APP_CERTIFICATE)));
|
||||
Rule rule = new Rule(
|
||||
openFormula, Rule.Effect.DENY);
|
||||
|
||||
Rule matchedRule = RuleEvaluator.evaluateRules(Collections.singletonList(rule),
|
||||
APP_INSTALL_METADATA);
|
||||
|
||||
assertEquals(rule, matchedRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchRules_ruleNotInDNF() {
|
||||
OpenFormula openFormula = new OpenFormula(OpenFormula.Connector.OR, Arrays.asList(
|
||||
new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
|
||||
PACKAGE_NAME_1),
|
||||
new AtomicFormula(AtomicFormula.Key.APP_CERTIFICATE,
|
||||
AtomicFormula.Operator.EQ,
|
||||
APP_CERTIFICATE)));
|
||||
Rule rule = new Rule(
|
||||
openFormula, Rule.Effect.DENY);
|
||||
|
||||
Rule matchedRule = RuleEvaluator.evaluateRules(Collections.singletonList(rule),
|
||||
APP_INSTALL_METADATA);
|
||||
|
||||
assertEquals(Rule.EMPTY, matchedRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchRules_openFormulaWithNot() {
|
||||
OpenFormula openSubFormula = new OpenFormula(OpenFormula.Connector.AND, Arrays.asList(
|
||||
new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
|
||||
PACKAGE_NAME_2),
|
||||
new AtomicFormula(AtomicFormula.Key.APP_CERTIFICATE,
|
||||
AtomicFormula.Operator.EQ,
|
||||
APP_CERTIFICATE)));
|
||||
OpenFormula openFormula = new OpenFormula(OpenFormula.Connector.NOT,
|
||||
Collections.singletonList(openSubFormula));
|
||||
Rule rule = new Rule(
|
||||
openFormula, Rule.Effect.DENY);
|
||||
|
||||
Rule matchedRule = RuleEvaluator.evaluateRules(Collections.singletonList(rule),
|
||||
APP_INSTALL_METADATA);
|
||||
|
||||
assertEquals(Rule.EMPTY, matchedRule);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user