1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.libraries.pcc.chronicle.api.policy.contextrules
18
19 import com.android.libraries.pcc.chronicle.util.TypedMap
20
21 /**
22 * This defines the basic structure of a context rule.
23 *
24 * `name` and `operands` are used internally for the ledger. `operands` refers to any rules that are
25 * used within the current rule.
26 */
27 interface PolicyContextRule {
28 val name: String
29 val operands: List<PolicyContextRule>
30
31 /** Returns whether a rule is true/false, for the given context */
invokenull32 operator fun invoke(context: TypedMap): Boolean
33 }
34
35 /**
36 * This context rule always returns true, regardless of the context. It can be used as a default
37 * ContextRule if no rules need to be applied.
38 */
39 object All : PolicyContextRule {
40 override val name = "All"
41 override val operands: List<PolicyContextRule> = emptyList()
42 override fun invoke(context: TypedMap): Boolean = true
43 }
44
45 /** Allows policy rule expressions such as `Rule1 and Rule2` */
andnull46 infix fun PolicyContextRule.and(other: PolicyContextRule): PolicyContextRule = And(this, other)
47
48 /** Used to perform an `&&` operation on the boolean evaluations of two PolicyContextRules */
49 class And(private val lhs: PolicyContextRule, private val rhs: PolicyContextRule) :
50 PolicyContextRule {
51 override val name = "And"
52 override val operands: List<PolicyContextRule> = listOf(lhs, rhs)
53 override fun invoke(context: TypedMap): Boolean = lhs(context) && rhs(context)
54 }
55
56 /** Allows policy rule expressions such as `Rule1 or Rule2` */
ornull57 infix fun PolicyContextRule.or(other: PolicyContextRule): PolicyContextRule = Or(this, other)
58
59 /** Used to perform an `||` operation on the boolean evaluations of two PolicyContextRules */
60 class Or(private val lhs: PolicyContextRule, private val rhs: PolicyContextRule) :
61 PolicyContextRule {
62 override val name = "Or"
63 override val operands: List<PolicyContextRule> = listOf(lhs, rhs)
64 override fun invoke(context: TypedMap): Boolean = lhs(context) || rhs(context)
65 }
66
67 /** Allows policy rule expressions such as `not(Rule1)` */
notnull68 fun not(rule: PolicyContextRule): PolicyContextRule = Not(rule)
69
70 /** Used to perform an `!` operation on the boolean evaluation of a PolicyContextRule */
71 class Not(private val inner: PolicyContextRule) : PolicyContextRule {
72 override val name = "Not"
73 override val operands: List<PolicyContextRule> = listOf(inner)
74 override fun invoke(context: TypedMap): Boolean = !inner(context)
75 }
76