blob: 257eb4da7bb4ab1fe78510bee537422efcce9a36 [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040016import unittest
Scott Baker1f7791d2018-10-04 13:21:20 -070017from xosgenx.generator import XOSProcessor, XOSProcessorArgs
18from helpers import FakeObject, XProtoTestHelpers
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040019
20"""The function below is for eliminating warnings arising due to the missing policy_output_validator,
21which is generated and loaded dynamically.
22"""
Zack Williams045b63d2019-01-22 16:30:57 -070023
24
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040025def policy_output_validator(x, y):
26 raise Exception("Validator not generated. Test failed.")
27 return False
28
Zack Williams045b63d2019-01-22 16:30:57 -070029
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040030"""
Zack Williams045b63d2019-01-22 16:30:57 -070031The tests below use the Python code target to generate
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040032Python validation policies, set up an appropriate environment and execute the Python.
33"""
Zack Williams045b63d2019-01-22 16:30:57 -070034
35
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040036class XProtoXOSModelValidationTest(unittest.TestCase):
37 def setUp(self):
Zack Williams045b63d2019-01-22 16:30:57 -070038 self.target = XProtoTestHelpers.write_tmp_target(
39 "{{ xproto_fol_to_python_validator('output', proto.policies.test_policy, None, 'Necessary Failure') }}"
40 )
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040041
42 def test_instance_container(self):
Zack Williams045b63d2019-01-22 16:30:57 -070043 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040044 policy test_policy < (obj.isolation = "container" | obj.isolation = "container_vm" ) -> (obj.image.kind = "container") >
45"""
Scott Baker1f7791d2018-10-04 13:21:20 -070046 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040047 args.inputs = xproto
48 args.target = self.target
49
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080050 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040051
Scott Baker1f7791d2018-10-04 13:21:20 -070052 obj = FakeObject()
Zack Williams045b63d2019-01-22 16:30:57 -070053 obj.isolation = "container"
54 obj.kind = "not a container"
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040055
Zack Williams045b63d2019-01-22 16:30:57 -070056 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040057
58 """
59 def policy_output_validator(obj, ctx):
60 i4 = (obj.isolation == 'container')
61 i5 = (self.isolation == 'container_vm')
62 i2 = (i4 or i5)
63 i3 = (obj.image.kind == 'container')
64 i1 = (i2 or i3)
65 return i1
66 """
67
68 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070069 policy_output_validator(obj, {})
70
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040071 def test_slice_name_validation(self):
Zack Williams045b63d2019-01-22 16:30:57 -070072 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040073 policy test_policy < not obj.id -> {{ obj.name.startswith(obj.site.login_base) }} >
74"""
Scott Baker1f7791d2018-10-04 13:21:20 -070075 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040076 args.inputs = xproto
77 args.target = self.target
78
Sapan Bhatiabfb233a2018-02-09 14:53:09 -080079 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040080
Scott Baker1f7791d2018-10-04 13:21:20 -070081 obj = FakeObject()
Zack Williams045b63d2019-01-22 16:30:57 -070082 obj.isolation = "container"
83 obj.kind = "not a container"
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040084
Zack Williams045b63d2019-01-22 16:30:57 -070085 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040086
87 """
88 def policy_output_validator(obj, ctx):
89 i3 = obj.id
90 i4 = obj.name.startswith(obj.site.login_base)
91 i2 = ((not i3) or i4)
92 i1 = (not i2)
93 if (not i1):
94 raise ValidationError('Necessary Failure')
95 """
96
97 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -070098 policy_output_validator(obj, {})
Sapan Bhatia5ea307d2017-07-19 00:13:21 -040099
100 def test_equal(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700101 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400102 policy test_policy < not (ctx.user = obj.user) >
103"""
104
Scott Baker1f7791d2018-10-04 13:21:20 -0700105 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400106 args.inputs = xproto
107 args.target = self.target
108
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800109 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400110
Zack Williams045b63d2019-01-22 16:30:57 -0700111 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400112
113 """
114 def policy_output_validator(obj, ctx):
115 i2 = (ctx.user == obj.user)
116 i1 = (not i2)
117 if (not i1):
118 raise Exception('Necessary Failure')
119 """
120
Scott Baker1f7791d2018-10-04 13:21:20 -0700121 obj = FakeObject()
122 obj.user = 1
123 ctx = FakeObject()
124 ctx.user = 1
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400125
126 with self.assertRaises(Exception):
Zack Williams045b63d2019-01-22 16:30:57 -0700127 policy_output_validator(obj, ctx)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400128
129 def test_bin(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700130 xproto = """
Sapan Bhatiab69f4702017-07-31 16:03:33 -0400131 policy test_policy < not (ctx.is_admin = True | obj.empty = True) | False>
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400132"""
133
Scott Baker1f7791d2018-10-04 13:21:20 -0700134 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400135 args.inputs = xproto
136 args.target = self.target
137
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800138 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700139 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400140
141 """
142 def policy_output_validator(obj, ctx):
143 i2 = (ctx.is_admin == True)
144 i3 = (obj.empty == True)
145 i1 = (i2 or i3)
146 if (not i1):
147 raise Exception('Necessary Failure')
148 """
149
Scott Baker1f7791d2018-10-04 13:21:20 -0700150 obj = FakeObject()
151 obj.empty = True
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400152
Scott Baker1f7791d2018-10-04 13:21:20 -0700153 ctx = FakeObject()
154 ctx.is_admin = True
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400155
156 with self.assertRaises(Exception):
157 verdict = policy_output_validator(obj, ctx)
158
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400159 def test_exists(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700160 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400161 policy test_policy < exists Privilege: Privilege.object_id = obj.id >
162"""
Scott Baker1f7791d2018-10-04 13:21:20 -0700163 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400164 args.inputs = xproto
165 args.target = self.target
166
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800167 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700168 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400169
170 """
171 def policy_output_validator(obj, ctx):
172 i1 = Privilege.objects.filter(Q(object_id=obj.id))[0]
173 if (not i1):
174 raise Exception('Necessary Failure')
175 """
176
177 self.assertTrue(policy_output_validator is not None)
Zack Williams045b63d2019-01-22 16:30:57 -0700178
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400179 def test_python(self):
Zack Williams045b63d2019-01-22 16:30:57 -0700180 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400181 policy test_policy < {{ "jack" in ["the", "box"] }} = True >
182"""
Scott Baker1f7791d2018-10-04 13:21:20 -0700183 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400184 args.inputs = xproto
185 args.target = self.target
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800186 output = XOSProcessor.process(args)
Zack Williams045b63d2019-01-22 16:30:57 -0700187 exec(output) # This loads the generated function, which should look like this:
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400188
189 """
190 def policy_output_validator(obj, ctx):
191 i2 = ('jack' in ['the', 'box'])
192 i1 = (i2 == True)
193 if (not i1):
194 raise Exception('Necessary Failure')
195 """
196
197 with self.assertRaises(Exception):
198 self.assertTrue(policy_output_validator({}, {}) is True)
199
200 def test_forall(self):
201 # This one we only parse
Zack Williams045b63d2019-01-22 16:30:57 -0700202 xproto = """
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400203 policy test_policy < forall Credential: Credential.obj_id = obj_id >
204"""
205
Scott Baker1f7791d2018-10-04 13:21:20 -0700206 args = XOSProcessorArgs()
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400207 args.inputs = xproto
208 args.target = self.target
209
Sapan Bhatiabfb233a2018-02-09 14:53:09 -0800210 output = XOSProcessor.process(args)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400211
212 """
213 def policy_output_enforcer(obj, ctx):
214 i2 = Credential.objects.filter((~ Q(obj_id=obj_id)))[0]
215 i1 = (not i2)
216 return i1
217 """
218
Zack Williams045b63d2019-01-22 16:30:57 -0700219 self.assertIn("policy_output_validator", output)
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400220
Zack Williams045b63d2019-01-22 16:30:57 -0700221
222if __name__ == "__main__":
Sapan Bhatia5ea307d2017-07-19 00:13:21 -0400223 unittest.main()